From 3b927278bdfad862edf55e04afccefdf7649bf02 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Fri, 8 Jun 2018 03:43:58 +0100 Subject: [PATCH] sync up arm patches --- ...-firmware-issue-on-X-Gene-based-m400.patch | 64 ++ ...x-regression-related-to-X-Gene-UARTs.patch | 44 ++ arm-dts-Add-am335x-pocketbeagle.patch | 432 +++++++++++++ arm-tegra-USB-driver-dependency-fix.patch | 610 ++++++++++++++++++ generate_bls_conf.sh | 31 + kernel.spec | 2 - ...eous-error-message-when-parsing-ACPI.patch | 240 +++++++ mvebu-a37xx-fixes.patch | 128 ++++ 8 files changed, 1549 insertions(+), 2 deletions(-) create mode 100644 ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch create mode 100644 ACPI-scan-Fix-regression-related-to-X-Gene-UARTs.patch create mode 100644 arm-dts-Add-am335x-pocketbeagle.patch create mode 100644 arm-tegra-USB-driver-dependency-fix.patch create mode 100755 generate_bls_conf.sh create mode 100644 mailbox-ACPI-erroneous-error-message-when-parsing-ACPI.patch create mode 100644 mvebu-a37xx-fixes.patch diff --git a/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch b/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch new file mode 100644 index 000000000..3dcfd4969 --- /dev/null +++ b/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch @@ -0,0 +1,64 @@ +From dbdda4277cf0422a9ccb7ea98d0263c3cdbecdf6 Mon Sep 17 00:00:00 2001 +From: Mark Salter +Date: Tue, 8 May 2018 21:54:39 -0400 +Subject: [PATCH] ACPI / irq: Workaround firmware issue on X-Gene based + m400 + +The ACPI firmware on the xgene-based m400 platorms erroneously +describes its UART interrupt as ACPI_PRODUCER rather than +ACPI_CONSUMER. This leads to the UART driver being unable to +find its interrupt and the kernel unable find a console. +Work around this by avoiding the producer/consumer check +for X-Gene UARTs. + +Signed-off-by: Mark Salter +--- + drivers/acpi/irq.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index 7c352cba0528..028c1a564cff 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -129,6 +129,7 @@ struct acpi_irq_parse_one_ctx { + unsigned int index; + unsigned long *res_flags; + struct irq_fwspec *fwspec; ++ bool skip_producer_check; + }; + + /** +@@ -200,7 +201,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, + return AE_CTRL_TERMINATE; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + eirq = &ares->data.extended_irq; +- if (eirq->producer_consumer == ACPI_PRODUCER) ++ if (!ctx->skip_producer_check && ++ eirq->producer_consumer == ACPI_PRODUCER) + return AE_OK; + if (ctx->index >= eirq->interrupt_count) { + ctx->index -= eirq->interrupt_count; +@@ -235,8 +237,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, + static int acpi_irq_parse_one(acpi_handle handle, unsigned int index, + struct irq_fwspec *fwspec, unsigned long *flags) + { +- struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec }; ++ struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false }; + ++ /* ++ * Firmware on arm64-based HPE m400 platform incorrectly marks ++ * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER. ++ * Don't do the producer/consumer check for that device. ++ */ ++ if (IS_ENABLED(CONFIG_ARM64)) { ++ struct acpi_device *adev = acpi_bus_get_acpi_device(handle); ++ ++ if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08")) ++ ctx.skip_producer_check = true; ++ } + acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx); + return ctx.rc; + } +-- +2.17.0 + diff --git a/ACPI-scan-Fix-regression-related-to-X-Gene-UARTs.patch b/ACPI-scan-Fix-regression-related-to-X-Gene-UARTs.patch new file mode 100644 index 000000000..56baf5ec6 --- /dev/null +++ b/ACPI-scan-Fix-regression-related-to-X-Gene-UARTs.patch @@ -0,0 +1,44 @@ +From patchwork Fri Apr 20 03:29:47 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: ACPI / scan: Fix regression related to X-Gene UARTs +From: Mark Salter +X-Patchwork-Id: 10351797 +Message-Id: <20180420032947.23023-1-msalter@redhat.com> +To: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= +Cc: "Rafael J . Wysocki" , + linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org +Date: Thu, 19 Apr 2018 23:29:47 -0400 + +Commit e361d1f85855 ("ACPI / scan: Fix enumeration for special UART +devices") caused a regression with some X-Gene based platforms (Mustang +and M400) with invalid DSDT. The DSDT makes it appear that the UART +device is also a slave device attached to itself. With the above commit +the UART won't be enumerated by ACPI scan (slave serial devices shouldn't +be). So check for X-Gene UART device and skip slace device check on it. + +Signed-off-by: Mark Salter +--- + drivers/acpi/scan.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index cc234e6a6297..1dcdd0122862 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -1551,6 +1551,14 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) + fwnode_property_present(&device->fwnode, "baud"))) + return true; + ++ /* ++ * Firmware on some arm64 X-Gene platforms will make the UART ++ * device appear as both a UART and a slave of that UART. Just ++ * bail out here for X-Gene UARTs. ++ */ ++ if (!strcmp(acpi_device_hid(device), "APMC0D08")) ++ return false; ++ + INIT_LIST_HEAD(&resource_list); + acpi_dev_get_resources(device, &resource_list, + acpi_check_serial_bus_slave, diff --git a/arm-dts-Add-am335x-pocketbeagle.patch b/arm-dts-Add-am335x-pocketbeagle.patch new file mode 100644 index 000000000..76fab6b55 --- /dev/null +++ b/arm-dts-Add-am335x-pocketbeagle.patch @@ -0,0 +1,432 @@ +From patchwork Tue Apr 17 17:14:04 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3] ARM: dts: Add am335x-pocketbeagle +From: Robert Nelson +X-Patchwork-Id: 10346089 +Message-Id: <20180417171404.13624-1-robertcnelson@gmail.com> +To: tony@atomide.com, + devicetree@vger.kernel.org +Cc: Drew Fustini , + Peter Robinson , + Jason Kridner , linux-omap@vger.kernel.org, + Robert Nelson , + linux-arm-kernel@lists.infradead.org +Date: Tue, 17 Apr 2018 12:14:04 -0500 + +PocketBeagle is an ultra-tiny-yet-complete open-source USB-key-fob computer. + +This board family can be indentified by the A335PBGL in the at24 eeprom: +A2: [aa 55 33 ee 41 33 33 35 50 42 47 4c 30 30 41 32 |.U3.A335PBGL00A2|] + +http://beagleboard.org/pocket +https://github.com/beagleboard/pocketbeagle + +Signed-off-by: Robert Nelson +CC: Tony Lindgren +CC: Jason Kridner +CC: Drew Fustini +CC: Peter Robinson +--- +Changes in v3: +- Fix: Board eeprom in subject message. (accidently copied PocketBone) +Changes in v2: +- Use SPDX tags. +- Use eeprom@50, remove repeated node and fix and remove '_' to fix node_name_chars_strict Warning +- Fix: PocketBeagle Name in Subject (not PocketBeagle Blue) +- Fix: leds remove '_' to fix node_name_chars_strict warning +- Fix: node_name_chars_strict pinmux_*_pins label's. +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/am335x-osd335x-common.dtsi | 124 ++++++++++ + arch/arm/boot/dts/am335x-pocketbeagle.dts | 237 +++++++++++++++++++ + 3 files changed, 362 insertions(+) + create mode 100644 arch/arm/boot/dts/am335x-osd335x-common.dtsi + create mode 100644 arch/arm/boot/dts/am335x-pocketbeagle.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 7e2424957809..5a09ff15743b 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -688,6 +688,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \ + am335x-pdu001.dtb \ + am335x-pepper.dtb \ + am335x-phycore-rdk.dtb \ ++ am335x-pocketbeagle.dtb \ + am335x-shc.dtb \ + am335x-sbc-t335.dtb \ + am335x-sl50.dtb \ +diff --git a/arch/arm/boot/dts/am335x-osd335x-common.dtsi b/arch/arm/boot/dts/am335x-osd335x-common.dtsi +new file mode 100644 +index 000000000000..d2150d207b7a +--- /dev/null ++++ b/arch/arm/boot/dts/am335x-osd335x-common.dtsi +@@ -0,0 +1,124 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ ++ * ++ * Author: Robert Nelson ++ */ ++ ++/ { ++ cpus { ++ cpu@0 { ++ cpu0-supply = <&dcdc2_reg>; ++ }; ++ }; ++ ++ memory@80000000 { ++ device_type = "memory"; ++ reg = <0x80000000 0x20000000>; /* 512 MB */ ++ }; ++}; ++ ++&cpu0_opp_table { ++ /* ++ * Octavo Systems: ++ * The EFUSE_SMA register is not programmed for any of the AM335x wafers ++ * we get and we are not programming them during our production test. ++ * Therefore, from a DEVICE_ID revision point of view, the silicon looks ++ * like it is Revision 2.1. However, from an EFUSE_SMA point of view for ++ * the HW OPP table, the silicon looks like it is Revision 1.0 (ie the ++ * EFUSE_SMA register reads as all zeros). ++ */ ++ oppnitro-1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ ++&am33xx_pinmux { ++ i2c0_pins: pinmux-i2c0-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* (C17) I2C0_SDA.I2C0_SDA */ ++ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* (C16) I2C0_SCL.I2C0_SCL */ ++ >; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++ ++ tps: tps@24 { ++ reg = <0x24>; ++ }; ++}; ++ ++/include/ "tps65217.dtsi" ++ ++&tps { ++ interrupts = <7>; /* NMI */ ++ interrupt-parent = <&intc>; ++ ++ ti,pmic-shutdown-controller; ++ ++ pwrbutton { ++ interrupts = <2>; ++ status = "okay"; ++ }; ++ ++ regulators { ++ dcdc1_reg: regulator@0 { ++ regulator-name = "vdds_dpr"; ++ regulator-always-on; ++ }; ++ ++ dcdc2_reg: regulator@1 { ++ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ ++ regulator-name = "vdd_mpu"; ++ regulator-min-microvolt = <925000>; ++ regulator-max-microvolt = <1351500>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ dcdc3_reg: regulator@2 { ++ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ ++ regulator-name = "vdd_core"; ++ regulator-min-microvolt = <925000>; ++ regulator-max-microvolt = <1150000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ ldo1_reg: regulator@3 { ++ regulator-name = "vio,vrtc,vdds"; ++ regulator-always-on; ++ }; ++ ++ ldo2_reg: regulator@4 { ++ regulator-name = "vdd_3v3aux"; ++ regulator-always-on; ++ }; ++ ++ ldo3_reg: regulator@5 { ++ regulator-name = "vdd_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ ldo4_reg: regulator@6 { ++ regulator-name = "vdd_3v3a"; ++ regulator-always-on; ++ }; ++ }; ++}; ++ ++&aes { ++ status = "okay"; ++}; ++ ++&sham { ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/am335x-pocketbeagle.dts b/arch/arm/boot/dts/am335x-pocketbeagle.dts +new file mode 100644 +index 000000000000..62fe5cab9fae +--- /dev/null ++++ b/arch/arm/boot/dts/am335x-pocketbeagle.dts +@@ -0,0 +1,237 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ ++ * ++ * Author: Robert Nelson ++ */ ++/dts-v1/; ++ ++#include "am33xx.dtsi" ++#include "am335x-osd335x-common.dtsi" ++ ++/ { ++ model = "TI AM335x PocketBeagle"; ++ compatible = "ti,am335x-pocketbeagle", "ti,am335x-bone", "ti,am33xx"; ++ ++ chosen { ++ stdout-path = &uart0; ++ }; ++ ++ leds { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usr_leds_pins>; ++ ++ compatible = "gpio-leds"; ++ ++ usr0 { ++ label = "beaglebone:green:usr0"; ++ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "off"; ++ }; ++ ++ usr1 { ++ label = "beaglebone:green:usr1"; ++ gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "mmc0"; ++ default-state = "off"; ++ }; ++ ++ usr2 { ++ label = "beaglebone:green:usr2"; ++ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "cpu0"; ++ default-state = "off"; ++ }; ++ ++ usr3 { ++ label = "beaglebone:green:usr3"; ++ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ vmmcsd_fixed: fixedregulator0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vmmcsd_fixed"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++}; ++ ++&am33xx_pinmux { ++ i2c2_pins: pinmux-i2c2-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3) /* (D17) uart1_rtsn.I2C2_SCL */ ++ AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3) /* (D18) uart1_ctsn.I2C2_SDA */ ++ >; ++ }; ++ ++ ehrpwm0_pins: pinmux-ehrpwm0-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* (A13) mcasp0_aclkx.ehrpwm0A */ ++ >; ++ }; ++ ++ ehrpwm1_pins: pinmux-ehrpwm1-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x848, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* (U14) gpmc_a2.ehrpwm1A */ ++ >; ++ }; ++ ++ mmc0_pins: pinmux-mmc0-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* (C15) spi0_cs1.gpio0[6] */ ++ AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* (G16) mmc0_dat0.mmc0_dat0 */ ++ AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* (G15) mmc0_dat1.mmc0_dat1 */ ++ AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* (F18) mmc0_dat2.mmc0_dat2 */ ++ AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* (F17) mmc0_dat3.mmc0_dat3 */ ++ AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* (G18) mmc0_cmd.mmc0_cmd */ ++ AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* (G17) mmc0_clk.mmc0_clk */ ++ AM33XX_IOPAD(0x9a0, PIN_INPUT | MUX_MODE4) /* (B12) mcasp0_aclkr.mmc0_sdwp */ ++ >; ++ }; ++ ++ spi0_pins: pinmux-spi0-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* (A17) spi0_sclk.spi0_sclk */ ++ AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* (B17) spi0_d0.spi0_d0 */ ++ AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* (B16) spi0_d1.spi0_d1 */ ++ AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0) /* (A16) spi0_cs0.spi0_cs0 */ ++ >; ++ }; ++ ++ spi1_pins: pinmux-spi1-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x964, PIN_INPUT_PULLUP | MUX_MODE4) /* (C18) eCAP0_in_PWM0_out.spi1_sclk */ ++ AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE4) /* (E18) uart0_ctsn.spi1_d0 */ ++ AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE4) /* (E17) uart0_rtsn.spi1_d1 */ ++ AM33XX_IOPAD(0x9b0, PIN_INPUT_PULLUP | MUX_MODE4) /* (A15) xdma_event_intr0.spi1_cs1 */ ++ >; ++ }; ++ ++ usr_leds_pins: pinmux-usr-leds-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7) /* (V15) gpmc_a5.gpio1[21] - USR_LED_0 */ ++ AM33XX_IOPAD(0x858, PIN_OUTPUT | MUX_MODE7) /* (U15) gpmc_a6.gpio1[22] - USR_LED_1 */ ++ AM33XX_IOPAD(0x85c, PIN_OUTPUT | MUX_MODE7) /* (T15) gpmc_a7.gpio1[23] - USR_LED_2 */ ++ AM33XX_IOPAD(0x860, PIN_OUTPUT | MUX_MODE7) /* (V16) gpmc_a8.gpio1[24] - USR_LED_3 */ ++ >; ++ }; ++ ++ uart0_pins: pinmux-uart0-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* (E15) uart0_rxd.uart0_rxd */ ++ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* (E16) uart0_txd.uart0_txd */ ++ >; ++ }; ++ ++ uart4_pins: pinmux-uart4-pins { ++ pinctrl-single,pins = < ++ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE6) /* (T17) gpmc_wait0.uart4_rxd */ ++ AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* (U17) gpmc_wpn.uart4_txd */ ++ >; ++ }; ++}; ++ ++&epwmss0 { ++ status = "okay"; ++}; ++ ++&ehrpwm0 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ehrpwm0_pins>; ++}; ++ ++&epwmss1 { ++ status = "okay"; ++}; ++ ++&ehrpwm1 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ehrpwm1_pins>; ++}; ++ ++&i2c0 { ++ eeprom: eeprom@50 { ++ compatible = "atmel,24c256"; ++ reg = <0x50>; ++ }; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ ++ status = "okay"; ++ clock-frequency = <400000>; ++}; ++ ++&mmc1 { ++ status = "okay"; ++ vmmc-supply = <&vmmcsd_fixed>; ++ bus-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins>; ++ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; ++}; ++ ++&rtc { ++ system-power-controller; ++}; ++ ++&tscadc { ++ status = "okay"; ++ adc { ++ ti,adc-channels = <0 1 2 3 4 5 6 7>; ++ ti,chan-step-avg = <16 16 16 16 16 16 16 16>; ++ ti,chan-step-opendelay = <0x98 0x98 0x98 0x98 0x98 0x98 0x98 0x98>; ++ ti,chan-step-sampledelay = <0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0>; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ ++ status = "okay"; ++}; ++ ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins>; ++ ++ status = "okay"; ++}; ++ ++&usb { ++ status = "okay"; ++}; ++ ++&usb_ctrl_mod { ++ status = "okay"; ++}; ++ ++&usb0_phy { ++ status = "okay"; ++}; ++ ++&usb0 { ++ status = "okay"; ++ dr_mode = "otg"; ++}; ++ ++&usb1_phy { ++ status = "okay"; ++}; ++ ++&usb1 { ++ status = "okay"; ++ dr_mode = "host"; ++}; ++ ++&cppi41dma { ++ status = "okay"; ++}; diff --git a/arm-tegra-USB-driver-dependency-fix.patch b/arm-tegra-USB-driver-dependency-fix.patch new file mode 100644 index 000000000..b1a80137b --- /dev/null +++ b/arm-tegra-USB-driver-dependency-fix.patch @@ -0,0 +1,610 @@ +From patchwork Mon Apr 9 22:02:57 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,1/3] usb: phy: tegra: Cleanup error messages +X-Patchwork-Submitter: Dmitry Osipenko +X-Patchwork-Id: 896433 +Message-Id: +To: Thierry Reding , + Jonathan Hunter , Felipe Balbi , + Alan Stern , + Greg Kroah-Hartman +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:57 +0300 +From: Dmitry Osipenko +List-Id: + +Tegra's PHY driver has a mix of pr_err() and dev_err(), let's switch to +dev_err() and use common errors message formatting across the driver for +consistency. + +Signed-off-by: Dmitry Osipenko +--- + drivers/usb/phy/phy-tegra-usb.c | 69 ++++++++++++++++++++++++----------------- + 1 file changed, 41 insertions(+), 28 deletions(-) + +diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c +index 0e8d23e51732..e46219e7fa93 100644 +--- a/drivers/usb/phy/phy-tegra-usb.c ++++ b/drivers/usb/phy/phy-tegra-usb.c +@@ -236,10 +236,14 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable) + + static int utmip_pad_open(struct tegra_usb_phy *phy) + { ++ int err; ++ + phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads"); + if (IS_ERR(phy->pad_clk)) { +- pr_err("%s: can't get utmip pad clock\n", __func__); +- return PTR_ERR(phy->pad_clk); ++ err = PTR_ERR(phy->pad_clk); ++ dev_err(phy->u_phy.dev, ++ "Failed to get UTMIP pad clock: %d\n", err); ++ return err; + } + + return 0; +@@ -282,7 +286,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy) + void __iomem *base = phy->pad_regs; + + if (!utmip_pad_count) { +- pr_err("%s: utmip pad already powered off\n", __func__); ++ dev_err(phy->u_phy.dev, "UTMIP pad already powered off\n"); + return -EINVAL; + } + +@@ -338,7 +342,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) + set_phcd(phy, true); + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) +- pr_err("%s: timeout waiting for phy to stabilize\n", __func__); ++ dev_err(phy->u_phy.dev, ++ "Timeout waiting for PHY to stabilize on disable\n"); + } + + static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) +@@ -370,7 +375,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID)) +- pr_err("%s: timeout waiting for phy to stabilize\n", __func__); ++ dev_err(phy->u_phy.dev, ++ "Timeout waiting for PHY to stabilize on enable\n"); + } + + static int utmi_phy_power_on(struct tegra_usb_phy *phy) +@@ -617,15 +623,15 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) + + ret = gpio_direction_output(phy->reset_gpio, 0); + if (ret < 0) { +- dev_err(phy->u_phy.dev, "gpio %d not set to 0\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "GPIO %d not set to 0: %d\n", ++ phy->reset_gpio, ret); + return ret; + } + msleep(5); + ret = gpio_direction_output(phy->reset_gpio, 1); + if (ret < 0) { +- dev_err(phy->u_phy.dev, "gpio %d not set to 1\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "GPIO %d not set to 1: %d\n", ++ phy->reset_gpio, ret); + return ret; + } + +@@ -661,13 +667,13 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) + /* Fix VbusInvalid due to floating VBUS */ + ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08); + if (ret) { +- pr_err("%s: ulpi write failed\n", __func__); ++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret); + return ret; + } + + ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B); + if (ret) { +- pr_err("%s: ulpi write failed\n", __func__); ++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret); + return ret; + } + +@@ -728,28 +734,30 @@ static int ulpi_open(struct tegra_usb_phy *phy) + + phy->clk = devm_clk_get(phy->u_phy.dev, "ulpi-link"); + if (IS_ERR(phy->clk)) { +- pr_err("%s: can't get ulpi clock\n", __func__); +- return PTR_ERR(phy->clk); ++ err = PTR_ERR(phy->clk); ++ dev_err(phy->u_phy.dev, "Failed to get ULPI clock: %d\n", err); ++ return err; + } + + err = devm_gpio_request(phy->u_phy.dev, phy->reset_gpio, + "ulpi_phy_reset_b"); + if (err < 0) { +- dev_err(phy->u_phy.dev, "request failed for gpio: %d\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "Request failed for GPIO %d: %d\n", ++ phy->reset_gpio, err); + return err; + } + + err = gpio_direction_output(phy->reset_gpio, 0); + if (err < 0) { +- dev_err(phy->u_phy.dev, "gpio %d direction not set to output\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, ++ "GPIO %d direction not set to output: %d\n", ++ phy->reset_gpio, err); + return err; + } + + phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); + if (!phy->ulpi) { +- dev_err(phy->u_phy.dev, "otg_ulpi_create returned NULL\n"); ++ dev_err(phy->u_phy.dev, "Failed to create ULPI OTG\n"); + err = -ENOMEM; + return err; + } +@@ -766,8 +774,10 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + + phy->pll_u = devm_clk_get(phy->u_phy.dev, "pll_u"); + if (IS_ERR(phy->pll_u)) { +- pr_err("Can't get pll_u clock\n"); +- return PTR_ERR(phy->pll_u); ++ err = PTR_ERR(phy->pll_u); ++ dev_err(phy->u_phy.dev, ++ "Failed to get pll_u clock: %d\n", err); ++ return err; + } + + err = clk_prepare_enable(phy->pll_u); +@@ -782,7 +792,8 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + } + } + if (!phy->freq) { +- pr_err("invalid pll_u parent rate %ld\n", parent_rate); ++ dev_err(phy->u_phy.dev, "Invalid pll_u parent rate %ld\n", ++ parent_rate); + err = -EINVAL; + goto fail; + } +@@ -791,7 +802,7 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + err = regulator_enable(phy->vbus); + if (err) { + dev_err(phy->u_phy.dev, +- "failed to enable usb vbus regulator: %d\n", ++ "Failed to enable USB VBUS regulator: %d\n", + err); + goto fail; + } +@@ -855,7 +866,8 @@ static int read_utmi_param(struct platform_device *pdev, const char *param, + int err = of_property_read_u32(pdev->dev.of_node, param, &value); + *dest = (u8)value; + if (err < 0) +- dev_err(&pdev->dev, "Failed to read USB UTMI parameter %s: %d\n", ++ dev_err(&pdev->dev, ++ "Failed to read USB UTMI parameter %s: %d\n", + param, err); + return err; + } +@@ -871,14 +883,14 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { +- dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n"); ++ dev_err(&pdev->dev, "Failed to get UTMI pad regs\n"); + return -ENXIO; + } + + tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!tegra_phy->pad_regs) { +- dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n"); ++ dev_err(&pdev->dev, "Failed to remap UTMI pad regs\n"); + return -ENOMEM; + } + +@@ -1020,15 +1032,16 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) + tegra_phy->reset_gpio = + of_get_named_gpio(np, "nvidia,phy-reset-gpio", 0); + if (!gpio_is_valid(tegra_phy->reset_gpio)) { +- dev_err(&pdev->dev, "invalid gpio: %d\n", +- tegra_phy->reset_gpio); ++ dev_err(&pdev->dev, ++ "Invalid GPIO: %d\n", tegra_phy->reset_gpio); + return tegra_phy->reset_gpio; + } + tegra_phy->config = NULL; + break; + + default: +- dev_err(&pdev->dev, "phy_type is invalid or unsupported\n"); ++ dev_err(&pdev->dev, "phy_type %u is invalid or unsupported\n", ++ phy_type); + return -EINVAL; + } + + +From patchwork Mon Apr 9 22:02:58 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3, + 2/3] usb: tegra: Move utmi-pads reset from ehci-tegra to tegra-phy +X-Patchwork-Submitter: Dmitry Osipenko +X-Patchwork-Id: 896435 +Message-Id: <66330166c6a53e8f463ec231e3cb8195fa3036cc.1523307883.git.digetx@gmail.com> +To: Thierry Reding , + Jonathan Hunter , Felipe Balbi , + Alan Stern , + Greg Kroah-Hartman +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:58 +0300 +From: Dmitry Osipenko +List-Id: + +UTMI pads are shared by USB controllers and reset of UTMI pads is shared +with the reset of USB1 controller. Currently reset of UTMI pads is done by +the EHCI driver and ChipIdea UDC works because EHCI driver always happen +to be probed first. Move reset controls from ehci-tegra to tegra-phy in +order to resolve the problem. + +Signed-off-by: Dmitry Osipenko +--- + drivers/usb/host/ehci-tegra.c | 87 ++++++++++++++++++--------------------- + drivers/usb/phy/phy-tegra-usb.c | 79 ++++++++++++++++++++++++++++++++--- + include/linux/usb/tegra_usb_phy.h | 2 + + 3 files changed, 115 insertions(+), 53 deletions(-) + +diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c +index a6f4389f7e88..4d2cdec4cb78 100644 +--- a/drivers/usb/host/ehci-tegra.c ++++ b/drivers/usb/host/ehci-tegra.c +@@ -36,7 +36,6 @@ + #define DRV_NAME "tegra-ehci" + + static struct hc_driver __read_mostly tegra_ehci_hc_driver; +-static bool usb1_reset_attempted; + + struct tegra_ehci_soc_config { + bool has_hostpc; +@@ -51,67 +50,54 @@ struct tegra_ehci_hcd { + enum tegra_usb_phy_port_speed port_speed; + }; + +-/* +- * The 1st USB controller contains some UTMI pad registers that are global for +- * all the controllers on the chip. Those registers are also cleared when +- * reset is asserted to the 1st controller. This means that the 1st controller +- * can only be reset when no other controlled has finished probing. So we'll +- * reset the 1st controller before doing any other setup on any of the +- * controllers, and then never again. +- * +- * Since this is a PHY issue, the Tegra PHY driver should probably be doing +- * the resetting of the USB controllers. But to keep compatibility with old +- * device trees that don't have reset phandles in the PHYs, do it here. +- * Those old DTs will be vulnerable to total USB breakage if the 1st EHCI +- * device isn't the first one to finish probing, so warn them. +- */ + static int tegra_reset_usb_controller(struct platform_device *pdev) + { + struct device_node *phy_np; + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct tegra_ehci_hcd *tegra = + (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; +- bool has_utmi_pad_registers = false; ++ struct reset_control *rst; ++ int err; + + phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0); + if (!phy_np) + return -ENOENT; + +- if (of_property_read_bool(phy_np, "nvidia,has-utmi-pad-registers")) +- has_utmi_pad_registers = true; ++ /* ++ * The 1st USB controller contains some UTMI pad registers that are ++ * global for all the controllers on the chip. Those registers are ++ * also cleared when reset is asserted to the 1st controller. ++ */ ++ rst = of_reset_control_get_shared(phy_np, "utmi-pads"); ++ if (IS_ERR(rst)) { ++ dev_warn(&pdev->dev, ++ "can't get utmi-pads reset from the PHY\n"); ++ dev_warn(&pdev->dev, ++ "continuing, but please update your DT\n"); ++ } else { ++ /* ++ * PHY driver performs UTMI-pads reset in a case of ++ * non-legacy DT. ++ */ ++ reset_control_put(rst); ++ } + +- if (!usb1_reset_attempted) { +- struct reset_control *usb1_reset; ++ of_node_put(phy_np); + +- if (!has_utmi_pad_registers) +- usb1_reset = of_reset_control_get(phy_np, "utmi-pads"); +- else +- usb1_reset = tegra->rst; +- +- if (IS_ERR(usb1_reset)) { +- dev_warn(&pdev->dev, +- "can't get utmi-pads reset from the PHY\n"); +- dev_warn(&pdev->dev, +- "continuing, but please update your DT\n"); +- } else { +- reset_control_assert(usb1_reset); +- udelay(1); +- reset_control_deassert(usb1_reset); +- +- if (!has_utmi_pad_registers) +- reset_control_put(usb1_reset); +- } ++ /* reset control is shared, hence initialize it first */ ++ err = reset_control_deassert(tegra->rst); ++ if (err) ++ return err; + +- usb1_reset_attempted = true; +- } ++ err = reset_control_assert(tegra->rst); ++ if (err) ++ return err; + +- if (!has_utmi_pad_registers) { +- reset_control_assert(tegra->rst); +- udelay(1); +- reset_control_deassert(tegra->rst); +- } ++ udelay(1); + +- of_node_put(phy_np); ++ err = reset_control_deassert(tegra->rst); ++ if (err) ++ return err; + + return 0; + } +@@ -440,7 +426,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) + goto cleanup_hcd_create; + } + +- tegra->rst = devm_reset_control_get(&pdev->dev, "usb"); ++ tegra->rst = devm_reset_control_get_shared(&pdev->dev, "usb"); + if (IS_ERR(tegra->rst)) { + dev_err(&pdev->dev, "Can't get ehci reset\n"); + err = PTR_ERR(tegra->rst); +@@ -452,8 +438,10 @@ static int tegra_ehci_probe(struct platform_device *pdev) + goto cleanup_hcd_create; + + err = tegra_reset_usb_controller(pdev); +- if (err) ++ if (err) { ++ dev_err(&pdev->dev, "Failed to reset controller\n"); + goto cleanup_clk_en; ++ } + + u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); + if (IS_ERR(u_phy)) { +@@ -538,6 +526,9 @@ static int tegra_ehci_remove(struct platform_device *pdev) + usb_phy_shutdown(hcd->usb_phy); + usb_remove_hcd(hcd); + ++ reset_control_assert(tegra->rst); ++ udelay(1); ++ + clk_disable_unprepare(tegra->clk); + + usb_put_hcd(hcd); +diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c +index e46219e7fa93..ea7ef1dc0b42 100644 +--- a/drivers/usb/phy/phy-tegra-usb.c ++++ b/drivers/usb/phy/phy-tegra-usb.c +@@ -236,17 +236,83 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable) + + static int utmip_pad_open(struct tegra_usb_phy *phy) + { +- int err; ++ int ret; + + phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads"); + if (IS_ERR(phy->pad_clk)) { +- err = PTR_ERR(phy->pad_clk); ++ ret = PTR_ERR(phy->pad_clk); + dev_err(phy->u_phy.dev, +- "Failed to get UTMIP pad clock: %d\n", err); +- return err; ++ "Failed to get UTMIP pad clock: %d\n", ret); ++ return ret; + } + +- return 0; ++ phy->pad_rst = devm_reset_control_get_optional_shared( ++ phy->u_phy.dev, "utmi-pads"); ++ if (IS_ERR(phy->pad_rst)) { ++ ret = PTR_ERR(phy->pad_rst); ++ dev_err(phy->u_phy.dev, ++ "Failed to get UTMI-pads reset: %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(phy->pad_clk); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to enable UTMI-pads clock: %d\n", ret); ++ return ret; ++ } ++ ++ spin_lock(&utmip_pad_lock); ++ ++ ret = reset_control_deassert(phy->pad_rst); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to initialize UTMI-pads reset: %d\n", ret); ++ goto unlock; ++ } ++ ++ ret = reset_control_assert(phy->pad_rst); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to assert UTMI-pads reset: %d\n", ret); ++ goto unlock; ++ } ++ ++ udelay(1); ++ ++ ret = reset_control_deassert(phy->pad_rst); ++ if (ret) ++ dev_err(phy->u_phy.dev, ++ "Failed to deassert UTMI-pads reset: %d\n", ret); ++unlock: ++ spin_unlock(&utmip_pad_lock); ++ ++ clk_disable_unprepare(phy->pad_clk); ++ ++ return ret; ++} ++ ++static int utmip_pad_close(struct tegra_usb_phy *phy) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(phy->pad_clk); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to enable UTMI-pads clock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = reset_control_assert(phy->pad_rst); ++ if (ret) ++ dev_err(phy->u_phy.dev, ++ "Failed to assert UTMI-pads reset: %d\n", ret); ++ ++ udelay(1); ++ ++ clk_disable_unprepare(phy->pad_clk); ++ ++ return ret; + } + + static void utmip_pad_power_on(struct tegra_usb_phy *phy) +@@ -700,6 +766,9 @@ static void tegra_usb_phy_close(struct tegra_usb_phy *phy) + if (!IS_ERR(phy->vbus)) + regulator_disable(phy->vbus); + ++ if (!phy->is_ulpi_phy) ++ utmip_pad_close(phy); ++ + clk_disable_unprepare(phy->pll_u); + } + +diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h +index d641ea1660b7..0c5c3ea8b2d7 100644 +--- a/include/linux/usb/tegra_usb_phy.h ++++ b/include/linux/usb/tegra_usb_phy.h +@@ -17,6 +17,7 @@ + #define __TEGRA_USB_PHY_H + + #include ++#include + #include + + /* +@@ -76,6 +77,7 @@ struct tegra_usb_phy { + bool is_legacy_phy; + bool is_ulpi_phy; + int reset_gpio; ++ struct reset_control *pad_rst; + }; + + void tegra_usb_phy_preresume(struct usb_phy *phy); + +From patchwork Mon Apr 9 22:02:59 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,3/3] usb: phy: Add Kconfig entry for Tegra PHY driver +X-Patchwork-Submitter: Dmitry Osipenko +X-Patchwork-Id: 896434 +Message-Id: +To: Thierry Reding , + Jonathan Hunter , Felipe Balbi , + Alan Stern , + Greg Kroah-Hartman +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:59 +0300 +From: Dmitry Osipenko +List-Id: + +Tegra's EHCI driver has a build dependency on Tegra's PHY driver and +currently Tegra's PHY driver is built only when Tegra's EHCI driver is +built. Add own Kconfig entry for the Tegra's PHY driver so that drivers +other than ehci-tegra (like ChipIdea UDC) could work with ehci-tegra +driver being disabled in kernels config by allowing user to manually +select the PHY driver. + +Signed-off-by: Dmitry Osipenko +--- + drivers/usb/host/Kconfig | 4 +--- + drivers/usb/phy/Kconfig | 9 +++++++++ + drivers/usb/phy/Makefile | 2 +- + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index 5d958da8e1bc..9f0aeb068acb 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -234,9 +234,7 @@ config USB_EHCI_TEGRA + tristate "NVIDIA Tegra HCD support" + depends on ARCH_TEGRA + select USB_EHCI_ROOT_HUB_TT +- select USB_PHY +- select USB_ULPI +- select USB_ULPI_VIEWPORT ++ select USB_TEGRA_PHY + help + This driver enables support for the internal USB Host Controllers + found in NVIDIA Tegra SoCs. The controllers are EHCI compliant. +diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +index 0f8ab981d572..b9b0a44be679 100644 +--- a/drivers/usb/phy/Kconfig ++++ b/drivers/usb/phy/Kconfig +@@ -159,6 +159,15 @@ config USB_MXS_PHY + + MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. + ++config USB_TEGRA_PHY ++ tristate "NVIDIA Tegra USB PHY Driver" ++ depends on ARCH_TEGRA ++ select USB_PHY ++ select USB_ULPI ++ help ++ This driver provides PHY support for the USB controllers found ++ on NVIDIA Tegra SoC's. ++ + config USB_ULPI + bool "Generic ULPI Transceiver Driver" + depends on ARM || ARM64 +diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +index 25e579fb92b8..df1d99010079 100644 +--- a/drivers/usb/phy/Makefile ++++ b/drivers/usb/phy/Makefile +@@ -16,7 +16,7 @@ obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o + obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o + obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o + obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o +-obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o ++obj-$(CONFIG_USB_TEGRA_PHY) += phy-tegra-usb.o + obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o + obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o + obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o diff --git a/generate_bls_conf.sh b/generate_bls_conf.sh new file mode 100755 index 000000000..f8415db24 --- /dev/null +++ b/generate_bls_conf.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +. /etc/os-release + +kernelver=$1 && shift +rootfs=$1 && shift +variant=$1 && shift + +output="${rootfs}/lib/modules/${kernelver}/bls.conf" +date=$(date -u +%Y%m%d%H%M%S) + +if [ "${variant:-5}" = "debug" ]; then + debugname=" with debugging" + debugid="-debug" +else + debugname="" + debugid="" +fi + +cat >${output} < +Date: Wed, 16 May 2018 16:01:41 -0600 +Subject: [PATCH] mailbox: PCC: erroneous error message when parsing ACPI PCCT + +There have been multiple reports of the following error message: + +[ 0.068293] Error parsing PCC subspaces from PCCT + +This error message is not correct. In multiple cases examined, the PCCT +(Platform Communications Channel Table) concerned is actually properly +constructed; the problem is that acpi_pcc_probe() which reads the PCCT +is making the assumption that the only valid PCCT is one that contains +subtables of one of two types: ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE or +ACPI_PCCT_TYPE_HW_REDUCED_TYPE2. The number of subtables of these +types are counted and as long as there is at least one of the desired +types, the acpi_pcc_probe() succeeds. When no subtables of these types +are found, regardless of whether or not any other subtable types are +present, the error mentioned above is reported. + +In the cases reported to me personally, the PCCT contains exactly one +subtable of type ACPI_PCCT_TYPE_GENERIC_SUBSPACE. The function +acpi_pcc_probe() does not count it as a valid subtable, so believes +there to be no valid subtables, and hence outputs the error message. + +An example of the PCCT being reported as erroneous yet perfectly fine +is the following: + + Signature : "PCCT" + Table Length : 0000006E + Revision : 05 + Checksum : A9 + Oem ID : "XXXXXX" + Oem Table ID : "XXXXX " + Oem Revision : 00002280 + Asl Compiler ID : "XXXX" + Asl Compiler Revision : 00000002 + + Flags (decoded below) : 00000001 + Platform : 1 + Reserved : 0000000000000000 + + Subtable Type : 00 [Generic Communications Subspace] + Length : 3E + + Reserved : 000000000000 + Base Address : 00000000DCE43018 + Address Length : 0000000000001000 + + Doorbell Register : [Generic Address Structure] + Space ID : 01 [SystemIO] + Bit Width : 08 + Bit Offset : 00 + Encoded Access Width : 01 [Byte Access:8] + Address : 0000000000001842 + + Preserve Mask : 00000000000000FD + Write Mask : 0000000000000002 + Command Latency : 00001388 + Maximum Access Rate : 00000000 + Minimum Turnaround Time : 0000 + +To fix this, we count up all of the possible subtable types for the +PCCT, and only report an error when there are none (which could mean +either no subtables, or no valid subtables), or there are too many. +We also change the logic so that if there is a valid subtable, we +do try to initialize it per the PCCT subtable contents. This is a +change in functionality; previously, the probe would have returned +right after the error message and would not have tried to use any +other subtable definition. + +Tested on my personal laptop which showed the error previously; the +error message no longer appears and the laptop appears to operate +normally. + +Signed-off-by: Al Stone +Reviewed-by: Prashanth Prakash +Signed-off-by: Rafael J. Wysocki +--- + drivers/mailbox/pcc.c | 81 ++++++++++++++++++++++++--------------------------- + 1 file changed, 38 insertions(+), 43 deletions(-) + +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index 3ef7f036ceea..fc3c237daef2 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -373,33 +373,24 @@ static const struct mbox_chan_ops pcc_chan_ops = { + }; + + /** +- * parse_pcc_subspace - Parse the PCC table and verify PCC subspace +- * entries. There should be one entry per PCC client. ++ * parse_pcc_subspaces -- Count PCC subspaces defined + * @header: Pointer to the ACPI subtable header under the PCCT. + * @end: End of subtable entry. + * +- * Return: 0 for Success, else errno. ++ * Return: If we find a PCC subspace entry of a valid type, return 0. ++ * Otherwise, return -EINVAL. + * + * This gets called for each entry in the PCC table. + */ + static int parse_pcc_subspace(struct acpi_subtable_header *header, + const unsigned long end) + { +- struct acpi_pcct_hw_reduced *pcct_ss; +- +- if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) { +- pcct_ss = (struct acpi_pcct_hw_reduced *) header; ++ struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header; + +- if ((pcct_ss->header.type != +- ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) +- && (pcct_ss->header.type != +- ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) { +- pr_err("Incorrect PCC Subspace type detected\n"); +- return -EINVAL; +- } +- } ++ if (ss->header.type < ACPI_PCCT_TYPE_RESERVED) ++ return 0; + +- return 0; ++ return -EINVAL; + } + + /** +@@ -449,8 +440,8 @@ static int __init acpi_pcc_probe(void) + struct acpi_table_header *pcct_tbl; + struct acpi_subtable_header *pcct_entry; + struct acpi_table_pcct *acpi_pcct_tbl; ++ struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED]; + int count, i, rc; +- int sum = 0; + acpi_status status = AE_OK; + + /* Search for PCCT */ +@@ -459,43 +450,41 @@ static int __init acpi_pcc_probe(void) + if (ACPI_FAILURE(status) || !pcct_tbl) + return -ENODEV; + +- count = acpi_table_parse_entries(ACPI_SIG_PCCT, +- sizeof(struct acpi_table_pcct), +- ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE, +- parse_pcc_subspace, MAX_PCC_SUBSPACES); +- sum += (count > 0) ? count : 0; +- +- count = acpi_table_parse_entries(ACPI_SIG_PCCT, +- sizeof(struct acpi_table_pcct), +- ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2, +- parse_pcc_subspace, MAX_PCC_SUBSPACES); +- sum += (count > 0) ? count : 0; ++ /* Set up the subtable handlers */ ++ for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE; ++ i < ACPI_PCCT_TYPE_RESERVED; i++) { ++ proc[i].id = i; ++ proc[i].count = 0; ++ proc[i].handler = parse_pcc_subspace; ++ } + +- if (sum == 0 || sum >= MAX_PCC_SUBSPACES) { +- pr_err("Error parsing PCC subspaces from PCCT\n"); ++ count = acpi_table_parse_entries_array(ACPI_SIG_PCCT, ++ sizeof(struct acpi_table_pcct), proc, ++ ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES); ++ if (count == 0 || count > MAX_PCC_SUBSPACES) { ++ pr_warn("Invalid PCCT: %d PCC subspaces\n", count); + return -EINVAL; + } + +- pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * +- sum, GFP_KERNEL); ++ pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) * count, GFP_KERNEL); + if (!pcc_mbox_channels) { + pr_err("Could not allocate space for PCC mbox channels\n"); + return -ENOMEM; + } + +- pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); ++ pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); + if (!pcc_doorbell_vaddr) { + rc = -ENOMEM; + goto err_free_mbox; + } + +- pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL); ++ pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL); + if (!pcc_doorbell_ack_vaddr) { + rc = -ENOMEM; + goto err_free_db_vaddr; + } + +- pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL); ++ pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL); + if (!pcc_doorbell_irq) { + rc = -ENOMEM; + goto err_free_db_ack_vaddr; +@@ -509,18 +498,24 @@ static int __init acpi_pcc_probe(void) + if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) + pcc_mbox_ctrl.txdone_irq = true; + +- for (i = 0; i < sum; i++) { ++ for (i = 0; i < count; i++) { + struct acpi_generic_address *db_reg; +- struct acpi_pcct_hw_reduced *pcct_ss; ++ struct acpi_pcct_subspace *pcct_ss; + pcc_mbox_channels[i].con_priv = pcct_entry; + +- pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry; ++ if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE || ++ pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { ++ struct acpi_pcct_hw_reduced *pcct_hrss; ++ ++ pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry; + +- if (pcc_mbox_ctrl.txdone_irq) { +- rc = pcc_parse_subspace_irq(i, pcct_ss); +- if (rc < 0) +- goto err; ++ if (pcc_mbox_ctrl.txdone_irq) { ++ rc = pcc_parse_subspace_irq(i, pcct_hrss); ++ if (rc < 0) ++ goto err; ++ } + } ++ pcct_ss = (struct acpi_pcct_subspace *) pcct_entry; + + /* If doorbell is in system memory cache the virt address */ + db_reg = &pcct_ss->doorbell_register; +@@ -531,7 +526,7 @@ static int __init acpi_pcc_probe(void) + ((unsigned long) pcct_entry + pcct_entry->length); + } + +- pcc_mbox_ctrl.num_chans = sum; ++ pcc_mbox_ctrl.num_chans = count; + + pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans); + +-- +2.14.3 diff --git a/mvebu-a37xx-fixes.patch b/mvebu-a37xx-fixes.patch new file mode 100644 index 000000000..0c04e8b00 --- /dev/null +++ b/mvebu-a37xx-fixes.patch @@ -0,0 +1,128 @@ +From patchwork Sun Mar 25 19:57:36 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Subject: arm64: dts: armada-3720-espressobin: wire up spi flash +From: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= +X-Patchwork-Id: 10306793 +Message-Id: <20180325195736.19782-1-u.kleine-koenig@pengutronix.de> +To: Jason Cooper , Andrew Lunn , + Gregory Clement , + Sebastian Hesselbarth +Cc: Ellie Reeves , + linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de +Date: Sun, 25 Mar 2018 21:57:36 +0200 + +From: Ellie Reeves + +This is the storage the machine boots from by default. The partitioning +is taken from the U-Boot that is shipped with the board. There is some +more space on the flash that isn't used. + +Signed-off-by: Ellie Reeves +Signed-off-by: Uwe Kleine-König +--- + .../boot/dts/marvell/armada-3720-espressobin.dts | 27 ++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +index 882d6e4a04e4..5f98c2fecca4 100644 +--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +@@ -108,6 +108,33 @@ + status = "okay"; + }; + ++&spi0 { ++ status = "okay"; ++ ++ flash@0 { ++ reg = <0>; ++ compatible = "winbond,w25q32dw", "jedec,spi-flash"; ++ spi-max-frequency = <104000000>; ++ m25p,fast-read; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "uboot"; ++ reg = <0 0x180000>; ++ }; ++ ++ partition@180000 { ++ label = "ubootenv"; ++ reg = <0x180000 0x10000>; ++ }; ++ }; ++ }; ++}; ++ + /* Exported on the micro USB connector J5 through an FTDI */ + &uart0 { + pinctrl-names = "default"; +From patchwork Sat Apr 21 14:03:42 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: arm64: dts: marvell: armada-37xx: reserve memory for ATF +From: Miquel Raynal +X-Patchwork-Id: 10354187 +Message-Id: <20180421140342.25082-1-miquel.raynal@bootlin.com> +To: Gregory Clement , + Jason Cooper , Andrew Lunn , + Sebastian Hesselbarth +Cc: Mark Rutland , devicetree@vger.kernel.org, + Antoine Tenart , + Catalin Marinas , + Will Deacon , + Maxime Chevallier , + Nadav Haklai , Rob Herring , + Thomas Petazzoni , + Miquel Raynal , Victor Gu , + linux-arm-kernel@lists.infradead.org +Date: Sat, 21 Apr 2018 16:03:42 +0200 + +From: Victor Gu + +The PSCI area should be reserved in Linux for PSCI operations such as +suspend/resume. + +Reserve 2MiB of memory which matches the area used by ATF (BL1, BL2, +BL3x, see [1] in ATF source code). This covers all PSCI code and data +area and is 2MiB aligned, which is required by Linux for huge pages +handling. + +[1] plat/marvell/a3700/common/include/platform_def.h + +Signed-off-by: Victor Gu +[miquel.raynal@bootlin.com: reword of commit message] +Signed-off-by: Miquel Raynal +--- + arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +index 97207a61bc79..429ce91bfc39 100644 +--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +@@ -22,6 +22,17 @@ + serial1 = &uart1; + }; + ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ psci-area@4000000 { ++ reg = <0 0x4000000 0 0x200000>; ++ no-map; ++ }; ++ }; ++ + cpus { + #address-cells = <1>; + #size-cells = <0>;