From cafa87dac8a6bc28459604564d3a280bd8ebe7cc Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Tue, 31 Oct 2017 16:07:06 +0800 Subject: [PATCH 01/20] Add Helios4 support (Target : default only) --- README.md | 38 +- config/boards/helios4.conf | 19 + config/bootenv/helios4-default.txt | 3 + config/bootscripts/boot-helios4.cmd | 37 ++ config/kernel/linux-mvebu-default.config | 16 +- config/sources/mvebu.conf | 33 +- ...dtb-file-for-backwards-compatibility.patch | 0 .../add-spi-flash.patch | 0 ...dtb-file-for-backwards-compatibility.patch | 29 ++ .../board_clearfogpro/add-spi-flash.patch | 34 ++ ...ebu-Add-limited-PWM-support.patch.disabled | 488 ++++++++++++++++++ ...perties-to-.dtsi-armada-38x.patch.disabled | 62 +++ ...ENSORS_PWM_FAN-in-defconfig.patch.disabled | 35 ++ .../0004-libata-add-ledtrig-support.patch | 179 +++++++ .../0005-Enable-ATA-port-LED-trigger.patch | 37 ++ .../0006-helios4-device-tree.patch | 387 ++++++++++++++ .../u-boot-helios4/add-fdtfile-env.patch | 15 + .../u-boot-helios4/add-mmc-target.patch | 53 ++ .../binary-header-toolchain-auto-select.patch | 17 + .../u-boot-helios4/disable-jffs-support.patch | 12 + .../u-boot-helios4/loading-boot-scr.patch | 79 +++ .../make-build-more-silent.patch | 13 + .../tools-bin_hdr-compiler-fixes.patch | 31 ++ 23 files changed, 1572 insertions(+), 45 deletions(-) create mode 100644 config/boards/helios4.conf create mode 100644 config/bootenv/helios4-default.txt create mode 100644 config/bootscripts/boot-helios4.cmd rename patch/kernel/mvebu-default/{ => board_clearfogbase}/add-dtb-file-for-backwards-compatibility.patch (100%) rename patch/kernel/mvebu-default/{ => board_clearfogbase}/add-spi-flash.patch (100%) create mode 100644 patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch create mode 100644 patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch create mode 100644 patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled create mode 100644 patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled create mode 100644 patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled create mode 100644 patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch create mode 100644 patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch create mode 100644 patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch create mode 100644 patch/u-boot/u-boot-helios4/add-fdtfile-env.patch create mode 100644 patch/u-boot/u-boot-helios4/add-mmc-target.patch create mode 100644 patch/u-boot/u-boot-helios4/binary-header-toolchain-auto-select.patch create mode 100644 patch/u-boot/u-boot-helios4/disable-jffs-support.patch create mode 100644 patch/u-boot/u-boot-helios4/loading-boot-scr.patch create mode 100644 patch/u-boot/u-boot-helios4/make-build-more-silent.patch create mode 100644 patch/u-boot/u-boot-helios4/tools-bin_hdr-compiler-fixes.patch diff --git a/README.md b/README.md index 7e56d7d8c..3f56a732a 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,7 @@ -# Armbian +# Armbian - Helios4 -Ubuntu and Debian images for ARM based single-board computers -https://www.armbian.com +**This repo is only for developement of Helios4 support in Armbian Build Framework** -## How to build my own image or kernel? +To get latest Armbian please go to the [Official Armbian Git](https://github.com/armbian/build) -Supported build environments: -- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) guest inside a [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or other virtualization software, -- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) guest managed by [Vagrant](https://www.vagrantup.com/). This uses Virtualbox (as above) but does so in an easily repeatable way. Please check the [Armbian with Vagrant README](https://docs.armbian.com/Developer-Guide_Using-Vagrant/) for a quick start HOWTO, -- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) inside a [Docker](https://www.docker.com/), [systemd-nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) or other container environment [(example)](https://github.com/igorpecovnik/lib/pull/255#issuecomment-205045273). Building full OS images inside containers may not work, so this option is mostly for the kernel compilation, -- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) running natively on a dedicated PC or a server (**not** recommended unless you build kernel only, for full OS images always use virtualization as outlined above), -- **20GB disk space** or more and **2GB RAM** or more available for the VM, container or native OS, -- superuser rights (configured `sudo` or root access). - -**Execution** - - apt-get -y install git - git clone https://github.com/armbian/build - cd build - ./compile.sh - -Make sure that full path to the build script does not contain spaces. - -You will be prompted with a selection menu for a build option, a board name, a kernel branch and an OS release. Please check the documentation for [advanced options](https://docs.armbian.com/Developer-Guide_Build-Options/) and [additional customization](https://docs.armbian.com/Developer-Guide_User-Configurations/). - -Build process uses caching for the compilation and the debootstrap process, so consecutive runs with similar settings will be much faster. - -## Reporting issues - -Please read [this](https://github.com/igorpecovnik/lib/blob/master/.github/ISSUE_TEMPLATE.md) notice first before opening an issue. - -## More info: - -- [Documentation](https://docs.armbian.com/Developer-Guide_Build-Preparation/) -- [Prebuilt images](https://www.armbian.com/download/) -- [Support forums](https://forum.armbian.com/ "Armbian support forum") -- [Project at Github](https://github.com/igorpecovnik/lib) diff --git a/config/boards/helios4.conf b/config/boards/helios4.conf new file mode 100644 index 000000000..18eccb458 --- /dev/null +++ b/config/boards/helios4.conf @@ -0,0 +1,19 @@ +# Marvell Armada 388 2GB-ECC 4xSATA 2xUSB3.0 1xGBE +BOARD_NAME="Helios4" +LINUXFAMILY="mvebu" +BOOTCONFIG="armada_38x_helios4_config" +MODULES="mv_cesa" +BUILD_DESKTOP="no" +# +KERNEL_TARGET="default" +CLI_TARGET="jessie:default" + +CLI_BETA_TARGET="" +# +RECOMMENDED="Debian_jessie_default:90" +# +BOARDRATING="" +CHIP="https://kobol.io/helios4" +REVIEW="" +HARDWARE="https://wiki.kobol.io" +FORUMS="" diff --git a/config/bootenv/helios4-default.txt b/config/bootenv/helios4-default.txt new file mode 100644 index 000000000..682c692d2 --- /dev/null +++ b/config/bootenv/helios4-default.txt @@ -0,0 +1,3 @@ +verbosity=1 +ethaddr=00:50:43:84:fb:2f + diff --git a/config/bootscripts/boot-helios4.cmd b/config/bootscripts/boot-helios4.cmd new file mode 100644 index 000000000..7c0ea6aaf --- /dev/null +++ b/config/bootscripts/boot-helios4.cmd @@ -0,0 +1,37 @@ +# DO NOT EDIT THIS FILE +# +# Please edit /boot/armbianEnv.txt to set supported parameters +# + +# default values +setenv rootdev "/dev/mmcblk0p1" +setenv rootfstype "ext4" +setenv verbosity "1" +setenv ethaddr "00:50:43:84:fb:2f" + +# fdtfile should come from compile-time u-boot patches +if test -z "${fdtfile}"; then + setenv fdtfile "armada-388-helios4.dtb" +fi + +test -z "${boot_interface}" && setenv boot_interface "mmc" + +echo "Boot script loaded from ${boot_interface}" + +if load ${boot_interface} 0:1 ${loadaddr} ${prefix}armbianEnv.txt; then + env import -t ${loadaddr} ${filesize} +fi + +setenv bootargs "console=ttyS0,115200 root=${rootdev} rootwait rootfstype=${rootfstype} ubootdev=${boot_interface} scandelay loglevel=${verbosity} ${extraargs}" + +load ${boot_interface} 0:1 ${fdt_addr} ${prefix}dtb/${fdtfile} +load ${boot_interface} 0:1 ${ramdisk_addr_r} ${prefix}uInitrd +load ${boot_interface} 0:1 ${kernel_addr_r} ${prefix}zImage + +setenv fdt_high 0xffffffff +setenv initrd_high 0xffffffff + +bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr} + +# Recompile with: +# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr diff --git a/config/kernel/linux-mvebu-default.config b/config/kernel/linux-mvebu-default.config index 6ccd3fc77..e2b64a7e8 100644 --- a/config/kernel/linux-mvebu-default.config +++ b/config/kernel/linux-mvebu-default.config @@ -1933,6 +1933,8 @@ CONFIG_SCSI_OSD_DPRINT_SENSE=1 CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_ATA_VERBOSE_ERROR is not set +CONFIG_ARCH_WANT_LIBATA_LEDS=y +CONFIG_ATA_LEDS=y CONFIG_SATA_PMP=y # @@ -3004,7 +3006,7 @@ CONFIG_SENSORS_GPIO_FAN=m # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set +CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set # CONFIG_SENSORS_LM80 is not set @@ -3026,6 +3028,7 @@ CONFIG_SENSORS_GPIO_FAN=m # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set +CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHTC1 is not set @@ -3274,6 +3277,7 @@ CONFIG_REGULATOR_GPIO=m # CONFIG_REGULATOR_MAX8973 is not set # CONFIG_REGULATOR_MT6311 is not set # CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PWM=m # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set @@ -3371,11 +3375,14 @@ CONFIG_LCD_LMS501KF03=m CONFIG_LCD_HX8357=m CONFIG_BACKLIGHT_CLASS_DEVICE=m CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_PM8941_WLED=m CONFIG_BACKLIGHT_ADP8860=m CONFIG_BACKLIGHT_ADP8870=m CONFIG_BACKLIGHT_88PM860X=m +# CONFIG_BACKLIGHT_LM3630A is not set CONFIG_BACKLIGHT_LM3639=m +# CONFIG_BACKLIGHT_LP855X is not set CONFIG_BACKLIGHT_GPIO=m CONFIG_BACKLIGHT_LV5207LP=m CONFIG_BACKLIGHT_BD6107=m @@ -3847,6 +3854,7 @@ CONFIG_LEDS_GPIO=m # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set # CONFIG_LEDS_DAC124S085 is not set +CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set @@ -4218,6 +4226,7 @@ CONFIG_COMMON_CLK_SCPI=m # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_CLK_QORIQ is not set +CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set CONFIG_MVEBU_CLK_COMMON=y @@ -4526,7 +4535,10 @@ CONFIG_IIO_SYSFS_TRIGGER=m # CONFIG_TSYS02D is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set -# CONFIG_PWM is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARMADA_370_XP_IRQ=y diff --git a/config/sources/mvebu.conf b/config/sources/mvebu.conf index 51cfb3e05..8d74df18b 100644 --- a/config/sources/mvebu.conf +++ b/config/sources/mvebu.conf @@ -1,16 +1,33 @@ -BOOTSOURCE='https://github.com/SolidRun/u-boot-armada38x' -BOOTBRANCH='branch:u-boot-2013.01-15t1-clearfog' -BOOTDIR='u-boot-armada' -BOOTSCRIPT='boot-marvell.cmd:boot.cmd' +case $BOARD in + helios4) + BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git' + BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4' + BOOTDIR='u-boot-helios4' + BOOTPATCHDIR='u-boot-helios4' + BOOTSCRIPT='boot-helios4.cmd:boot.cmd' -UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc u-boot-uart.mmc + UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc" + + BOOTENV_FILE='helios4-default.txt' + ;; + + *) + BOOTSOURCE='https://github.com/SolidRun/u-boot-armada38x' + BOOTBRANCH='branch:u-boot-2013.01-15t1-clearfog' + BOOTDIR='u-boot-armada' + BOOTSCRIPT='boot-marvell.cmd:boot.cmd' + + UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc u-boot-uart.mmc u-boot.sata;sata;u-boot.sata u-boot-uart.sata u-boot.flash;spi;u-boot.flash u-boot-uart.flash" -UBOOT_USE_GCC='== 4.9' -UBOOT_COMPILER='arm-linux-gnueabi-' + BOOTENV_FILE='clearfog-default.txt' + ;; +esac -BOOTENV_FILE='clearfog-default.txt' + +UBOOT_USE_GCC='< 5.0' +UBOOT_COMPILER='arm-linux-gnueabi-' HAS_UUID_SUPPORT=yes case $BRANCH in diff --git a/patch/kernel/mvebu-default/add-dtb-file-for-backwards-compatibility.patch b/patch/kernel/mvebu-default/board_clearfogbase/add-dtb-file-for-backwards-compatibility.patch similarity index 100% rename from patch/kernel/mvebu-default/add-dtb-file-for-backwards-compatibility.patch rename to patch/kernel/mvebu-default/board_clearfogbase/add-dtb-file-for-backwards-compatibility.patch diff --git a/patch/kernel/mvebu-default/add-spi-flash.patch b/patch/kernel/mvebu-default/board_clearfogbase/add-spi-flash.patch similarity index 100% rename from patch/kernel/mvebu-default/add-spi-flash.patch rename to patch/kernel/mvebu-default/board_clearfogbase/add-spi-flash.patch diff --git a/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch b/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch new file mode 100644 index 000000000..b3f11fb83 --- /dev/null +++ b/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch @@ -0,0 +1,29 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index face816..9dc5e06 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -751,6 +751,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ + armada-385-linksys-cobra.dtb \ + armada-388-clearfog-base.dtb \ + armada-388-clearfog-pro.dtb \ ++ armada-388-clearfog.dtb \ + armada-388-db.dtb \ + armada-388-gp.dtb \ + armada-388-rd.dtb +diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts +new file mode 100644 +index 0000000..7d906da +--- /dev/null ++++ b/arch/arm/boot/dts/armada-388-clearfog.dts +@@ -0,0 +1,11 @@ ++/* ++ * Device Tree file for backwards compatibility with old file name expected by boot script ++ * ++ * This file is distributed in the hope that it will be useful ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "armada-388-clearfog-pro.dts" diff --git a/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch b/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch new file mode 100644 index 000000000..4dd79d3d0 --- /dev/null +++ b/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch @@ -0,0 +1,34 @@ +diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi +index 1307e83e..e019ca23 100644 +--- a/arch/arm/boot/dts/armada-388-clearfog.dtsi ++++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi +@@ -263,7 +263,28 @@ + compatible = "w25q32", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <3000000>; +- status = "enabled"; ++ status = "okay"; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "uboot"; ++ reg = <0x0 0x100000>; ++ }; ++ ++ partition@100000 { ++ label = "env"; ++ reg = <0x100000 0x100000>; ++ }; ++ ++ partition@200000 { ++ label = "data"; ++ reg = <0x200000 0x200000>; ++ }; ++ }; + }; + }; + diff --git a/patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled b/patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled new file mode 100644 index 000000000..045c82886 --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled @@ -0,0 +1,488 @@ +From 65bce3cd01230b283915be86196f5e1318c18dd6 Mon Sep 17 00:00:00 2001 +From: aprayoga +Date: Sun, 3 Sep 2017 15:59:11 +0800 +Subject: gpio: mvebu: Add limited PWM support + +backported from https://patchwork.kernel.org/patch/9681399/ + +* Remove atomic PWM API portion as this is not supported on LK4.4 +and use https://patchwork.ozlabs.org/patch/739591/ instead. +--- + .../devicetree/bindings/gpio/gpio-mvebu.txt | 31 +++ + MAINTAINERS | 2 + + drivers/gpio/gpio-mvebu.c | 309 ++++++++++++++++++++- + 3 files changed, 328 insertions(+), 14 deletions(-) + +diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt +index 6b76891..b6cdcb2 100644 +--- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt ++++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt +@@ -46,6 +46,23 @@ Optional: + The base of CP0 bank0 should be 20 (after AP-806 pins) the base of CP0 bank1 should be + 52 (after AP-806, and CP0 bank0 pins) + ++Optional properties: ++ ++In order to use the gpio lines in PWM mode, some additional optional ++properties are required. Only Armada 370 and XP support these properties. ++ ++- reg: an additional register set is needed, for the GPIO Blink ++ Counter on/off registers. ++ ++- reg-names: Must contain an entry "pwm" corresponding to the ++ additional register range needed for pwm operation. ++ ++- #pwm-cells: Should be two. The first cell is the pin number. The ++ second cell is reserved for flags and should be set to 0, so it has a ++ known value. It then becomes possible to use it in the future. ++ ++- clocks: Must be a phandle to the clock for the gpio controller. ++ + Example: + + gpio0: gpio@d0018100 { +@@ -59,3 +76,17 @@ Example: + #interrupt-cells = <2>; + interrupts = <16>, <17>, <18>, <19>; + }; ++ ++ gpio1: gpio@18140 { ++ compatible = "marvell,armada-370-xp-gpio"; ++ reg = <0x18140 0x40>, <0x181c8 0x08>; ++ reg-names = "gpio", "pwm"; ++ ngpios = <17>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ #pwm-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = <87>, <88>, <89>; ++ clocks = <&coreclk 0>; ++ }; +diff --git a/MAINTAINERS b/MAINTAINERS +index 7008b0d..d272aca 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -8635,6 +8635,8 @@ F: include/linux/pwm.h + F: drivers/pwm/ + F: drivers/video/backlight/pwm_bl.c + F: include/linux/pwm_backlight.h ++F: drivers/gpio/gpio-mvebu.c ++F: Documentation/devicetree/bindings/gpio/gpio-mvebu.txt + + PXA2xx/PXA3xx SUPPORT + M: Daniel Mack +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index ffea532..8775123 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -42,29 +42,43 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include ++ ++#include "gpiolib.h" + + /* + * GPIO unit register offsets. + */ +-#define GPIO_OUT_OFF 0x0000 +-#define GPIO_IO_CONF_OFF 0x0004 +-#define GPIO_BLINK_EN_OFF 0x0008 +-#define GPIO_IN_POL_OFF 0x000c +-#define GPIO_DATA_IN_OFF 0x0010 +-#define GPIO_EDGE_CAUSE_OFF 0x0014 +-#define GPIO_EDGE_MASK_OFF 0x0018 +-#define GPIO_LEVEL_MASK_OFF 0x001c ++#define GPIO_OUT_OFF 0x0000 ++#define GPIO_IO_CONF_OFF 0x0004 ++#define GPIO_BLINK_EN_OFF 0x0008 ++#define GPIO_IN_POL_OFF 0x000c ++#define GPIO_DATA_IN_OFF 0x0010 ++#define GPIO_EDGE_CAUSE_OFF 0x0014 ++#define GPIO_EDGE_MASK_OFF 0x0018 ++#define GPIO_LEVEL_MASK_OFF 0x001c ++#define GPIO_BLINK_CNT_SELECT_OFF 0x0020 ++ ++/* ++ * PWM register offsets. ++ */ ++#define PWM_BLINK_ON_DURATION_OFF 0x0 ++#define PWM_BLINK_OFF_DURATION_OFF 0x4 ++ + + /* The MV78200 has per-CPU registers for edge mask and level mask */ + #define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18) + #define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C) + +-/* The Armada XP has per-CPU registers for interrupt cause, interrupt ++/* ++ * The Armada XP has per-CPU registers for interrupt cause, interrupt + * mask and interrupt level mask. Those are relative to the +- * percpu_membase. */ ++ * percpu_membase. ++ */ + #define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4) + #define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4) + #define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4) +@@ -75,6 +89,23 @@ + + #define MVEBU_MAX_GPIO_PER_BANK 32 + ++struct mvebu_pwm { ++ void __iomem *membase; ++ unsigned long clk_rate; ++ struct gpio_desc *gpiod; ++ bool used; ++ unsigned int pin; ++ struct pwm_chip chip; ++ int id; ++ spinlock_t lock; ++ struct mvebu_gpio_chip *mvchip; ++ ++ /* Used to preserve GPIO/PWM registers across suspend/resume */ ++ u32 blink_select; ++ u32 blink_on_duration; ++ u32 blink_off_duration; ++}; ++ + struct mvebu_gpio_chip { + struct gpio_chip chip; + spinlock_t lock; +@@ -84,6 +115,10 @@ struct mvebu_gpio_chip { + struct irq_domain *domain; + int soc_variant; + ++ /* Used for PWM support */ ++ struct clk *clk; ++ struct mvebu_pwm *mvpwm; ++ + /* Used to preserve GPIO registers across suspend/resume */ + u32 out_reg; + u32 io_conf_reg; +@@ -102,6 +137,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) + return mvchip->membase + GPIO_OUT_OFF; + } + ++static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip) ++{ ++ return mvchip->membase + GPIO_BLINK_CNT_SELECT_OFF; ++} ++ + static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) + { + return mvchip->membase + GPIO_BLINK_EN_OFF; +@@ -182,6 +222,20 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) + } + + /* ++ * Functions returning addresses of individual registers for a given ++ * PWM controller. ++ */ ++static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwm *mvpwm) ++{ ++ return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF; ++} ++ ++static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwm *mvpwm) ++{ ++ return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF; ++} ++ ++/* + * Functions implementing the gpio_chip methods + */ + +@@ -489,6 +543,220 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + ++/* ++ * Functions implementing the pwm_chip methods ++ */ ++static struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip) ++{ ++ return container_of(chip, struct mvebu_pwm, chip); ++} ++ ++static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ struct gpio_desc *desc; ++ unsigned long flags; ++ int ret = 0; ++ ++ spin_lock_irqsave(&mvpwm->lock, flags); ++ if (mvpwm->gpiod) { ++ ret = -EBUSY; ++ } else { ++ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm); ++ if (!desc) { ++ ret = -ENODEV; ++ goto out; ++ } ++ ret = gpiod_request(desc, "mvebu-pwm"); ++ if (ret) ++ goto out; ++ ++ ret = gpiod_direction_output(desc, 0); ++ if (ret) { ++ gpiod_free(desc); ++ goto out; ++ } ++ ++ mvpwm->gpiod = desc; ++ mvpwm->pin = pwm->pwm - mvchip->chip.base; ++ mvpwm->used = true; ++ } ++ ++out: ++ spin_unlock_irqrestore(&mvpwm->lock, flags); ++ return ret; ++} ++ ++static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&mvpwm->lock, flags); ++ gpiod_free(mvpwm->gpiod); ++ mvpwm->used = false; ++ spin_unlock_irqrestore(&mvpwm->lock, flags); ++} ++ ++static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd, ++ int duty_ns, int period_ns) ++{ ++ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = pwm->mvchip; ++ unsigned int on, off; ++ unsigned long long val; ++ u32 u; ++ ++ val = (unsigned long long) pwm->clk_rate * duty_ns; ++ do_div(val, NSEC_PER_SEC); ++ if (val > UINT_MAX) ++ return -EINVAL; ++ if (val) ++ on = val; ++ else ++ on = 1; ++ ++ val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns); ++ do_div(val, NSEC_PER_SEC); ++ if (val > UINT_MAX) ++ return -EINVAL; ++ if (val) ++ off = val; ++ else ++ off = 1; ++ ++ u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); ++ u &= ~(1 << pwm->pin); ++ u |= (pwm->id << pwm->pin); ++ writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip)); ++ ++ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(pwm)); ++ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(pwm)); ++ ++ return 0; ++} ++ ++static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ ++ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 1); ++ ++ return 0; ++} ++ ++static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ ++ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 0); ++} ++ ++static const struct pwm_ops mvebu_pwm_ops = { ++ .request = mvebu_pwm_request, ++ .free = mvebu_pwm_free, ++ .config = mvebu_pwm_config, ++ .enable = mvebu_pwm_enable, ++ .disable = mvebu_pwm_disable, ++ .owner = THIS_MODULE, ++}; ++ ++static void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) ++{ ++ struct mvebu_pwm *mvpwm = mvchip->mvpwm; ++ ++ mvpwm->blink_select = ++ readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); ++ mvpwm->blink_on_duration = ++ readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); ++ mvpwm->blink_off_duration = ++ readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); ++} ++ ++static void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) ++{ ++ struct mvebu_pwm *mvpwm = mvchip->mvpwm; ++ ++ writel_relaxed(mvpwm->blink_select, ++ mvebu_gpioreg_blink_select(mvchip)); ++ writel_relaxed(mvpwm->blink_on_duration, ++ mvebu_pwmreg_blink_on_duration(mvpwm)); ++ writel_relaxed(mvpwm->blink_off_duration, ++ mvebu_pwmreg_blink_off_duration(mvpwm)); ++} ++ ++/* ++ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs ++ * don't have this hardware. So if we don't have the necessary ++ * resource, it is not an error. ++ */ ++static int mvebu_pwm_probe(struct platform_device *pdev, ++ struct mvebu_gpio_chip *mvchip, ++ int id) ++{ ++ struct device *dev = &pdev->dev; ++ struct mvebu_pwm *mvpwm; ++ struct resource *res; ++ u32 set; ++ ++ if (!of_device_is_compatible(mvchip->chip.of_node, ++ "marvell,armada-370-xp-gpio")) ++ return 0; ++ ++ if (IS_ERR(mvchip->clk)) ++ return PTR_ERR(mvchip->clk); ++ ++ /* ++ * There are only two sets of PWM configuration registers for ++ * all the GPIO lines on those SoCs which this driver reserves ++ * for the first two GPIO chips. So if the resource is missing ++ * we can't treat it as an error. ++ */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); ++ if (!res) ++ return 0; ++ ++ /* ++ * Use set A for lines of GPIO chip with id 0, B for GPIO chip ++ * with id 1. Don't allow further GPIO chips to be used for PWM. ++ */ ++ if (id == 0) ++ set = 0; ++ else if (id == 1) ++ set = U32_MAX; ++ else ++ return -EINVAL; ++ writel_relaxed(set, mvebu_gpioreg_blink_select(mvchip)); ++ mvpwm->id = id; ++ ++ mvpwm = devm_kzalloc(dev, sizeof(struct mvebu_pwm), GFP_KERNEL); ++ if (!mvpwm) ++ return -ENOMEM; ++ mvchip->mvpwm = mvpwm; ++ mvpwm->mvchip = mvchip; ++ ++ mvpwm->membase = devm_ioremap_resource(dev, res); ++ if (IS_ERR(mvpwm->membase)) ++ return PTR_ERR(mvpwm->membase); ++ ++ mvpwm->clk_rate = clk_get_rate(mvchip->clk); ++ if (!mvpwm->clk_rate) { ++ dev_err(dev, "failed to get clock rate\n"); ++ return -EINVAL; ++ } ++ ++ mvpwm->chip.dev = dev; ++ mvpwm->chip.ops = &mvebu_pwm_ops; ++ mvpwm->chip.npwm = mvchip->chip.ngpio; ++ ++ spin_lock_init(&mvpwm->lock); ++ ++ return pwmchip_add(&mvpwm->chip); ++} ++ + #ifdef CONFIG_DEBUG_FS + #include + +@@ -561,6 +829,10 @@ static const struct of_device_id mvebu_gpio_of_match[] = { + .data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP, + }, + { ++ .compatible = "marvell,armada-370-xp-gpio", ++ .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION, ++ }, ++ { + /* sentinel */ + }, + }; +@@ -607,6 +879,9 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state) + BUG(); + } + ++ if (IS_ENABLED(CONFIG_PWM)) ++ mvebu_pwm_suspend(mvchip); ++ + return 0; + } + +@@ -650,6 +925,9 @@ static int mvebu_gpio_resume(struct platform_device *pdev) + BUG(); + } + ++ if (IS_ENABLED(CONFIG_PWM)) ++ mvebu_pwm_resume(mvchip); ++ + return 0; + } + +@@ -661,7 +939,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + struct resource *res; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; +- struct clk *clk; + unsigned int ngpios; + unsigned int gpio_base = -1; + int soc_variant; +@@ -695,10 +972,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + return id; + } + +- clk = devm_clk_get(&pdev->dev, NULL); ++ mvchip->clk = devm_clk_get(&pdev->dev, NULL); + /* Not all SoCs require a clock.*/ +- if (!IS_ERR(clk)) +- clk_prepare_enable(clk); ++ if (!IS_ERR(mvchip->clk)) ++ clk_prepare_enable(mvchip->clk); + + mvchip->soc_variant = soc_variant; + mvchip->chip.label = dev_name(&pdev->dev); +@@ -835,6 +1112,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + goto err_generic_chip; + } + ++ /* Armada 370/XP has simple PWM support for GPIO lines */ ++ if (IS_ENABLED(CONFIG_PWM)) ++ return mvebu_pwm_probe(pdev, mvchip, id); ++ + return 0; + + err_generic_chip: +-- +2.7.4 + diff --git a/patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled b/patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled new file mode 100644 index 000000000..e19aa068d --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled @@ -0,0 +1,62 @@ +From e85a492b45f49e374f544bbffe8c975b1dabe87f Mon Sep 17 00:00:00 2001 +From: aprayoga +Date: Sun, 3 Sep 2017 16:08:59 +0800 +Subject: ARM: dts: mvebu: Add PWM properties to .dtsi (armada-38x) + +reference: +https://patchwork.kernel.org/patch/9681397/ +--- + arch/arm/boot/dts/armada-38x.dtsi | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi +index a73cbe2..f87204f 100644 +--- a/arch/arm/boot/dts/armada-38x.dtsi ++++ b/arch/arm/boot/dts/armada-38x.dtsi +@@ -345,31 +345,39 @@ + }; + + gpio0: gpio@18100 { +- compatible = "marvell,orion-gpio"; +- reg = <0x18100 0x40>; ++ compatible = "marvell,armada-370-xp-gpio", ++ "marvell,orion-gpio"; ++ reg = <0x18100 0x40>, <0x181c0 0x08>; ++ reg-names = "gpio", "pwm"; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; ++ #pwm-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + ; ++ clocks = <&coreclk 0>; + }; + + gpio1: gpio@18140 { +- compatible = "marvell,orion-gpio"; +- reg = <0x18140 0x40>; ++ compatible = "marvell,armada-370-xp-gpio", ++ "marvell,orion-gpio"; ++ reg = <0x18140 0x40>, <0x181c8 0x08>; ++ reg-names = "gpio", "pwm"; + ngpios = <28>; + gpio-controller; + #gpio-cells = <2>; ++ #pwm-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + ; ++ clocks = <&coreclk 0>; + }; + + system-controller@18200 { +-- +2.7.4 + diff --git a/patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled b/patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled new file mode 100644 index 000000000..5180ec9a1 --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled @@ -0,0 +1,35 @@ +From facb61a995ceac9b307159f0eb1e8666ce353ef0 Mon Sep 17 00:00:00 2001 +From: Andrew Lunn +Date: Fri, 14 Apr 2017 17:40:54 +0200 +Subject: ARM: mvebu: Enable SENSORS_PWM_FAN in defconfig + +Now that the GPIO driver also supports PWM operation, enable the PWM +framework and fan driver in mvebu_v7_defconfig. + +Signed-off-by: Andrew Lunn +URL: https://patchwork.ozlabs.org/patch/427297/ +[Ralph Sennhauser: add fan driver to defconfig] +Signed-off-by: Ralph Sennhauser +Tested-by: Andrew Lunn +Acked-by: Linus Walleij +Signed-off-by: Gregory CLEMENT +--- + arch/arm/configs/mvebu_v7_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig +index cf363ab..98cc3da 100644 +--- a/arch/arm/configs/mvebu_v7_defconfig ++++ b/arch/arm/configs/mvebu_v7_defconfig +@@ -132,6 +132,8 @@ CONFIG_DMADEVICES=y + CONFIG_MV_XOR=y + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_MEMORY=y ++CONFIG_PWM=y ++CONFIG_SENSORS_PWM_FAN=y + CONFIG_EXT4_FS=y + CONFIG_ISO9660_FS=y + CONFIG_JOLIET=y +-- +2.7.4 + diff --git a/patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch b/patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch new file mode 100644 index 000000000..272964ec1 --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch @@ -0,0 +1,179 @@ +From 5843af891d0dabf9bb80039cfe807d01e9495154 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 12 Dec 2014 13:38:33 +0100 +Subject: libata: add ledtrig support + +This adds a LED trigger for each ATA port indicating disk activity. + +As this is needed only on specific platforms (NAS SoCs and such), +these platforms should define ARCH_WANTS_LIBATA_LEDS if there +are boards with LED(s) intended to indicate ATA disk activity and +need the OS to take care of that. +In that way, if not selected, LED trigger support not will be +included in libata-core and both, codepaths and structures remain +untouched. + +Signed-off-by: Daniel Golle +--- + drivers/ata/Kconfig | 16 ++++++++++++++ + drivers/ata/libata-core.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/libata.h | 7 ++++++ + 3 files changed, 79 insertions(+) + +diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig +index 6aaa3f8..4e24b64 100644 +--- a/drivers/ata/Kconfig ++++ b/drivers/ata/Kconfig +@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR + + If unsure, say Y. + ++config ARCH_WANT_LIBATA_LEDS ++ bool ++ ++config ATA_LEDS ++ bool "support ATA port LED triggers" ++ depends on ARCH_WANT_LIBATA_LEDS ++ select NEW_LEDS ++ select LEDS_CLASS ++ select LEDS_TRIGGERS ++ default y ++ help ++ This option adds a LED trigger for each registered ATA port. ++ It is used to drive disk activity leds connected via GPIO. ++ ++ If unsure, say N. ++ + config ATA_ACPI + bool "ATA ACPI Support" + depends on ACPI +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index b0b77b6..1400f4d 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -728,6 +728,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) + return block; + } + ++ + /** + * ata_build_rw_tf - Build ATA taskfile for given read/write request + * @tf: Target ATA taskfile +@@ -4757,6 +4758,30 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) + } + + /** ++ * ata_led_act - Trigger port activity LED ++ * @ap: indicating port ++ * ++ * Blinks any LEDs registered to the trigger. ++ * Commonly used with leds-gpio on NAS systems with disk activity ++ * indicator LEDs. ++ * ++ * LOCKING: ++ * None. ++ */ ++static inline void ata_led_act(struct ata_port *ap) ++{ ++#if CONFIG_ATA_LEDS ++#define LIBATA_BLINK_DELAY 20 /* ms */ ++ unsigned long led_delay = LIBATA_BLINK_DELAY; ++ ++ if (unlikely(!ap->ledtrig)) ++ return; ++ ++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); ++#endif /* CONFIG_ATA_LEDS */ ++} ++ ++/** + * ata_qc_new_init - Request an available ATA command, and initialize it + * @dev: Device from whom we request an available command structure + * @tag: tag +@@ -4780,6 +4805,9 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) + if (tag < 0) + return NULL; + } ++#if CONFIG_ATA_LEDS ++ ata_led_act(ap); ++#endif + + qc = __ata_qc_from_tag(ap, tag); + qc->tag = tag; +@@ -5677,6 +5705,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) + ap->stats.unhandled_irq = 1; + ap->stats.idle_irq = 1; + #endif ++#if CONFIG_ATA_LEDS ++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); ++#endif + ata_sff_port_init(ap); + + return ap; +@@ -5698,6 +5729,12 @@ static void ata_host_release(struct device *gendev, void *res) + + kfree(ap->pmp_link); + kfree(ap->slave_link); ++#if CONFIG_ATA_LEDS ++ if (ap->ledtrig) { ++ led_trigger_unregister(ap->ledtrig); ++ kfree(ap->ledtrig); ++ }; ++#endif + kfree(ap); + host->ports[i] = NULL; + } +@@ -6145,6 +6182,25 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) + host->ports[i]->local_port_no = i + 1; + } + ++#if CONFIG_ATA_LEDS ++ /* register LED triggers for all ports */ ++ for (i = 0; i < host->n_ports; i++) { ++ if (unlikely(!host->ports[i]->ledtrig)) ++ continue; ++ ++ snprintf(host->ports[i]->ledtrig_name, ++ sizeof(host->ports[i]->ledtrig_name), "ata%u", ++ host->ports[i]->print_id); ++ ++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; ++ ++ if (led_trigger_register(host->ports[i]->ledtrig)) { ++ kfree(host->ports[i]->ledtrig); ++ host->ports[i]->ledtrig = NULL; ++ } ++ } ++#endif ++ + /* Create associated sysfs transport objects */ + for (i = 0; i < host->n_ports; i++) { + rc = ata_tport_add(host->dev,host->ports[i]); +diff --git a/include/linux/libata.h b/include/linux/libata.h +index b20a275..50eeee3 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + /* + * Define if arch has non-standard setup. This is a _PCI_ standard +@@ -877,6 +878,12 @@ struct ata_port { + #ifdef CONFIG_ATA_ACPI + struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ + #endif ++ ++#ifdef CONFIG_ATA_LEDS ++ struct led_trigger *ledtrig; ++ char ledtrig_name[8]; ++#endif ++ + /* owned by EH */ + u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; + }; +-- +2.7.4 + diff --git a/patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch b/patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch new file mode 100644 index 000000000..2b5952f12 --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch @@ -0,0 +1,37 @@ +From 9ee6345ef82f7af5f98e17a40e667f8ad6b2fa1b Mon Sep 17 00:00:00 2001 +From: aprayoga +Date: Sun, 3 Sep 2017 18:10:12 +0800 +Subject: Enable ATA port LED trigger + +--- + arch/arm/configs/mvebu_v7_defconfig | 1 + + arch/arm/mach-mvebu/Kconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig +index cf363ab..19449d3 100644 +--- a/arch/arm/configs/mvebu_v7_defconfig ++++ b/arch/arm/configs/mvebu_v7_defconfig +@@ -61,6 +61,7 @@ CONFIG_MTD_SPI_NOR=y + CONFIG_EEPROM_AT24=y + CONFIG_BLK_DEV_SD=y + CONFIG_ATA=y ++CONFIG_ATA_LEDS=y + CONFIG_SATA_AHCI=y + CONFIG_AHCI_MVEBU=y + CONFIG_SATA_MV=y +diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig +index 053ea9d..aa1f389 100644 +--- a/arch/arm/mach-mvebu/Kconfig ++++ b/arch/arm/mach-mvebu/Kconfig +@@ -52,6 +52,7 @@ config MACH_ARMADA_375 + + config MACH_ARMADA_38X + bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7 ++ select ARCH_WANT_LIBATA_LEDS + select ARM_ERRATA_720789 + select ARM_ERRATA_753970 + select ARM_GIC +-- +2.7.4 + diff --git a/patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch b/patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch new file mode 100644 index 000000000..0a1ec90cc --- /dev/null +++ b/patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch @@ -0,0 +1,387 @@ +From 9fe4b82ed5e62ac82df8294e9e02b4ffab23bb47 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Sun, 19 Mar 2017 17:27:01 +0800 +Subject: Initial device tree + +- Tested using clearfrog u-boot +- Increase SD Card clock to 50 MHz from default 25 MHz +- All 7 LED declared as led-gpio +- LED1 (system) default to hearbeat +- LED7 (USB) triggered by USB Host activity +- GPIO23 (MPP23) declared as GPIO button +- SPI NOR flash declared as MTD +- Enable IO expander interrupt +- Allocate GPIOs for fans +--- + arch/arm/boot/dts/armada-388-helios4.dts | 318 ++++++++++++++++++++++++++++++ + 1 file changed, 318 insertions(+) + create mode 100644 arch/arm/boot/dts/armada-388-helios4.dts + +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +new file mode 100644 +index 0000000..b7a2122 +--- /dev/null ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -0,0 +1,346 @@ ++/* ++ * Device Tree file for Helios4 ++ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) ++ * ++ * Copyright (C) 2017 ++ * ++ */ ++ ++/dts-v1/; ++#include "armada-388.dtsi" ++#include "armada-38x-solidrun-microsom.dtsi" ++ ++/ { ++ model = "Helios4"; ++ compatible = "marvell,armada388", ++ "marvell,armada385", "marvell,armada380"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x00000000 0x40000000>; /* 1 GB */ ++ }; ++ ++ aliases { ++ /* So that mvebu u-boot can update the MAC addresses */ ++ ethernet1 = ð0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reg_12v: regulator-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "power_brick_12V"; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "3P3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <®_12v>; ++ }; ++ ++ reg_5p0v_hdd: regulator-5v-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "5V_HDD"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <®_12v>; ++ }; ++ ++ reg_5p0v_usb: regulator-5v-usb { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB-PWR"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ enable-active-high; ++ gpio = <&expander0 6 GPIO_ACTIVE_HIGH>; ++ vin-supply = <®_12v>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ pinctrl-0 = <&user_button_pins>; ++ pinctrl-names = "default"; ++ ++ button_0 { ++ label = "User Button"; ++ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; ++ linux,can-disable; ++ linux,code = ; ++ }; ++ }; ++ ++ system-leds { ++ compatible = "gpio-leds"; ++ status-led { ++ label = "helios4:green:status"; ++ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ ++ fault-led { ++ label = "helios4:red:fault"; ++ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; ++ default-state = "keep"; ++ }; ++ }; ++ ++ io-leds { ++ compatible = "gpio-leds"; ++ sata1-led { ++ label = "helios4:green:ata1"; ++ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata1"; ++ default-state = "off"; ++ }; ++ sata2-led { ++ label = "helios4:green:ata2"; ++ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata2"; ++ default-state = "off"; ++ }; ++ sata3-led { ++ label = "helios4:green:ata3"; ++ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata3"; ++ default-state = "off"; ++ }; ++ sata4-led { ++ label = "helios4:green:ata4"; ++ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata4"; ++ default-state = "off"; ++ }; ++ usb-led { ++ label = "helios4:green:usb"; ++ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "usb-host"; ++ default-state = "off"; ++ }; ++ }; ++ ++ fan1: j10-pwm { ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 9 3000>; ++ }; ++ ++ fan2: j17-pwm { ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 4 4500>; ++ }; ++ ++ usb2_phy: usb2-phy { ++ compatible = "usb-nop-xceiv"; ++ vbus-regulator = <®_5p0v_usb>; ++ }; ++ ++ usb3_phy: usb3-phy { ++ compatible = "usb-nop-xceiv"; ++ //vbus-regulator = <®_5p0v_usb>; ++ }; ++ ++ soc { ++ internal-regs { ++ i2c@11000 { ++ clock-frequency = <100000>; ++ pinctrl-0 = <&i2c0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ /* ++ * PCA9655 GPIO expander, up to 1MHz clock. ++ * 0-Board Revision bit 0 # ++ * 1-Board Revision bit 1 # ++ * 5-USB3 overcurrent ++ * 6-USB3 power ++ */ ++ expander0: gpio-expander@20 { ++ /* ++ * This is how it should be: ++ * compatible = "onnn,pca9655", ++ * "nxp,pca9555"; ++ * but you can't do this because of ++ * the way I2C works. ++ */ ++ compatible = "nxp,pca9555"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ reg = <0x20>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pca0_pins>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <18 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ board_rev_bit_0 { ++ gpio-hog; ++ gpios = <0 GPIO_ACTIVE_LOW>; ++ input; ++ line-name = "board-rev-0"; ++ }; ++ board_rev_bit_1 { ++ gpio-hog; ++ gpios = <1 GPIO_ACTIVE_LOW>; ++ input; ++ line-name = "board-rev-1"; ++ }; ++ usb3_ilimit { ++ gpio-hog; ++ gpios = <5 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "usb-overcurrent-status"; ++ }; ++ }; ++ ++ temp_sensor: temp@4c { ++ compatible = "ti,lm75"; ++ reg = <0x4c>; ++ vcc-supply = <®_3p3v>; ++ }; ++ ++ /* What device at 0x64 ? */ ++ }; ++ ++ i2c@11100 { ++ /* ++ * External I2C Bus for user peripheral ++ */ ++ clock-frequency = <400000>; ++ pinctrl-0 = <&helios_i2c1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ }; ++ ++ sata@a8000 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sata0: sata-port@0 { ++ reg = <0>; ++ }; ++ ++ sata1: sata-port@1 { ++ reg = <1>; ++ }; ++ }; ++ ++ sata@e0000 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sata2: sata-port@0 { ++ reg = <0>; ++ }; ++ ++ sata3: sata-port@1 { ++ reg = <1>; ++ }; ++ }; ++ ++ spi@10680 { ++ pinctrl-0 = <&spi1_pins ++ µsom_spi1_cs_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "w25q32", "jedec,spi-nor"; ++ reg = <0>; /* Chip select 0 */ ++ spi-max-frequency = <104000000>; ++ spi-cpha; ++ status = "okay"; ++ }; ++ }; ++ ++ sdhci@d8000 { ++ bus-width = <4>; ++ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; ++ no-1-8-v; ++ pinctrl-0 = <&helios_sdhci_pins ++ &helios_sdhci_cd_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ vmmc = <®_3p3v>; ++ wp-inverted; ++ max-frequency = <50000000>; ++ cap-sd-highspeed; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ keep-power-in-suspend; ++ wakeup-source; ++ }; ++ ++ usb@58000 { ++ //vcc-supply = <®_5p0v_usb>; ++ usb-phy = <&usb2_phy>; ++ status = "okay"; ++ }; ++ ++ usb3@f0000 { ++ status = "okay"; ++ }; ++ ++ usb3@f8000 { ++ status = "okay"; ++ }; ++ ++ pinctrl@18000 { ++ pca0_pins: pca0_pins { ++ marvell,pins = "mpp18"; ++ marvell,function = "gpio"; ++ }; ++ helios_i2c1_pins: i2c1-pins { ++ marvell,pins = "mpp26", "mpp27"; ++ marvell,function = "i2c1"; ++ }; ++ helios_sdhci_cd_pins: helios-sdhci-cd-pins { ++ marvell,pins = "mpp20"; ++ marvell,function = "gpio"; ++ }; ++ helios_sdhci_pins: helios-sdhci-pins { ++ marvell,pins = "mpp21", "mpp28", ++ "mpp37", "mpp38", ++ "mpp39", "mpp40"; ++ marvell,function = "sd0"; ++ }; ++ helios_led_pins: helios-led-pins { ++ marvell,pins = "mpp24", "mpp25", ++ "mpp49", "mpp50", ++ "mpp52", "mpp53", ++ "mpp54"; ++ marvell,function = "gpio"; ++ }; ++ helios_fan_pins: helios-fan-pins { ++ marvell,pins = "mpp41", "mpp43", ++ "mpp36", "mpp25"; ++ marvell,function = "gpio"; ++ }; ++ microsom_spi1_cs_pins: spi1-cs-pins { ++ marvell,pins = "mpp59"; ++ marvell,function = "spi1"; ++ }; ++ user_button_pins: user-button-pins { ++ marvell,pins = "mpp23"; ++ marvell,function = "gpio"; ++ }; ++ }; ++ }; ++ }; ++}; + +diff -u a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +--- a/arch/arm/boot/dts/Makefile 2017-10-19 03:51:29.758061000 +0800 ++++ b/arch/arm/boot/dts/Makefile 2017-10-19 05:58:52.613043929 +0800 +@@ -751,6 +751,7 @@ + armada-385-linksys-cobra.dtb \ + armada-388-clearfog-base.dtb \ + armada-388-clearfog-pro.dtb \ ++ armada-388-helios4.dtb \ + armada-388-db.dtb \ + armada-388-gp.dtb \ + armada-388-rd.dtb + +-- +2.7.4 + diff --git a/patch/u-boot/u-boot-helios4/add-fdtfile-env.patch b/patch/u-boot/u-boot-helios4/add-fdtfile-env.patch new file mode 100644 index 000000000..d8e3d0cd3 --- /dev/null +++ b/patch/u-boot/u-boot-helios4/add-fdtfile-env.patch @@ -0,0 +1,15 @@ +diff --git a/board/mv_ebu/a38x/mv_main_a38x.c b/board/mv_ebu/a38x/mv_main_a38x.c +index 4b43a9c..cf77da9 100755 +--- a/board/mv_ebu/a38x/mv_main_a38x.c ++++ b/board/mv_ebu/a38x/mv_main_a38x.c +@@ -331,6 +331,10 @@ void misc_init_r_env(void) + if (!env) + setenv("console", "console=ttyS0,115200"); + ++ env = getenv("fdtfile"); ++ if (!env) ++ setenv("fdtfile", "armada-388-helios4.dtb"); ++ + env = getenv("mtdids"); + if (!env) { + #if defined(MV_NAND) && defined(MV_INCLUDE_SPI) diff --git a/patch/u-boot/u-boot-helios4/add-mmc-target.patch b/patch/u-boot/u-boot-helios4/add-mmc-target.patch new file mode 100644 index 000000000..e2997955b --- /dev/null +++ b/patch/u-boot/u-boot-helios4/add-mmc-target.patch @@ -0,0 +1,53 @@ +diff --git a/Makefile b/Makefile +index 07debc4..3d91d1d 100755 +--- a/Makefile ++++ b/Makefile +@@ -477,6 +477,9 @@ ifndef CONFIG_SYS_UBOOT_START + CONFIG_SYS_UBOOT_START := 0 + endif + ++$(obj)u-boot.mmc: $(obj)u-boot.bin ++ echo y | $(obj)tools/marvell/doimage -T mmc -D 0x0 -E 0x0 -G $(obj)tools/marvell/bin_hdr/bin_hdr.bin u-boot.bin u-boot.mmc ++ + $(obj)u-boot.img: $(obj)u-boot.bin + $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \ + -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \ +diff --git a/boards.cfg b/boards.cfg +index 7e8d713..4d9f810 100644 +--- a/boards.cfg ++++ b/boards.cfg +@@ -55,7 +55,7 @@ armada_38x arm armv7 a38x mv_ebu + armada_38x_customer0 arm armv7 a38x mv_ebu mvca9 armada_38x:CUSTOMER_BOARD_0,ARMADA_38X + armada_38x_customer1 arm armv7 a38x mv_ebu mvca9 armada_38x:CUSTOMER_BOARD_1,ARMADA_38X + armada_38x_clearfog arm armv7 a38x mv_ebu mvca9 armada_38x:CLEARFOG_BOARD,ARMADA_38X +-armada_38x_helios4 arm armv7 a38x mv_ebu mvca9 armada_38x:HELIOS4_BOARD,ARMADA_38X ++armada_38x_helios4 arm armv7 a38x mv_ebu mvca9 armada_38x:HELIOS4_BOARD,ARMADA_38X,MV_MMC_BOOT,MV_INCLUDE_SPI,DDR3 + armada_39x arm armv7 a38x mv_ebu mvca9 armada_38x:ARMADA_39X + armada_39x_customer0 arm armv7 a38x mv_ebu mvca9 armada_38x:CUSTOMER_BOARD_0,ARMADA_39X + armada_39x_customer1 arm armv7 a38x mv_ebu mvca9 armada_38x:CUSTOMER_BOARD_1,ARMADA_39X +diff --git a/include/configs/armada_38x.h b/include/configs/armada_38x.h +index 1ae5256..23d681d 100644 +--- a/include/configs/armada_38x.h ++++ b/include/configs/armada_38x.h +@@ -286,6 +286,10 @@ extern unsigned int mvUartPortGet(void); + + /* SPI Flash configuration */ + /*****************************/ ++#if defined(CONFIG_MV_INCLUDE_SPI) ++ #define MV_INCLUDE_SPI ++#endif ++ + #if defined(MV_INCLUDE_SPI) + #define CONFIG_CMD_SPI + #define CONFIG_CMD_SF +@@ -563,6 +567,10 @@ extern int nand_get_env_offs(void); + /*****************************/ + //#define CONFIG_MMC_TRACE + /* Boot from MMC settings */ ++#if defined(CONFIG_MV_MMC_BOOT) ++ #define MV_MMC_BOOT ++#endif ++ + #if defined(MV_MMC_BOOT) + /* the following commands are supported only with SPI/NAND interfaces */ + #if (!defined(MV_INCLUDE_SPI) && !defined(MV_NAND)) diff --git a/patch/u-boot/u-boot-helios4/binary-header-toolchain-auto-select.patch b/patch/u-boot/u-boot-helios4/binary-header-toolchain-auto-select.patch new file mode 100644 index 000000000..755bc762e --- /dev/null +++ b/patch/u-boot/u-boot-helios4/binary-header-toolchain-auto-select.patch @@ -0,0 +1,17 @@ +diff --git a/tools/marvell/bin_hdr/base.mk b/tools/marvell/bin_hdr/base.mk +index 6e0078a..ad3011a 100755 +--- a/tools/marvell/bin_hdr/base.mk ++++ b/tools/marvell/bin_hdr/base.mk +@@ -183,7 +183,11 @@ ifeq "$(CONFIG_ALLEYCAT3)" "y" + CFLAGS += -DCONFIG_ALLEYCAT3 + endif + +-CROSS = $(CROSS_COMPILE_BH) ++ifneq "$(CROSS_COMPILE_BH)" "" ++ CROSS = $(CROSS_COMPILE_BH) ++else ++ CROSS = $(CROSS_COMPILE) ++endif + LD = $(CROSS)ld + CC = $(CROSS)gcc + AS = $(CROSS)as diff --git a/patch/u-boot/u-boot-helios4/disable-jffs-support.patch b/patch/u-boot/u-boot-helios4/disable-jffs-support.patch new file mode 100644 index 000000000..f0760ce8f --- /dev/null +++ b/patch/u-boot/u-boot-helios4/disable-jffs-support.patch @@ -0,0 +1,12 @@ +diff --git a/include/configs/armada_38x.h b/include/configs/armada_38x.h +index 75b8bf5..63475cd 100644 +--- a/include/configs/armada_38x.h ++++ b/include/configs/armada_38x.h +@@ -203,7 +204,6 @@ extern unsigned int mvUartPortGet(void); + #define CONFIG_FS_EXT4 + #define CONFIG_CMD_EXT4_WRITE + #define CONFIG_EXT4_WRITE +-#define CONFIG_CMD_JFFS2 + #define CONFIG_CMD_FAT + #define CONFIG_FS_FAT + #define CONFIG_SUPPORT_VFAT diff --git a/patch/u-boot/u-boot-helios4/loading-boot-scr.patch b/patch/u-boot/u-boot-helios4/loading-boot-scr.patch new file mode 100644 index 000000000..8092975ef --- /dev/null +++ b/patch/u-boot/u-boot-helios4/loading-boot-scr.patch @@ -0,0 +1,79 @@ +diff --git a/board/mv_ebu/a38x/mv_main_a38x.c b/board/mv_ebu/a38x/mv_main_a38x.c +index 0dce7f6..6d69879 100755 +--- a/board/mv_ebu/a38x/mv_main_a38x.c ++++ b/board/mv_ebu/a38x/mv_main_a38x.c +@@ -679,25 +679,33 @@ void misc_init_r_env(void) + setenv("enaLPAE", "no"); + #endif + +- /* Flatten Device Tree environment setup */ +-#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT +- #ifdef CONFIG_ARMADA_38X +- fdt_env_setup("armada-38x.dtb", MV_FALSE); /* static setup: Skip DT update for customer */ +- #else +- fdt_env_setup("armada-39x.dtb", MV_FALSE); +- #endif +-#else +- #ifdef CONFIG_ARMADA_38X +- fdt_env_setup("armada-38x-modular.dtb", MV_TRUE); /* dynamic setup: run DT update */ +- #else +- fdt_env_setup("armada-39x.dtb", MV_FALSE); /* static setup: Skip DT update */ +- #endif +-#endif ++ setenv("fdt_skip_update", "yes"); ++ setenv("boot_a_script", ++ "for prefix in /boot/ /; do \ ++ load ${boot_interface} 0:1 ${script_addr_r} ${prefix}boot.scr && \ ++ source ${script_addr_r}; \ ++ done"); ++ setenv("mmcboot", ++ "setenv boot_interface mmc; run boot_a_script;"); ++ setenv("sataboot", ++ "scsi init; setenv boot_interface scsi; run boot_a_script;"); ++ setenv("usbboot", ++ "setenv usbActive 1; setenv usbType 3; usb start; setenv boot_interface usb; run boot_a_script;"); + + #if (CONFIG_BOOTDELAY >= 0) + env = getenv("bootcmd"); + if (!env) +- setenv("bootcmd", "tftpboot 0x2000000 $image_name;tftpboot $fdtaddr $fdtfile;" ++ setenv("bootcmd", ++#if defined (MV_MMC_BOOT) ++ "echo Trying to boot from MMC; run mmcboot;" ++#elif defined (MV_SATA_BOOT) ++ "echo Trying to boot from SATA; run sataboot;" ++#elif defined (MV_NOR_BOOT) ++ "echo Please store the boot environment on the NOR SPI flash to override the default boot sequence;" ++#endif /* MV_NOR_BOOT */ ++ "echo Trying to boot from USB; run usbboot;" ++ "echo Default boot sequence failed - falling back to TFTP;" ++ "tftpboot 0x2000000 $image_name;tftpboot $fdtaddr $fdtfile;" + "setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath " + "ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params " + "clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel; bootz 0x2000000 - $fdtaddr;"); +diff --git a/common/cmd_fs.c b/common/cmd_fs.c +index a681d03..9cc5013 100644 +--- a/common/cmd_fs.c ++++ b/common/cmd_fs.c +@@ -22,7 +22,7 @@ + + int do_load_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) + { +- return do_load(cmdtp, flag, argc, argv, FS_TYPE_ANY, 0); ++ return do_load(cmdtp, flag, argc, argv, FS_TYPE_ANY, 16); + } + + U_BOOT_CMD( +diff --git a/include/configs/armada_38x.h b/include/configs/armada_38x.h +index 1ae5256..2086859 100644 +--- a/include/configs/armada_38x.h ++++ b/include/configs/armada_38x.h +@@ -164,7 +164,7 @@ extern unsigned int mvUartPortGet(void); + #define CONFIG_CMD_RCVR + #define CONFIG_CMD_BOOT_MENU + #define CONFIG_CMD_SYS_RESTORE +- ++#define CONFIG_CMD_FS_GENERIC + + /* Open this define for enabling Secure Boot Mode eFuses modification + #define CONFIG_CMD_EFUSE diff --git a/patch/u-boot/u-boot-helios4/make-build-more-silent.patch b/patch/u-boot/u-boot-helios4/make-build-more-silent.patch new file mode 100644 index 000000000..d8e91be65 --- /dev/null +++ b/patch/u-boot/u-boot-helios4/make-build-more-silent.patch @@ -0,0 +1,13 @@ +diff --git a/Makefile b/Makefile +index 9fd8afe..7591a9e 100755 +--- a/Makefile ++++ b/Makefile +@@ -64,6 +64,8 @@ else + XECHO = : + endif + ++MAKEFLAGS += --no-print-directory ++ + ######################################################################### + # + # U-boot build supports producing a object files to the separate external diff --git a/patch/u-boot/u-boot-helios4/tools-bin_hdr-compiler-fixes.patch b/patch/u-boot/u-boot-helios4/tools-bin_hdr-compiler-fixes.patch new file mode 100644 index 000000000..c5d1c0c81 --- /dev/null +++ b/patch/u-boot/u-boot-helios4/tools-bin_hdr-compiler-fixes.patch @@ -0,0 +1,31 @@ +diff --git a/tools/marvell/bin_hdr/base.mk b/tools/marvell/bin_hdr/base.mk +index 33ecf70..d1ee228 100755 +--- a/tools/marvell/bin_hdr/base.mk ++++ b/tools/marvell/bin_hdr/base.mk +@@ -208,7 +208,7 @@ CPUOPTS = -mthumb -mthumb-interwork -march=armv7 -mlittle-endian + BH_ROOT_DIR = $(TOPDIR)/tools/marvell/bin_hdr + INCLUDE = -I$(BH_ROOT_DIR)/src_ddr -I$(BH_ROOT_DIR)/src_phy/$(BOARD) -I$(BH_ROOT_DIR)/inc/common \ + -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(INCNAME) -I$(BH_ROOT_DIR)/inc/ddr3_soc/$(BOARD) -I$(BH_ROOT_DIR)/platform/sysEnv/$(BOARD) -I$(TOPDIR)/include -I$(BH_ROOT_DIR)/src_init/$(BOARD) +-HOSTCFLAGS = -Wall $(INCLUDE) ++HOSTCFLAGS = -fno-stack-protector -Wall $(INCLUDE) + + ifeq ($(BIN_HDR_DEBUG),1) + DEBUG_FLAGS += -g -O0 +@@ -223,7 +223,7 @@ DEBUG_MODE_FLAG = no + endif + endif + +-CFLAGS += -Wall $(INCLUDE) $(DEBUG_FLAGS) $(CPUOPTS) -msoft-float -mabi=aapcs ++CFLAGS += -fno-stack-protector -Wall $(INCLUDE) $(DEBUG_FLAGS) $(CPUOPTS) -msoft-float -mabi=aapcs + + ifeq ($(BOARD),msys_bc2) + CFLAGS += -fPIE -fno-zero-initialized-in-bss -fno-unwind-tables +@@ -231,7 +231,7 @@ else + CFLAGS += -fdata-sections -ffunction-sections + endif + +-EXTRA_LD_FLAGS = -Wl,--gc-sections --entry=_start ++EXTRA_LD_FLAGS = -fno-stack-protector -Wl,--gc-sections --entry=_start + + ifeq ($(DDRTYPE),ddr4) + CFLAGS += -DCONFIG_DDR4 From fcd0e5cb6cf1099707ebcdfc6be416a80dc7886d Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Thu, 2 Nov 2017 00:13:10 +0800 Subject: [PATCH 02/20] Pull parts of Helios4 support from #812 --- config/boards/{helios4.conf => helios4.wip} | 6 +- config/kernel/linux-mvebu-default.config | 14 +- config/sources/mvebu-u-boot-clearfog.inc | 15 + config/sources/mvebu-u-boot-helios4.inc | 15 + config/sources/mvebu.conf | 60 +- .../mvebu-default/03-patch-4.4.92-93.patch | 933 ++++++++++ .../mvebu-default/03-patch-4.4.93-94.patch | 1389 +++++++++++++++ .../mvebu-default/03-patch-4.4.94-95.patch | 1587 +++++++++++++++++ ...bu-Add-limited-PWM-support.patch.disabled} | 0 ...erties-to-.dtsi-armada-38x.patch.disabled} | 0 ...ch => 92-libata-add-ledtrig-support.patch} | 0 ...h => 93-Enable-ATA-port-LED-trigger.patch} | 0 ...ebu-Enable-SENSORS_PWM_FAN.patch.disabled} | 0 ...ree.patch => 95-helios4-device-tree.patch} | 0 ...dtb-file-for-backwards-compatibility.patch | 2 +- .../add-spi-flash.patch | 0 ...dtb-file-for-backwards-compatibility.patch | 29 - .../board_clearfogpro/add-spi-flash.patch | 34 - 18 files changed, 3975 insertions(+), 109 deletions(-) rename config/boards/{helios4.conf => helios4.wip} (77%) create mode 100644 config/sources/mvebu-u-boot-clearfog.inc create mode 100644 config/sources/mvebu-u-boot-helios4.inc create mode 100644 patch/kernel/mvebu-default/03-patch-4.4.92-93.patch create mode 100644 patch/kernel/mvebu-default/03-patch-4.4.93-94.patch create mode 100644 patch/kernel/mvebu-default/03-patch-4.4.94-95.patch rename patch/kernel/mvebu-default/{board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled => 90-gpio-mvebu-Add-limited-PWM-support.patch.disabled} (100%) rename patch/kernel/mvebu-default/{board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled => 91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled} (100%) rename patch/kernel/mvebu-default/{board_helios4/0004-libata-add-ledtrig-support.patch => 92-libata-add-ledtrig-support.patch} (100%) rename patch/kernel/mvebu-default/{board_helios4/0005-Enable-ATA-port-LED-trigger.patch => 93-Enable-ATA-port-LED-trigger.patch} (100%) rename patch/kernel/mvebu-default/{board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled => 94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled} (100%) rename patch/kernel/mvebu-default/{board_helios4/0006-helios4-device-tree.patch => 95-helios4-device-tree.patch} (100%) rename patch/kernel/mvebu-default/{board_clearfogbase => }/add-dtb-file-for-backwards-compatibility.patch (97%) rename patch/kernel/mvebu-default/{board_clearfogbase => }/add-spi-flash.patch (100%) delete mode 100644 patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch delete mode 100644 patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch diff --git a/config/boards/helios4.conf b/config/boards/helios4.wip similarity index 77% rename from config/boards/helios4.conf rename to config/boards/helios4.wip index 18eccb458..6a5c1c1ac 100644 --- a/config/boards/helios4.conf +++ b/config/boards/helios4.wip @@ -6,14 +6,14 @@ MODULES="mv_cesa" BUILD_DESKTOP="no" # KERNEL_TARGET="default" -CLI_TARGET="jessie:default" +CLI_TARGET="" CLI_BETA_TARGET="" # -RECOMMENDED="Debian_jessie_default:90" +RECOMMENDED="" # BOARDRATING="" CHIP="https://kobol.io/helios4" REVIEW="" HARDWARE="https://wiki.kobol.io" -FORUMS="" +FORUMS="https://forum.armbian.com/forum/11-other-boards/" diff --git a/config/kernel/linux-mvebu-default.config b/config/kernel/linux-mvebu-default.config index e2b64a7e8..502006082 100644 --- a/config/kernel/linux-mvebu-default.config +++ b/config/kernel/linux-mvebu-default.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.4.91 Kernel Configuration +# Linux/arm 4.4.95 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -3028,7 +3028,6 @@ CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set -CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHTC1 is not set @@ -3277,7 +3276,6 @@ CONFIG_REGULATOR_GPIO=m # CONFIG_REGULATOR_MAX8973 is not set # CONFIG_REGULATOR_MT6311 is not set # CONFIG_REGULATOR_PFUZE100 is not set -CONFIG_REGULATOR_PWM=m # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set @@ -3375,14 +3373,11 @@ CONFIG_LCD_LMS501KF03=m CONFIG_LCD_HX8357=m CONFIG_BACKLIGHT_CLASS_DEVICE=m CONFIG_BACKLIGHT_GENERIC=m -CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_PM8941_WLED=m CONFIG_BACKLIGHT_ADP8860=m CONFIG_BACKLIGHT_ADP8870=m CONFIG_BACKLIGHT_88PM860X=m -# CONFIG_BACKLIGHT_LM3630A is not set CONFIG_BACKLIGHT_LM3639=m -# CONFIG_BACKLIGHT_LP855X is not set CONFIG_BACKLIGHT_GPIO=m CONFIG_BACKLIGHT_LV5207LP=m CONFIG_BACKLIGHT_BD6107=m @@ -3854,7 +3849,6 @@ CONFIG_LEDS_GPIO=m # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set # CONFIG_LEDS_DAC124S085 is not set -CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set @@ -4226,7 +4220,6 @@ CONFIG_COMMON_CLK_SCPI=m # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_CLK_QORIQ is not set -CONFIG_COMMON_CLK_PWM=y # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set CONFIG_MVEBU_CLK_COMMON=y @@ -4535,10 +4528,7 @@ CONFIG_IIO_SYSFS_TRIGGER=m # CONFIG_TSYS02D is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_PCA9685 is not set +# CONFIG_PWM is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARMADA_370_XP_IRQ=y diff --git a/config/sources/mvebu-u-boot-clearfog.inc b/config/sources/mvebu-u-boot-clearfog.inc new file mode 100644 index 000000000..137e5b866 --- /dev/null +++ b/config/sources/mvebu-u-boot-clearfog.inc @@ -0,0 +1,15 @@ +case $BRANCH in + default|next) + BOOTSOURCE='https://github.com/SolidRun/u-boot-armada38x' + BOOTBRANCH='branch:u-boot-2013.01-15t1-clearfog' + BOOTDIR='u-boot-armada' + BOOTSCRIPT='boot-marvell.cmd:boot.cmd' + + UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc u-boot-uart.mmc + u-boot.sata;sata;u-boot.sata u-boot-uart.sata + u-boot.flash;spi;u-boot.flash u-boot-uart.flash" + + UBOOT_USE_GCC='== 4.9' + UBOOT_COMPILER='arm-linux-gnueabi-' + ;; +esac diff --git a/config/sources/mvebu-u-boot-helios4.inc b/config/sources/mvebu-u-boot-helios4.inc new file mode 100644 index 000000000..cdf276ede --- /dev/null +++ b/config/sources/mvebu-u-boot-helios4.inc @@ -0,0 +1,15 @@ +case $BRANCH in + default|next) + BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git' + BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4' + BOOTDIR='u-boot-armada' + BOOTSCRIPT='boot-marvell.cmd:boot.cmd' + + UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc" + + UBOOT_USE_GCC='== 4.9' + UBOOT_COMPILER='arm-linux-gnueabi-' + + BOOTPATCHDIR='u-boot-helios4' + ;; +esac diff --git a/config/sources/mvebu.conf b/config/sources/mvebu.conf index 8d74df18b..eb6e59623 100644 --- a/config/sources/mvebu.conf +++ b/config/sources/mvebu.conf @@ -1,40 +1,20 @@ -case $BOARD in - helios4) - BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git' - BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4' - BOOTDIR='u-boot-helios4' - BOOTPATCHDIR='u-boot-helios4' - BOOTSCRIPT='boot-helios4.cmd:boot.cmd' - - UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc" - - BOOTENV_FILE='helios4-default.txt' - ;; - - *) - BOOTSOURCE='https://github.com/SolidRun/u-boot-armada38x' - BOOTBRANCH='branch:u-boot-2013.01-15t1-clearfog' - BOOTDIR='u-boot-armada' - BOOTSCRIPT='boot-marvell.cmd:boot.cmd' - - UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc u-boot-uart.mmc - u-boot.sata;sata;u-boot.sata u-boot-uart.sata - u-boot.flash;spi;u-boot.flash u-boot-uart.flash" - - BOOTENV_FILE='clearfog-default.txt' - ;; -esac - - -UBOOT_USE_GCC='< 5.0' -UBOOT_COMPILER='arm-linux-gnueabi-' HAS_UUID_SUPPORT=yes +if [[ $BOARD == helios4 ]]; then + source "${BASH_SOURCE%/*}/mvebu-u-boot-helios4.inc" + BOOTENV_FILE='helios4-default.txt' +else + source "${BASH_SOURCE%/*}/mvebu-u-boot-clearfog.inc" + BOOTENV_FILE='clearfog-default.txt' +fi + case $BRANCH in default) KERNELSOURCE='https://github.com/moonman/linux-stable' KERNELBRANCH='branch:linux-4.4.y-marvell' KERNELDIR='linux-armada-lts' + + KERNEL_USE_GCC='> 5.0' ;; next) @@ -44,6 +24,26 @@ case $BRANCH in KERNEL_USE_GCC='> 7.0' ;; + + dev) + BOOTSOURCE=$MAINLINE_UBOOT_SOURCE + BOOTBRANCH=$MAINLINE_UBOOT_BRANCH + BOOTDIR=$MAINLINE_UBOOT_DIR + BOOTPATCHDIR='u-boot-mvebu-next' + BOOTSCRIPT='boot-mvebu-next.cmd:boot.cmd' + + UBOOT_TARGET_MAP=";;u-boot-spl.kwb:u-boot.mmc" + UBOOT_USE_GCC='> 7.0' + + OVERLAY_PREFIX='armada-388' + + KERNELSOURCE=$MAINLINE_KERNEL_SOURCE + KERNELBRANCH='branch:linux-4.13.y' + KERNELDIR=$MAINLINE_KERNEL_DIR + LINUXCONFIG='linux-mvebu-next' + + KERNEL_USE_GCC='> 7.0' + ;; esac CPUMIN=800000 diff --git a/patch/kernel/mvebu-default/03-patch-4.4.92-93.patch b/patch/kernel/mvebu-default/03-patch-4.4.92-93.patch new file mode 100644 index 000000000..08ef2569a --- /dev/null +++ b/patch/kernel/mvebu-default/03-patch-4.4.92-93.patch @@ -0,0 +1,933 @@ +diff --git a/Makefile b/Makefile +index fab2d640a27e..77a17fb24b6d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 92 ++SUBLEVEL = 93 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c +index 6da2e4a6ba39..dd058aa8a3b5 100644 +--- a/arch/mips/math-emu/cp1emu.c ++++ b/arch/mips/math-emu/cp1emu.c +@@ -2360,7 +2360,6 @@ dcopuop: + break; + default: + /* Reserved R6 ops */ +- pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); + return SIGILL; + } + } +@@ -2434,7 +2433,6 @@ dcopuop: + break; + default: + /* Reserved R6 ops */ +- pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); + return SIGILL; + } + } +diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h +index e7636bac7372..6c98821fef5e 100644 +--- a/arch/x86/include/asm/alternative-asm.h ++++ b/arch/x86/include/asm/alternative-asm.h +@@ -62,8 +62,10 @@ + #define new_len2 145f-144f + + /* +- * max without conditionals. Idea adapted from: ++ * gas compatible max based on the idea from: + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax ++ * ++ * The additional "-" is needed because gas uses a "true" value of -1. + */ + #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) + +diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h +index 7bfc85bbb8ff..09936e9c8154 100644 +--- a/arch/x86/include/asm/alternative.h ++++ b/arch/x86/include/asm/alternative.h +@@ -102,12 +102,12 @@ static inline int alternatives_text_reserved(void *start, void *end) + alt_end_marker ":\n" + + /* +- * max without conditionals. Idea adapted from: ++ * gas compatible max based on the idea from: + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax + * +- * The additional "-" is needed because gas works with s32s. ++ * The additional "-" is needed because gas uses a "true" value of -1. + */ +-#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))" ++#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))" + + /* + * Pad the second replacement alternative with additional NOPs if it is +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index a018dff00808..9114588e3e61 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -10369,7 +10369,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, + * (KVM doesn't change it)- no reason to call set_cr4_guest_host_mask(); + */ + vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK); +- kvm_set_cr4(vcpu, vmcs12->host_cr4); ++ vmx_set_cr4(vcpu, vmcs12->host_cr4); + + nested_ept_uninit_mmu_context(vcpu); + +diff --git a/block/bio.c b/block/bio.c +index 14263fab94d3..68bbc835bacc 100644 +--- a/block/bio.c ++++ b/block/bio.c +@@ -1320,6 +1320,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, + offset = uaddr & ~PAGE_MASK; + for (j = cur_page; j < page_limit; j++) { + unsigned int bytes = PAGE_SIZE - offset; ++ unsigned short prev_bi_vcnt = bio->bi_vcnt; + + if (len <= 0) + break; +@@ -1334,6 +1335,13 @@ struct bio *bio_map_user_iov(struct request_queue *q, + bytes) + break; + ++ /* ++ * check if vector was merged with previous ++ * drop page reference if needed ++ */ ++ if (bio->bi_vcnt == prev_bi_vcnt) ++ put_page(pages[j]); ++ + len -= bytes; + offset = 0; + } +diff --git a/crypto/shash.c b/crypto/shash.c +index 359754591653..b2cd109d9171 100644 +--- a/crypto/shash.c ++++ b/crypto/shash.c +@@ -274,12 +274,14 @@ static int shash_async_finup(struct ahash_request *req) + + int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) + { +- struct scatterlist *sg = req->src; +- unsigned int offset = sg->offset; + unsigned int nbytes = req->nbytes; ++ struct scatterlist *sg; ++ unsigned int offset; + int err; + +- if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { ++ if (nbytes && ++ (sg = req->src, offset = sg->offset, ++ nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) { + void *data; + + data = kmap_atomic(sg_page(sg)); +diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c +index 16fe773fb846..85674a8d0436 100644 +--- a/drivers/dma/edma.c ++++ b/drivers/dma/edma.c +@@ -1126,11 +1126,24 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + struct edma_desc *edesc; + struct device *dev = chan->device->dev; + struct edma_chan *echan = to_edma_chan(chan); +- unsigned int width, pset_len; ++ unsigned int width, pset_len, array_size; + + if (unlikely(!echan || !len)) + return NULL; + ++ /* Align the array size (acnt block) with the transfer properties */ ++ switch (__ffs((src | dest | len))) { ++ case 0: ++ array_size = SZ_32K - 1; ++ break; ++ case 1: ++ array_size = SZ_32K - 2; ++ break; ++ default: ++ array_size = SZ_32K - 4; ++ break; ++ } ++ + if (len < SZ_64K) { + /* + * Transfer size less than 64K can be handled with one paRAM +@@ -1152,7 +1165,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + * When the full_length is multibple of 32767 one slot can be + * used to complete the transfer. + */ +- width = SZ_32K - 1; ++ width = array_size; + pset_len = rounddown(len, width); + /* One slot is enough for lengths multiple of (SZ_32K -1) */ + if (unlikely(pset_len == len)) +@@ -1202,7 +1215,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( + } + dest += pset_len; + src += pset_len; +- pset_len = width = len % (SZ_32K - 1); ++ pset_len = width = len % array_size; + + ret = edma_config_pset(chan, &edesc->pset[1], src, dest, 1, + width, pset_len, DMA_MEM_TO_MEM); +diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c +index 0df32fe0e345..b0eeb5090c91 100644 +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -971,6 +971,8 @@ static int usbhid_parse(struct hid_device *hid) + unsigned int rsize = 0; + char *rdesc; + int ret, n; ++ int num_descriptors; ++ size_t offset = offsetof(struct hid_descriptor, desc); + + quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); +@@ -993,10 +995,18 @@ static int usbhid_parse(struct hid_device *hid) + return -ENODEV; + } + ++ if (hdesc->bLength < sizeof(struct hid_descriptor)) { ++ dbg_hid("hid descriptor is too short\n"); ++ return -EINVAL; ++ } ++ + hid->version = le16_to_cpu(hdesc->bcdHID); + hid->country = hdesc->bCountryCode; + +- for (n = 0; n < hdesc->bNumDescriptors; n++) ++ num_descriptors = min_t(int, hdesc->bNumDescriptors, ++ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor)); ++ ++ for (n = 0; n < num_descriptors; n++) + if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) + rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index a0ef57483ebb..52c36394dba5 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -3096,6 +3096,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, + mutex_unlock(&domain->api_lock); + + domain_flush_tlb_pde(domain); ++ domain_flush_complete(domain); + + return unmap_size; + } +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +index f18491cf793c..5fecae0ba52e 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -2903,6 +2903,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + s32 status; + struct brcmf_escan_result_le *escan_result_le; ++ u32 escan_buflen; + struct brcmf_bss_info_le *bss_info_le; + struct brcmf_bss_info_le *bss = NULL; + u32 bi_length; +@@ -2919,11 +2920,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); ++ if (e->datalen < sizeof(*escan_result_le)) { ++ brcmf_err("invalid event data length\n"); ++ goto exit; ++ } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { + brcmf_err("Invalid escan result (NULL pointer)\n"); + goto exit; + } ++ escan_buflen = le32_to_cpu(escan_result_le->buflen); ++ if (escan_buflen > WL_ESCAN_BUF_SIZE || ++ escan_buflen > e->datalen || ++ escan_buflen < sizeof(*escan_result_le)) { ++ brcmf_err("Invalid escan buffer length: %d\n", ++ escan_buflen); ++ goto exit; ++ } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { + brcmf_err("Invalid bss_count %d: ignoring\n", + escan_result_le->bss_count); +@@ -2940,9 +2953,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + } + + bi_length = le32_to_cpu(bss_info_le->length); +- if (bi_length != (le32_to_cpu(escan_result_le->buflen) - +- WL_ESCAN_RESULTS_FIXED_SIZE)) { +- brcmf_err("Invalid bss_info length %d: ignoring\n", ++ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { ++ brcmf_err("Ignoring invalid bss_info length: %d\n", + bi_length); + goto exit; + } +diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c +index 1a8ea775de08..984cd2f05c4a 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c +@@ -1906,6 +1906,11 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, + struct iwl_mvm_mc_iter_data *data = _data; + struct iwl_mvm *mvm = data->mvm; + struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd; ++ struct iwl_host_cmd hcmd = { ++ .id = MCAST_FILTER_CMD, ++ .flags = CMD_ASYNC, ++ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, ++ }; + int ret, len; + + /* if we don't have free ports, mcast frames will be dropped */ +@@ -1920,7 +1925,10 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, + memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); + len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); + +- ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd); ++ hcmd.len[0] = len; ++ hcmd.data[0] = cmd; ++ ++ ret = iwl_mvm_send_cmd(mvm, &hcmd); + if (ret) + IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); + } +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index e2641d4dfdd6..d186d0282a38 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -1905,6 +1905,8 @@ static DEVICE_ATTR_RO(suspended); + static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) + { + struct usb_composite_dev *cdev = get_gadget_data(gadget); ++ struct usb_gadget_strings *gstr = cdev->driver->strings[0]; ++ struct usb_string *dev_str = gstr->strings; + + /* composite_disconnect() must already have been called + * by the underlying peripheral controller driver! +@@ -1924,6 +1926,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) + + composite_dev_cleanup(cdev); + ++ if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) ++ dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; ++ + kfree(cdev->def_manufacturer); + kfree(cdev); + set_gadget_data(gadget, NULL); +diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c +index db645c38055d..8080a11947b7 100644 +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -420,6 +420,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) + static void set_link_state(struct dummy_hcd *dum_hcd) + { + struct dummy *dum = dum_hcd->dum; ++ unsigned int power_bit; + + dum_hcd->active = 0; + if (dum->pullup) +@@ -430,17 +431,19 @@ static void set_link_state(struct dummy_hcd *dum_hcd) + return; + + set_link_state_by_speed(dum_hcd); ++ power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? ++ USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); + + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || + dum_hcd->active) + dum_hcd->resuming = 0; + + /* Currently !connected or in reset */ +- if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || ++ if ((dum_hcd->port_status & power_bit) == 0 || + (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { +- unsigned disconnect = USB_PORT_STAT_CONNECTION & ++ unsigned int disconnect = power_bit & + dum_hcd->old_status & (~dum_hcd->port_status); +- unsigned reset = USB_PORT_STAT_RESET & ++ unsigned int reset = USB_PORT_STAT_RESET & + (~dum_hcd->old_status) & dum_hcd->port_status; + + /* Report reset and disconnect events to the driver */ +diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c +index d95cd1a72b66..8bb9367ada45 100644 +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -858,9 +858,9 @@ static void xfer_work(struct work_struct *work) + fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); + + usbhs_pipe_running(pipe, 1); +- usbhsf_dma_start(pipe, fifo); + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); + dma_async_issue_pending(chan); ++ usbhsf_dma_start(pipe, fifo); + usbhs_pipe_enable(pipe); + + xfer_work_end: +diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c +index 3806e7014199..2938153fe7b1 100644 +--- a/drivers/usb/serial/console.c ++++ b/drivers/usb/serial/console.c +@@ -189,6 +189,7 @@ static int usb_console_setup(struct console *co, char *options) + tty_kref_put(tty); + reset_open_count: + port->port.count = 0; ++ info->port = NULL; + usb_autopm_put_interface(serial->interface); + error_get_interface: + usb_serial_put(serial); +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 41a6513646de..1f5ecf905b7d 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -170,6 +170,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ ++ { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ + { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ + { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ + { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index e0385d6c0abb..30344efc123f 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, + { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, ++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, ++ { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, + { } /* Terminating entry */ + }; + +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 4fcf1cecb6d7..f9d15bd62785 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -609,6 +609,13 @@ + #define ADI_GNICE_PID 0xF000 + #define ADI_GNICEPLUS_PID 0xF001 + ++/* ++ * Cypress WICED USB UART ++ */ ++#define CYPRESS_VID 0x04B4 ++#define CYPRESS_WICED_BT_USB_PID 0x009B ++#define CYPRESS_WICED_WL_USB_PID 0xF900 ++ + /* + * Microchip Technology, Inc. + * +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 2a9944326210..db3d34c2c82e 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); + + /* TP-LINK Incorporated products */ + #define TPLINK_VENDOR_ID 0x2357 ++#define TPLINK_PRODUCT_LTE 0x000D + #define TPLINK_PRODUCT_MA180 0x0201 + + /* Changhong products */ +@@ -2011,6 +2012,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ +diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c +index 652b4334b26d..e1c1e329c877 100644 +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { + {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ + {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ ++ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ ++ {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ ++ {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ ++ {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ + + /* Huawei devices */ + {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index e2f6a79e9b01..8225de3c9743 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -351,6 +351,8 @@ struct smb_version_operations { + unsigned int (*calc_smb_size)(void *); + /* check for STATUS_PENDING and process it in a positive case */ + bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); ++ /* check for STATUS_NETWORK_SESSION_EXPIRED */ ++ bool (*is_session_expired)(char *); + /* send oplock break response */ + int (*oplock_response)(struct cifs_tcon *, struct cifs_fid *, + struct cifsInodeInfo *); +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index b60150e5b5ce..0c92af11f4f4 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1460,6 +1460,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + return length; + server->total_read += length; + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, 0)) { + discard_remaining_data(server); +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index b377aa8f266f..0a2bf9462637 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -850,6 +850,13 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) + cifs_dump_mem("Bad SMB: ", buf, + min_t(unsigned int, server->total_read, 48)); + ++ if (server->ops->is_session_expired && ++ server->ops->is_session_expired(buf)) { ++ cifs_reconnect(server); ++ wake_up(&server->response_q); ++ return -1; ++ } ++ + if (server->ops->is_status_pending && + server->ops->is_status_pending(buf, server, length)) + return -1; +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 1d125d3d0d89..e6b1795fbf2a 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -963,6 +963,18 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length) + return true; + } + ++static bool ++smb2_is_session_expired(char *buf) ++{ ++ struct smb2_hdr *hdr = (struct smb2_hdr *)buf; ++ ++ if (hdr->Status != STATUS_NETWORK_SESSION_EXPIRED) ++ return false; ++ ++ cifs_dbg(FYI, "Session expired\n"); ++ return true; ++} ++ + static int + smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid, + struct cifsInodeInfo *cinode) +@@ -1552,6 +1564,7 @@ struct smb_version_operations smb20_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1633,6 +1646,7 @@ struct smb_version_operations smb21_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1715,6 +1729,7 @@ struct smb_version_operations smb30_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +@@ -1803,6 +1818,7 @@ struct smb_version_operations smb311_operations = { + .close_dir = smb2_close_dir, + .calc_smb_size = smb2_calc_size, + .is_status_pending = smb2_is_status_pending, ++ .is_session_expired = smb2_is_session_expired, + .oplock_response = smb2_oplock_response, + .queryfs = smb2_queryfs, + .mand_lock = smb2_mand_lock, +diff --git a/fs/direct-io.c b/fs/direct-io.c +index c772fdf36cd9..44f49d86d714 100644 +--- a/fs/direct-io.c ++++ b/fs/direct-io.c +@@ -823,7 +823,8 @@ out: + */ + if (sdio->boundary) { + ret = dio_send_cur_page(dio, sdio, map_bh); +- dio_bio_submit(dio, sdio); ++ if (sdio->bio) ++ dio_bio_submit(dio, sdio); + page_cache_release(sdio->cur_page); + sdio->cur_page = NULL; + } +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index 45ef9975caec..a8b1749d79a8 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -559,7 +559,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) + mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + mutex_unlock(&inode->i_mutex); + return -ENXIO; + } +@@ -632,7 +632,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) + mutex_lock(&inode->i_mutex); + + isize = i_size_read(inode); +- if (offset >= isize) { ++ if (offset < 0 || offset >= isize) { + mutex_unlock(&inode->i_mutex); + return -ENXIO; + } +diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h +index a03acd0d398a..695257ae64ac 100644 +--- a/include/sound/seq_virmidi.h ++++ b/include/sound/seq_virmidi.h +@@ -60,6 +60,7 @@ struct snd_virmidi_dev { + int port; /* created/attached port */ + unsigned int flags; /* SNDRV_VIRMIDI_* */ + rwlock_t filelist_lock; ++ struct rw_semaphore filelist_sem; + struct list_head filelist; + }; + +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index f07343b54fe5..8a62cbfe1f2f 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -759,6 +759,12 @@ void rcu_irq_exit(void) + + local_irq_save(flags); + rdtp = this_cpu_ptr(&rcu_dynticks); ++ ++ /* Page faults can happen in NMI handlers, so check... */ ++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) ++ return; ++ ++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_exit() invoked with irqs enabled!!!"); + oldval = rdtp->dynticks_nesting; + rdtp->dynticks_nesting--; + WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && +@@ -887,6 +893,12 @@ void rcu_irq_enter(void) + + local_irq_save(flags); + rdtp = this_cpu_ptr(&rcu_dynticks); ++ ++ /* Page faults can happen in NMI handlers, so check... */ ++ if (READ_ONCE(rdtp->dynticks_nmi_nesting)) ++ return; ++ ++ RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_irq_enter() invoked with irqs enabled!!!"); + oldval = rdtp->dynticks_nesting; + rdtp->dynticks_nesting++; + WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 8ece212aa3d2..7950506395a8 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -485,6 +485,14 @@ nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = { + [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 }, + }; + ++/* policy for packet pattern attributes */ ++static const struct nla_policy ++nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { ++ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, ++ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, ++}; ++ + static int nl80211_prepare_wdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, +@@ -9410,7 +9418,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + err = -EINVAL; + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) +@@ -9660,7 +9668,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, + u8 *mask_pat; + + nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat), +- nla_len(pat), NULL); ++ nla_len(pat), nl80211_packet_pattern_policy); + if (!pat_tb[NL80211_PKTPAT_MASK] || + !pat_tb[NL80211_PKTPAT_PATTERN]) + return -EINVAL; +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index e326c1d80416..e847b9923c19 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1260,6 +1260,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, + struct snd_seq_client_port *port; + struct snd_seq_port_info info; + struct snd_seq_port_callback *callback; ++ int port_idx; + + if (copy_from_user(&info, arg, sizeof(info))) + return -EFAULT; +@@ -1273,7 +1274,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, + return -ENOMEM; + + if (client->type == USER_CLIENT && info.kernel) { +- snd_seq_delete_port(client, port->addr.port); ++ port_idx = port->addr.port; ++ snd_seq_port_unlock(port); ++ snd_seq_delete_port(client, port_idx); + return -EINVAL; + } + if (client->type == KERNEL_CLIENT) { +@@ -1294,6 +1297,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, + + snd_seq_set_port_info(port, &info); + snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); ++ snd_seq_port_unlock(port); + + if (copy_to_user(arg, &info, sizeof(info))) + return -EFAULT; +diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c +index fe686ee41c6d..f04714d70bf7 100644 +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) + } + + +-/* create a port, port number is returned (-1 on failure) */ ++/* create a port, port number is returned (-1 on failure); ++ * the caller needs to unref the port via snd_seq_port_unlock() appropriately ++ */ + struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + int port) + { +@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + snd_use_lock_init(&new_port->use_lock); + port_subs_info_init(&new_port->c_src); + port_subs_info_init(&new_port->c_dest); ++ snd_use_lock_use(&new_port->use_lock); + + num = port >= 0 ? port : 0; + mutex_lock(&client->ports_mutex); +@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, + list_add_tail(&new_port->list, &p->list); + client->num_ports++; + new_port->addr.port = num; /* store the port number in the port */ ++ sprintf(new_port->name, "port-%d", num); + write_unlock_irqrestore(&client->ports_lock, flags); + mutex_unlock(&client->ports_mutex); +- sprintf(new_port->name, "port-%d", num); + + return new_port; + } +diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c +index 81134e067184..3b126af4a026 100644 +--- a/sound/core/seq/seq_virmidi.c ++++ b/sound/core/seq/seq_virmidi.c +@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, + * decode input event and put to read buffer of each opened file + */ + static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, +- struct snd_seq_event *ev) ++ struct snd_seq_event *ev, ++ bool atomic) + { + struct snd_virmidi *vmidi; + unsigned char msg[4]; + int len; + +- read_lock(&rdev->filelist_lock); ++ if (atomic) ++ read_lock(&rdev->filelist_lock); ++ else ++ down_read(&rdev->filelist_sem); + list_for_each_entry(vmidi, &rdev->filelist, list) { + if (!vmidi->trigger) + continue; +@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, + snd_rawmidi_receive(vmidi->substream, msg, len); + } + } +- read_unlock(&rdev->filelist_lock); ++ if (atomic) ++ read_unlock(&rdev->filelist_lock); ++ else ++ up_read(&rdev->filelist_sem); + + return 0; + } +@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev) + struct snd_virmidi_dev *rdev; + + rdev = rmidi->private_data; +- return snd_virmidi_dev_receive_event(rdev, ev); ++ return snd_virmidi_dev_receive_event(rdev, ev, true); + } + #endif /* 0 */ + +@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, + rdev = private_data; + if (!(rdev->flags & SNDRV_VIRMIDI_USE)) + return 0; /* ignored */ +- return snd_virmidi_dev_receive_event(rdev, ev); ++ return snd_virmidi_dev_receive_event(rdev, ev, atomic); + } + + /* +@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) + struct snd_virmidi_dev *rdev = substream->rmidi->private_data; + struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_virmidi *vmidi; +- unsigned long flags; + + vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); + if (vmidi == NULL) +@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) + vmidi->client = rdev->client; + vmidi->port = rdev->port; + runtime->private_data = vmidi; +- write_lock_irqsave(&rdev->filelist_lock, flags); ++ down_write(&rdev->filelist_sem); ++ write_lock_irq(&rdev->filelist_lock); + list_add_tail(&vmidi->list, &rdev->filelist); +- write_unlock_irqrestore(&rdev->filelist_lock, flags); ++ write_unlock_irq(&rdev->filelist_lock); ++ up_write(&rdev->filelist_sem); + vmidi->rdev = rdev; + return 0; + } +@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) + struct snd_virmidi_dev *rdev = substream->rmidi->private_data; + struct snd_virmidi *vmidi = substream->runtime->private_data; + ++ down_write(&rdev->filelist_sem); + write_lock_irq(&rdev->filelist_lock); + list_del(&vmidi->list); + write_unlock_irq(&rdev->filelist_lock); ++ up_write(&rdev->filelist_sem); + snd_midi_event_free(vmidi->parser); + substream->runtime->private_data = NULL; + kfree(vmidi); +@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi + rdev->rmidi = rmidi; + rdev->device = device; + rdev->client = -1; ++ init_rwsem(&rdev->filelist_sem); + rwlock_init(&rdev->filelist_lock); + INIT_LIST_HEAD(&rdev->filelist); + rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; +diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c +index b871ba407e4e..4458190149d1 100644 +--- a/sound/usb/caiaq/device.c ++++ b/sound/usb/caiaq/device.c +@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev) + + err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); + if (err) +- return err; ++ goto err_kill_urb; + +- if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) +- return -ENODEV; ++ if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) { ++ err = -ENODEV; ++ goto err_kill_urb; ++ } + + usb_string(usb_dev, usb_dev->descriptor.iManufacturer, + cdev->vendor_name, CAIAQ_USB_STR_LEN); +@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev) + + setup_card(cdev); + return 0; ++ ++ err_kill_urb: ++ usb_kill_urb(&cdev->ep1_in_urb); ++ return err; + } + + static int snd_probe(struct usb_interface *intf, +diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c +index 183311cb849e..be78078a10ba 100644 +--- a/sound/usb/line6/driver.c ++++ b/sound/usb/line6/driver.c +@@ -586,9 +586,10 @@ int line6_probe(struct usb_interface *interface, + return 0; + + error: +- if (line6->disconnect) +- line6->disconnect(line6); +- snd_card_free(card); ++ /* we can call disconnect callback here because no close-sync is ++ * needed yet at this point ++ */ ++ line6_disconnect(interface); + return ret; + } + EXPORT_SYMBOL_GPL(line6_probe); +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 696de5ac69be..a23efc8671d6 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -2161,6 +2161,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) + + static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) + { ++ /* kill pending URBs */ ++ snd_usb_mixer_disconnect(mixer); ++ + kfree(mixer->id_elems); + if (mixer->urb) { + kfree(mixer->urb->transfer_buffer); +@@ -2504,8 +2507,13 @@ _error: + + void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) + { +- usb_kill_urb(mixer->urb); +- usb_kill_urb(mixer->rc_urb); ++ if (mixer->disconnected) ++ return; ++ if (mixer->urb) ++ usb_kill_urb(mixer->urb); ++ if (mixer->rc_urb) ++ usb_kill_urb(mixer->rc_urb); ++ mixer->disconnected = true; + } + + #ifdef CONFIG_PM +diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h +index 2b4b067646ab..545d99b09706 100644 +--- a/sound/usb/mixer.h ++++ b/sound/usb/mixer.h +@@ -22,6 +22,8 @@ struct usb_mixer_interface { + struct urb *rc_urb; + struct usb_ctrlrequest *rc_setup_packet; + u8 rc_buffer[6]; ++ ++ bool disconnected; + }; + + #define MAX_CHANNELS 16 /* max logical channels */ diff --git a/patch/kernel/mvebu-default/03-patch-4.4.93-94.patch b/patch/kernel/mvebu-default/03-patch-4.4.93-94.patch new file mode 100644 index 000000000..4a0013b84 --- /dev/null +++ b/patch/kernel/mvebu-default/03-patch-4.4.93-94.patch @@ -0,0 +1,1389 @@ +diff --git a/Makefile b/Makefile +index 77a17fb24b6d..ff9d6bbf2210 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 93 ++SUBLEVEL = 94 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h +index 77edb22f855d..5433ccc9d706 100644 +--- a/arch/mips/include/asm/irq.h ++++ b/arch/mips/include/asm/irq.h +@@ -18,7 +18,7 @@ + #include + + #define IRQ_STACK_SIZE THREAD_SIZE +-#define IRQ_STACK_START (IRQ_STACK_SIZE - sizeof(unsigned long)) ++#define IRQ_STACK_START (IRQ_STACK_SIZE - 16) + + extern void *irq_stack[NR_CPUS]; + +diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h +index be0cc1beed41..3fae200dd251 100644 +--- a/arch/sparc/include/asm/setup.h ++++ b/arch/sparc/include/asm/setup.h +@@ -59,8 +59,11 @@ extern atomic_t dcpage_flushes; + extern atomic_t dcpage_flushes_xcall; + + extern int sysctl_tsb_ratio; +-#endif + ++#ifdef CONFIG_SERIAL_SUNHV ++void sunhv_migrate_hvcons_irq(int cpu); ++#endif ++#endif + void sun_do_break(void); + extern int stop_a_enabled; + extern int scons_pwroff; +diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c +index 4511caa3b7e9..46866b2097e8 100644 +--- a/arch/sparc/kernel/smp_64.c ++++ b/arch/sparc/kernel/smp_64.c +@@ -1443,8 +1443,12 @@ void smp_send_stop(void) + int cpu; + + if (tlb_type == hypervisor) { ++ int this_cpu = smp_processor_id(); ++#ifdef CONFIG_SERIAL_SUNHV ++ sunhv_migrate_hvcons_irq(this_cpu); ++#endif + for_each_online_cpu(cpu) { +- if (cpu == smp_processor_id()) ++ if (cpu == this_cpu) + continue; + #ifdef CONFIG_SUN_LDOMS + if (ldom_domaining_enabled) { +diff --git a/block/bsg-lib.c b/block/bsg-lib.c +index 341b8d858e67..650f427d915b 100644 +--- a/block/bsg-lib.c ++++ b/block/bsg-lib.c +@@ -147,6 +147,7 @@ static int bsg_create_job(struct device *dev, struct request *req) + failjob_rls_rqst_payload: + kfree(job->request_payload.sg_list); + failjob_rls_job: ++ kfree(job); + return -ENOMEM; + } + +diff --git a/crypto/Kconfig b/crypto/Kconfig +index 7240821137fd..617bf4a7da56 100644 +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -343,6 +343,7 @@ config CRYPTO_XTS + select CRYPTO_BLKCIPHER + select CRYPTO_MANAGER + select CRYPTO_GF128MUL ++ select CRYPTO_ECB + help + XTS: IEEE1619/D16 narrow block cipher use with aes-xts-plain, + key size 256, 384 or 512 bits. This implementation currently +diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm +index b1f8a73e5a94..eed1e073d96d 100644 +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -241,7 +241,7 @@ config ARM_PXA2xx_CPUFREQ + + config ACPI_CPPC_CPUFREQ + tristate "CPUFreq driver based on the ACPI CPPC spec" +- depends on ACPI ++ depends on ACPI_PROCESSOR + select ACPI_CPPC_LIB + default n + help +diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c +index 58bf94b69186..273e05a3c933 100644 +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -1802,6 +1802,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) + return -EINVAL; + } + req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; ++ req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; + } else { + port = NULL; + req_payload.num_slots = 0; +@@ -1817,6 +1818,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) + if (req_payload.num_slots) { + drm_dp_create_payload_step1(mgr, mgr->proposed_vcpis[i]->vcpi, &req_payload); + mgr->payloads[i].num_slots = req_payload.num_slots; ++ mgr->payloads[i].vcpi = req_payload.vcpi; + } else if (mgr->payloads[i].num_slots) { + mgr->payloads[i].num_slots = 0; + drm_dp_destroy_payload_step1(mgr, port, mgr->payloads[i].vcpi, &mgr->payloads[i]); +diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c +index 10835d1f559b..dee0fc421054 100644 +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -1131,6 +1131,7 @@ static int at91_twi_suspend_noirq(struct device *dev) + + static int at91_twi_resume_noirq(struct device *dev) + { ++ struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + int ret; + + if (!pm_runtime_status_suspended(dev)) { +@@ -1142,6 +1143,8 @@ static int at91_twi_resume_noirq(struct device *dev) + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + ++ at91_init_twi_bus(twi_dev); ++ + return 0; + } + +diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c +index 02e636a1c49a..475c5a74f2d1 100644 +--- a/drivers/iio/adc/xilinx-xadc-core.c ++++ b/drivers/iio/adc/xilinx-xadc-core.c +@@ -1208,7 +1208,7 @@ static int xadc_probe(struct platform_device *pdev) + + ret = xadc->ops->setup(pdev, indio_dev, irq); + if (ret) +- goto err_free_samplerate_trigger; ++ goto err_clk_disable_unprepare; + + ret = request_irq(irq, xadc->ops->interrupt_handler, 0, + dev_name(&pdev->dev), indio_dev); +@@ -1268,6 +1268,8 @@ static int xadc_probe(struct platform_device *pdev) + + err_free_irq: + free_irq(irq, indio_dev); ++err_clk_disable_unprepare: ++ clk_disable_unprepare(xadc->clk); + err_free_samplerate_trigger: + if (xadc->ops->flags & XADC_FLAGS_BUFFERED) + iio_trigger_free(xadc->samplerate_trigger); +@@ -1277,8 +1279,6 @@ err_free_convst_trigger: + err_triggered_buffer_cleanup: + if (xadc->ops->flags & XADC_FLAGS_BUFFERED) + iio_triggered_buffer_cleanup(indio_dev); +-err_clk_disable_unprepare: +- clk_disable_unprepare(xadc->clk); + err_device_free: + kfree(indio_dev->channels); + +diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c +index 75573fa431ba..63faee04a008 100644 +--- a/drivers/irqchip/irq-crossbar.c ++++ b/drivers/irqchip/irq-crossbar.c +@@ -198,7 +198,8 @@ static const struct irq_domain_ops crossbar_domain_ops = { + + static int __init crossbar_of_init(struct device_node *node) + { +- int i, size, max = 0, reserved = 0, entry; ++ int i, size, reserved = 0; ++ u32 max = 0, entry; + const __be32 *irqsr; + int ret = -ENOMEM; + +diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c +index bf3fbd00a091..64b586458d3d 100644 +--- a/drivers/isdn/i4l/isdn_ppp.c ++++ b/drivers/isdn/i4l/isdn_ppp.c +@@ -828,7 +828,6 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) + isdn_net_local *lp; + struct ippp_struct *is; + int proto; +- unsigned char protobuf[4]; + + is = file->private_data; + +@@ -842,24 +841,28 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) + if (!lp) + printk(KERN_DEBUG "isdn_ppp_write: lp == NULL\n"); + else { +- /* +- * Don't reset huptimer for +- * LCP packets. (Echo requests). +- */ +- if (copy_from_user(protobuf, buf, 4)) +- return -EFAULT; +- proto = PPP_PROTOCOL(protobuf); +- if (proto != PPP_LCP) +- lp->huptimer = 0; ++ if (lp->isdn_device < 0 || lp->isdn_channel < 0) { ++ unsigned char protobuf[4]; ++ /* ++ * Don't reset huptimer for ++ * LCP packets. (Echo requests). ++ */ ++ if (copy_from_user(protobuf, buf, 4)) ++ return -EFAULT; ++ ++ proto = PPP_PROTOCOL(protobuf); ++ if (proto != PPP_LCP) ++ lp->huptimer = 0; + +- if (lp->isdn_device < 0 || lp->isdn_channel < 0) + return 0; ++ } + + if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) && + lp->dialstate == 0 && + (lp->flags & ISDN_NET_CONNECTED)) { + unsigned short hl; + struct sk_buff *skb; ++ unsigned char *cpy_buf; + /* + * we need to reserve enough space in front of + * sk_buff. old call to dev_alloc_skb only reserved +@@ -872,11 +875,21 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count) + return count; + } + skb_reserve(skb, hl); +- if (copy_from_user(skb_put(skb, count), buf, count)) ++ cpy_buf = skb_put(skb, count); ++ if (copy_from_user(cpy_buf, buf, count)) + { + kfree_skb(skb); + return -EFAULT; + } ++ ++ /* ++ * Don't reset huptimer for ++ * LCP packets. (Echo requests). ++ */ ++ proto = PPP_PROTOCOL(cpy_buf); ++ if (proto != PPP_LCP) ++ lp->huptimer = 0; ++ + if (is->debug & 0x40) { + printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len); + isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot); +diff --git a/drivers/md/linear.c b/drivers/md/linear.c +index 6ba3227e29b2..7ffb20ec1a46 100644 +--- a/drivers/md/linear.c ++++ b/drivers/md/linear.c +@@ -223,7 +223,8 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev) + * oldconf until no one uses it anymore. + */ + mddev_suspend(mddev); +- oldconf = rcu_dereference(mddev->private); ++ oldconf = rcu_dereference_protected(mddev->private, ++ lockdep_is_held(&mddev->reconfig_mutex)); + mddev->raid_disks++; + WARN_ONCE(mddev->raid_disks != newconf->raid_disks, + "copied raid_disks doesn't match mddev->raid_disks"); +diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c +index fdb5cdb3cd15..81abe46c9e0d 100644 +--- a/drivers/net/ethernet/ibm/emac/mal.c ++++ b/drivers/net/ethernet/ibm/emac/mal.c +@@ -402,7 +402,7 @@ static int mal_poll(struct napi_struct *napi, int budget) + unsigned long flags; + + MAL_DBG2(mal, "poll(%d)" NL, budget); +- again: ++ + /* Process TX skbs */ + list_for_each(l, &mal->poll_list) { + struct mal_commac *mc = +@@ -451,7 +451,6 @@ static int mal_poll(struct napi_struct *napi, int budget) + spin_lock_irqsave(&mal->lock, flags); + mal_disable_eob_irq(mal); + spin_unlock_irqrestore(&mal->lock, flags); +- goto again; + } + mc->ops->poll_tx(mc->dev); + } +diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c +index 0e67145bc418..4f34e1b79705 100644 +--- a/drivers/net/ethernet/marvell/mvpp2.c ++++ b/drivers/net/ethernet/marvell/mvpp2.c +@@ -4415,13 +4415,12 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port, + struct mvpp2_txq_pcpu_buf *tx_buf = + txq_pcpu->buffs + txq_pcpu->txq_get_index; + +- mvpp2_txq_inc_get(txq_pcpu); +- + dma_unmap_single(port->dev->dev.parent, tx_buf->phys, + tx_buf->size, DMA_TO_DEVICE); +- if (!tx_buf->skb) +- continue; +- dev_kfree_skb_any(tx_buf->skb); ++ if (tx_buf->skb) ++ dev_kfree_skb_any(tx_buf->skb); ++ ++ mvpp2_txq_inc_get(txq_pcpu); + } + } + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c +index 1494997c4f7e..4dccf7287f0f 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c +@@ -88,10 +88,17 @@ void mlx4_en_remove_timestamp(struct mlx4_en_dev *mdev) + } + } + ++#define MLX4_EN_WRAP_AROUND_SEC 10UL ++/* By scheduling the overflow check every 5 seconds, we have a reasonably ++ * good chance we wont miss a wrap around. ++ * TOTO: Use a timer instead of a work queue to increase the guarantee. ++ */ ++#define MLX4_EN_OVERFLOW_PERIOD (MLX4_EN_WRAP_AROUND_SEC * HZ / 2) ++ + void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) + { + bool timeout = time_is_before_jiffies(mdev->last_overflow_check + +- mdev->overflow_period); ++ MLX4_EN_OVERFLOW_PERIOD); + unsigned long flags; + + if (timeout) { +@@ -236,7 +243,6 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = { + .enable = mlx4_en_phc_enable, + }; + +-#define MLX4_EN_WRAP_AROUND_SEC 10ULL + + /* This function calculates the max shift that enables the user range + * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register. +@@ -258,7 +264,6 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) + { + struct mlx4_dev *dev = mdev->dev; + unsigned long flags; +- u64 ns, zero = 0; + + /* mlx4_en_init_timestamp is called for each netdev. + * mdev->ptp_clock is common for all ports, skip initialization if +@@ -282,13 +287,6 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) + ktime_to_ns(ktime_get_real())); + write_unlock_irqrestore(&mdev->clock_lock, flags); + +- /* Calculate period in seconds to call the overflow watchdog - to make +- * sure counter is checked at least once every wrap around. +- */ +- ns = cyclecounter_cyc2ns(&mdev->cycles, mdev->cycles.mask, zero, &zero); +- do_div(ns, NSEC_PER_SEC / 2 / HZ); +- mdev->overflow_period = ns; +- + /* Configure the PHC */ + mdev->ptp_clock_info = mlx4_en_ptp_clock_info; + snprintf(mdev->ptp_clock_info.name, 16, "mlx4 ptp"); +diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c +index 31c491e02e69..99361352ed0d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/main.c ++++ b/drivers/net/ethernet/mellanox/mlx4/main.c +@@ -791,8 +791,6 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) + return -ENOSYS; + } + +- mlx4_log_num_mgm_entry_size = hca_param.log_mc_entry_sz; +- + dev->caps.hca_core_clock = hca_param.hca_core_clock; + + memset(&dev_cap, 0, sizeof(dev_cap)); +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +index c41f15102ae0..10aa6544cf4d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -409,7 +409,6 @@ struct mlx4_en_dev { + struct cyclecounter cycles; + struct timecounter clock; + unsigned long last_overflow_check; +- unsigned long overflow_period; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_clock_info; + struct notifier_block nb; +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index c31d8e74f131..cd191f82d816 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1195,11 +1195,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, + switch (tun->flags & TUN_TYPE_MASK) { + case IFF_TUN: + if (tun->flags & IFF_NO_PI) { +- switch (skb->data[0] & 0xf0) { +- case 0x40: ++ u8 ip_version = skb->len ? (skb->data[0] >> 4) : 0; ++ ++ switch (ip_version) { ++ case 4: + pi.proto = htons(ETH_P_IP); + break; +- case 0x60: ++ case 6: + pi.proto = htons(ETH_P_IPV6); + break; + default: +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index 019d7165a045..2a996a68fc2b 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2884,6 +2884,7 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2, + static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) + { + struct hwsim_new_radio_params param = { 0 }; ++ const char *hwname = NULL; + + param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; + param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; +@@ -2897,8 +2898,14 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) + if (info->attrs[HWSIM_ATTR_NO_VIF]) + param.no_vif = true; + +- if (info->attrs[HWSIM_ATTR_RADIO_NAME]) +- param.hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); ++ if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { ++ hwname = kasprintf(GFP_KERNEL, "%.*s", ++ nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), ++ (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); ++ if (!hwname) ++ return -ENOMEM; ++ param.hwname = hwname; ++ } + + if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) + param.use_chanctx = true; +@@ -2926,11 +2933,15 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) + s64 idx = -1; + const char *hwname = NULL; + +- if (info->attrs[HWSIM_ATTR_RADIO_ID]) ++ if (info->attrs[HWSIM_ATTR_RADIO_ID]) { + idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); +- else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) +- hwname = (void *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); +- else ++ } else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { ++ hwname = kasprintf(GFP_KERNEL, "%.*s", ++ nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), ++ (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); ++ if (!hwname) ++ return -ENOMEM; ++ } else + return -EINVAL; + + spin_lock_bh(&hwsim_radio_lock); +@@ -2939,7 +2950,8 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) + if (data->idx != idx) + continue; + } else { +- if (strcmp(hwname, wiphy_name(data->hw->wiphy))) ++ if (!hwname || ++ strcmp(hwname, wiphy_name(data->hw->wiphy))) + continue; + } + +@@ -2947,10 +2959,12 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) + spin_unlock_bh(&hwsim_radio_lock); + mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), + info); ++ kfree(hwname); + return 0; + } + spin_unlock_bh(&hwsim_radio_lock); + ++ kfree(hwname); + return -ENODEV; + } + +diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c +index e6fb97cb12f4..7c28dc1cb0dd 100644 +--- a/drivers/scsi/device_handler/scsi_dh_emc.c ++++ b/drivers/scsi/device_handler/scsi_dh_emc.c +@@ -456,7 +456,7 @@ static int clariion_prep_fn(struct scsi_device *sdev, struct request *req) + static int clariion_std_inquiry(struct scsi_device *sdev, + struct clariion_dh_data *csdev) + { +- int err; ++ int err = SCSI_DH_OK; + char *sp_model; + + err = send_inquiry_cmd(sdev, 0, csdev); +diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c +index 6c88fb021444..4eeb82cf79e4 100644 +--- a/drivers/target/iscsi/iscsi_target_erl0.c ++++ b/drivers/target/iscsi/iscsi_target_erl0.c +@@ -44,10 +44,8 @@ void iscsit_set_dataout_sequence_values( + */ + if (cmd->unsolicited_data) { + cmd->seq_start_offset = cmd->write_data_done; +- cmd->seq_end_offset = (cmd->write_data_done + +- ((cmd->se_cmd.data_length > +- conn->sess->sess_ops->FirstBurstLength) ? +- conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length)); ++ cmd->seq_end_offset = min(cmd->se_cmd.data_length, ++ conn->sess->sess_ops->FirstBurstLength); + return; + } + +diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c +index e04b57f79df8..0f82c0b146f6 100644 +--- a/drivers/tty/goldfish.c ++++ b/drivers/tty/goldfish.c +@@ -293,7 +293,7 @@ static int goldfish_tty_probe(struct platform_device *pdev) + return 0; + + err_tty_register_device_failed: +- free_irq(irq, qtty); ++ free_irq(irq, pdev); + err_request_irq_failed: + goldfish_tty_current_line_count--; + if (goldfish_tty_current_line_count == 0) +diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c +index 4e603d060e80..59828d819145 100644 +--- a/drivers/tty/serial/sunhv.c ++++ b/drivers/tty/serial/sunhv.c +@@ -398,6 +398,12 @@ static struct uart_driver sunhv_reg = { + + static struct uart_port *sunhv_port; + ++void sunhv_migrate_hvcons_irq(int cpu) ++{ ++ /* Migrate hvcons irq to param cpu */ ++ irq_force_affinity(sunhv_port->irq, cpumask_of(cpu)); ++} ++ + /* Copy 's' into the con_write_page, decoding "\n" into + * "\r\n" along the way. We have to return two lengths + * because the caller needs to know how much to advance +diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c +index 5bf931ce1353..978098f71761 100644 +--- a/drivers/watchdog/kempld_wdt.c ++++ b/drivers/watchdog/kempld_wdt.c +@@ -140,12 +140,19 @@ static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data, + unsigned int timeout) + { + struct kempld_device_data *pld = wdt_data->pld; +- u32 prescaler = kempld_prescaler[PRESCALER_21]; ++ u32 prescaler; + u64 stage_timeout64; + u32 stage_timeout; + u32 remainder; + u8 stage_cfg; + ++#if GCC_VERSION < 40400 ++ /* work around a bug compiling do_div() */ ++ prescaler = READ_ONCE(kempld_prescaler[PRESCALER_21]); ++#else ++ prescaler = kempld_prescaler[PRESCALER_21]; ++#endif ++ + if (!stage) + return -EINVAL; + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index 63a6152be04b..c5bbb5300658 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -1648,6 +1648,9 @@ static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen) + { + int ret; + ++ if (ino == BTRFS_FIRST_FREE_OBJECTID) ++ return 1; ++ + ret = get_cur_inode_state(sctx, ino, gen); + if (ret < 0) + goto out; +@@ -1833,7 +1836,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, + * not delted and then re-created, if it was then we have no overwrite + * and we can just unlink this entry. + */ +- if (sctx->parent_root) { ++ if (sctx->parent_root && dir != BTRFS_FIRST_FREE_OBJECTID) { + ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, + NULL, NULL, NULL); + if (ret < 0 && ret != -ENOENT) +diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c +index f54f77037d22..ead89489ae71 100644 +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -1845,13 +1845,18 @@ static int build_dentry_path(struct dentry *dentry, + int *pfreepath) + { + char *path; ++ struct inode *dir; + +- if (ceph_snap(d_inode(dentry->d_parent)) == CEPH_NOSNAP) { +- *pino = ceph_ino(d_inode(dentry->d_parent)); ++ rcu_read_lock(); ++ dir = d_inode_rcu(dentry->d_parent); ++ if (dir && ceph_snap(dir) == CEPH_NOSNAP) { ++ *pino = ceph_ino(dir); ++ rcu_read_unlock(); + *ppath = dentry->d_name.name; + *ppathlen = dentry->d_name.len; + return 0; + } ++ rcu_read_unlock(); + path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1); + if (IS_ERR(path)) + return PTR_ERR(path); +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 972eab7ac071..98b2fc2678ff 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -1416,7 +1416,12 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, + goto fail; + } + repeat: +- page = grab_cache_page_write_begin(mapping, index, flags); ++ /* ++ * Do not use grab_cache_page_write_begin() to avoid deadlock due to ++ * wait_for_stable_page. Will wait that below with our IO control. ++ */ ++ page = pagecache_get_page(mapping, index, ++ FGP_LOCK | FGP_WRITE | FGP_CREAT, GFP_NOFS); + if (!page) { + err = -ENOMEM; + goto fail; +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 15bdc2d48cfe..24ace275160c 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -696,6 +696,14 @@ int set_callback_cred(void) + return 0; + } + ++void cleanup_callback_cred(void) ++{ ++ if (callback_cred) { ++ put_rpccred(callback_cred); ++ callback_cred = NULL; ++ } ++} ++ + static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses) + { + if (clp->cl_minorversion == 0) { +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 9e5a6842346e..ca9ebc3242d3 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -6792,23 +6792,24 @@ nfs4_state_start(void) + + ret = set_callback_cred(); + if (ret) +- return -ENOMEM; ++ return ret; ++ + laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); + if (laundry_wq == NULL) { + ret = -ENOMEM; +- goto out_recovery; ++ goto out_cleanup_cred; + } + ret = nfsd4_create_callback_queue(); + if (ret) + goto out_free_laundry; + + set_max_delegations(); +- + return 0; + + out_free_laundry: + destroy_workqueue(laundry_wq); +-out_recovery: ++out_cleanup_cred: ++ cleanup_callback_cred(); + return ret; + } + +@@ -6847,6 +6848,7 @@ nfs4_state_shutdown(void) + { + destroy_workqueue(laundry_wq); + nfsd4_destroy_callback_queue(); ++ cleanup_callback_cred(); + } + + static void +diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h +index 5134eedcb16c..86af697c21d3 100644 +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -595,6 +595,7 @@ extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, + extern __be32 nfs4_check_open_reclaim(clientid_t *clid, + struct nfsd4_compound_state *cstate, struct nfsd_net *nn); + extern int set_callback_cred(void); ++extern void cleanup_callback_cred(void); + extern void nfsd4_probe_callback(struct nfs4_client *clp); + extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); + extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); +diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c +index 60a5f1548cd9..555b57a16499 100644 +--- a/fs/ocfs2/dlmglue.c ++++ b/fs/ocfs2/dlmglue.c +@@ -531,6 +531,7 @@ void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) + init_waitqueue_head(&res->l_event); + INIT_LIST_HEAD(&res->l_blocked_list); + INIT_LIST_HEAD(&res->l_mask_waiters); ++ INIT_LIST_HEAD(&res->l_holders); + } + + void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res, +@@ -748,6 +749,50 @@ void ocfs2_lock_res_free(struct ocfs2_lock_res *res) + res->l_flags = 0UL; + } + ++/* ++ * Keep a list of processes who have interest in a lockres. ++ * Note: this is now only uesed for check recursive cluster locking. ++ */ ++static inline void ocfs2_add_holder(struct ocfs2_lock_res *lockres, ++ struct ocfs2_lock_holder *oh) ++{ ++ INIT_LIST_HEAD(&oh->oh_list); ++ oh->oh_owner_pid = get_pid(task_pid(current)); ++ ++ spin_lock(&lockres->l_lock); ++ list_add_tail(&oh->oh_list, &lockres->l_holders); ++ spin_unlock(&lockres->l_lock); ++} ++ ++static inline void ocfs2_remove_holder(struct ocfs2_lock_res *lockres, ++ struct ocfs2_lock_holder *oh) ++{ ++ spin_lock(&lockres->l_lock); ++ list_del(&oh->oh_list); ++ spin_unlock(&lockres->l_lock); ++ ++ put_pid(oh->oh_owner_pid); ++} ++ ++static inline int ocfs2_is_locked_by_me(struct ocfs2_lock_res *lockres) ++{ ++ struct ocfs2_lock_holder *oh; ++ struct pid *pid; ++ ++ /* look in the list of holders for one with the current task as owner */ ++ spin_lock(&lockres->l_lock); ++ pid = task_pid(current); ++ list_for_each_entry(oh, &lockres->l_holders, oh_list) { ++ if (oh->oh_owner_pid == pid) { ++ spin_unlock(&lockres->l_lock); ++ return 1; ++ } ++ } ++ spin_unlock(&lockres->l_lock); ++ ++ return 0; ++} ++ + static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres, + int level) + { +@@ -2343,8 +2388,9 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, + goto getbh; + } + +- if (ocfs2_mount_local(osb)) +- goto local; ++ if ((arg_flags & OCFS2_META_LOCK_GETBH) || ++ ocfs2_mount_local(osb)) ++ goto update; + + if (!(arg_flags & OCFS2_META_LOCK_RECOVERY)) + ocfs2_wait_for_recovery(osb); +@@ -2373,7 +2419,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, + if (!(arg_flags & OCFS2_META_LOCK_RECOVERY)) + ocfs2_wait_for_recovery(osb); + +-local: ++update: + /* + * We only see this flag if we're being called from + * ocfs2_read_locked_inode(). It means we're locking an inode +@@ -2515,6 +2561,59 @@ void ocfs2_inode_unlock(struct inode *inode, + ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); + } + ++/* ++ * This _tracker variantes are introduced to deal with the recursive cluster ++ * locking issue. The idea is to keep track of a lock holder on the stack of ++ * the current process. If there's a lock holder on the stack, we know the ++ * task context is already protected by cluster locking. Currently, they're ++ * used in some VFS entry routines. ++ * ++ * return < 0 on error, return == 0 if there's no lock holder on the stack ++ * before this call, return == 1 if this call would be a recursive locking. ++ */ ++int ocfs2_inode_lock_tracker(struct inode *inode, ++ struct buffer_head **ret_bh, ++ int ex, ++ struct ocfs2_lock_holder *oh) ++{ ++ int status; ++ int arg_flags = 0, has_locked; ++ struct ocfs2_lock_res *lockres; ++ ++ lockres = &OCFS2_I(inode)->ip_inode_lockres; ++ has_locked = ocfs2_is_locked_by_me(lockres); ++ /* Just get buffer head if the cluster lock has been taken */ ++ if (has_locked) ++ arg_flags = OCFS2_META_LOCK_GETBH; ++ ++ if (likely(!has_locked || ret_bh)) { ++ status = ocfs2_inode_lock_full(inode, ret_bh, ex, arg_flags); ++ if (status < 0) { ++ if (status != -ENOENT) ++ mlog_errno(status); ++ return status; ++ } ++ } ++ if (!has_locked) ++ ocfs2_add_holder(lockres, oh); ++ ++ return has_locked; ++} ++ ++void ocfs2_inode_unlock_tracker(struct inode *inode, ++ int ex, ++ struct ocfs2_lock_holder *oh, ++ int had_lock) ++{ ++ struct ocfs2_lock_res *lockres; ++ ++ lockres = &OCFS2_I(inode)->ip_inode_lockres; ++ if (!had_lock) { ++ ocfs2_remove_holder(lockres, oh); ++ ocfs2_inode_unlock(inode, ex); ++ } ++} ++ + int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno) + { + struct ocfs2_lock_res *lockres; +diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h +index d293a22c32c5..a7fc18ba0dc1 100644 +--- a/fs/ocfs2/dlmglue.h ++++ b/fs/ocfs2/dlmglue.h +@@ -70,6 +70,11 @@ struct ocfs2_orphan_scan_lvb { + __be32 lvb_os_seqno; + }; + ++struct ocfs2_lock_holder { ++ struct list_head oh_list; ++ struct pid *oh_owner_pid; ++}; ++ + /* ocfs2_inode_lock_full() 'arg_flags' flags */ + /* don't wait on recovery. */ + #define OCFS2_META_LOCK_RECOVERY (0x01) +@@ -77,6 +82,8 @@ struct ocfs2_orphan_scan_lvb { + #define OCFS2_META_LOCK_NOQUEUE (0x02) + /* don't block waiting for the downconvert thread, instead return -EAGAIN */ + #define OCFS2_LOCK_NONBLOCK (0x04) ++/* just get back disk inode bh if we've got cluster lock. */ ++#define OCFS2_META_LOCK_GETBH (0x08) + + /* Locking subclasses of inode cluster lock */ + enum { +@@ -170,4 +177,15 @@ void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug); + + /* To set the locking protocol on module initialization */ + void ocfs2_set_locking_protocol(void); ++ ++/* The _tracker pair is used to avoid cluster recursive locking */ ++int ocfs2_inode_lock_tracker(struct inode *inode, ++ struct buffer_head **ret_bh, ++ int ex, ++ struct ocfs2_lock_holder *oh); ++void ocfs2_inode_unlock_tracker(struct inode *inode, ++ int ex, ++ struct ocfs2_lock_holder *oh, ++ int had_lock); ++ + #endif /* DLMGLUE_H */ +diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h +index 7a0126267847..2495066a9ca3 100644 +--- a/fs/ocfs2/ocfs2.h ++++ b/fs/ocfs2/ocfs2.h +@@ -172,6 +172,7 @@ struct ocfs2_lock_res { + + struct list_head l_blocked_list; + struct list_head l_mask_waiters; ++ struct list_head l_holders; + + unsigned long l_flags; + char l_name[OCFS2_LOCK_ID_MAX_LEN]; +diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h +index 4d9f233c4ba8..7d58ffdacd62 100644 +--- a/include/asm-generic/percpu.h ++++ b/include/asm-generic/percpu.h +@@ -105,15 +105,35 @@ do { \ + (__ret); \ + }) + +-#define this_cpu_generic_read(pcp) \ ++#define __this_cpu_generic_read_nopreempt(pcp) \ + ({ \ + typeof(pcp) __ret; \ + preempt_disable(); \ +- __ret = *this_cpu_ptr(&(pcp)); \ ++ __ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \ + preempt_enable(); \ + __ret; \ + }) + ++#define __this_cpu_generic_read_noirq(pcp) \ ++({ \ ++ typeof(pcp) __ret; \ ++ unsigned long __flags; \ ++ raw_local_irq_save(__flags); \ ++ __ret = *raw_cpu_ptr(&(pcp)); \ ++ raw_local_irq_restore(__flags); \ ++ __ret; \ ++}) ++ ++#define this_cpu_generic_read(pcp) \ ++({ \ ++ typeof(pcp) __ret; \ ++ if (__native_word(pcp)) \ ++ __ret = __this_cpu_generic_read_nopreempt(pcp); \ ++ else \ ++ __ret = __this_cpu_generic_read_noirq(pcp); \ ++ __ret; \ ++}) ++ + #define this_cpu_generic_to_op(pcp, val, op) \ + do { \ + unsigned long __flags; \ +diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h +index 925730bc9fc1..311176f290b2 100644 +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -301,6 +301,7 @@ struct trace_event_call { + int perf_refcount; + struct hlist_head __percpu *perf_events; + struct bpf_prog *prog; ++ struct perf_event *bpf_prog_owner; + + int (*perf_perm)(struct trace_event_call *, + struct perf_event *); +diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h +index cccdcfd14973..f348c736e6e0 100644 +--- a/include/net/sctp/ulpevent.h ++++ b/include/net/sctp/ulpevent.h +@@ -141,8 +141,12 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); + static inline int sctp_ulpevent_type_enabled(__u16 sn_type, + struct sctp_event_subscribe *mask) + { ++ int offset = sn_type - SCTP_SN_TYPE_BASE; + char *amask = (char *) mask; +- return amask[sn_type - SCTP_SN_TYPE_BASE]; ++ ++ if (offset >= sizeof(struct sctp_event_subscribe)) ++ return 0; ++ return amask[offset]; + } + + /* Given an event subscription, is this event enabled? */ +diff --git a/include/uapi/linux/mroute6.h b/include/uapi/linux/mroute6.h +index ce91215cf7e6..e0b566dc72ef 100644 +--- a/include/uapi/linux/mroute6.h ++++ b/include/uapi/linux/mroute6.h +@@ -3,6 +3,7 @@ + + #include + #include ++#include /* For struct sockaddr_in6. */ + + /* + * Based on the MROUTING 3.5 defines primarily to keep +diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h +index 0f9265cb2a96..7af20a136429 100644 +--- a/include/uapi/linux/rds.h ++++ b/include/uapi/linux/rds.h +@@ -35,6 +35,7 @@ + #define _LINUX_RDS_H + + #include ++#include /* For __kernel_sockaddr_storage. */ + + #define RDS_IB_ABI_VERSION 0x301 + +@@ -223,7 +224,7 @@ struct rds_get_mr_args { + }; + + struct rds_get_mr_for_dest_args { +- struct sockaddr_storage dest_addr; ++ struct __kernel_sockaddr_storage dest_addr; + struct rds_iovec vec; + uint64_t cookie_addr; + uint64_t flags; +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 863e24f1e62e..70dc6dcf8649 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1033,7 +1033,8 @@ static int check_alu_op(struct verifier_env *env, struct bpf_insn *insn) + } + } else { + if (insn->src_reg != BPF_REG_0 || insn->off != 0 || +- (insn->imm != 16 && insn->imm != 32 && insn->imm != 64)) { ++ (insn->imm != 16 && insn->imm != 32 && insn->imm != 64) || ++ BPF_CLASS(insn->code) == BPF_ALU64) { + verbose("BPF_END uses reserved fields\n"); + return -EINVAL; + } +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 3697063dd09a..8f75386e61a7 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7108,6 +7108,7 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) + } + + event->tp_event->prog = prog; ++ event->tp_event->bpf_prog_owner = event; + + return 0; + } +@@ -7120,7 +7121,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event) + return; + + prog = event->tp_event->prog; +- if (prog) { ++ if (prog && event->tp_event->bpf_prog_owner == event) { + event->tp_event->prog = NULL; + bpf_prog_put_rcu(prog); + } +diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c +index 60ace56618f6..0e2c4911ba61 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -3128,10 +3128,17 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, + if (depth) { + hlock = curr->held_locks + depth - 1; + if (hlock->class_idx == class_idx && nest_lock) { +- if (hlock->references) ++ if (hlock->references) { ++ /* ++ * Check: unsigned int references:12, overflow. ++ */ ++ if (DEBUG_LOCKS_WARN_ON(hlock->references == (1 << 12)-1)) ++ return 0; ++ + hlock->references++; +- else ++ } else { + hlock->references = 2; ++ } + + return 1; + } +diff --git a/mm/slab_common.c b/mm/slab_common.c +index bec2fce9fafc..01e7246de8df 100644 +--- a/mm/slab_common.c ++++ b/mm/slab_common.c +@@ -250,7 +250,7 @@ struct kmem_cache *find_mergeable(size_t size, size_t align, + { + struct kmem_cache *s; + +- if (slab_nomerge || (flags & SLAB_NEVER_MERGE)) ++ if (slab_nomerge) + return NULL; + + if (ctor) +@@ -261,6 +261,9 @@ struct kmem_cache *find_mergeable(size_t size, size_t align, + size = ALIGN(size, align); + flags = kmem_cache_flags(size, flags, name, NULL); + ++ if (flags & SLAB_NEVER_MERGE) ++ return NULL; ++ + list_for_each_entry_reverse(s, &slab_caches, list) { + if (slab_unmergeable(s)) + continue; +diff --git a/net/core/sock.c b/net/core/sock.c +index bd2fad27891e..cd12cb6fe366 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1516,6 +1516,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) + + sock_copy(newsk, sk); + ++ newsk->sk_prot_creator = sk->sk_prot; ++ + /* SANITY */ + if (likely(newsk->sk_net_refcnt)) + get_net(sock_net(newsk)); +diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c +index 65036891e080..a03f834f16d5 100644 +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -156,6 +156,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, + struct ip_tunnel_parm *parms = &tunnel->parms; + struct dst_entry *dst = skb_dst(skb); + struct net_device *tdev; /* Device to other host */ ++ int pkt_len = skb->len; + int err; + + if (!dst) { +@@ -199,7 +200,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, + + err = dst_output(tunnel->net, skb->sk, skb); + if (net_xmit_eval(err) == 0) +- err = skb->len; ++ err = pkt_len; + iptunnel_xmit_stats(err, &dev->stats, dev->tstats); + return NETDEV_TX_OK; + +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index e89135828c3d..eab117033b8a 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -1173,24 +1173,25 @@ static int ip6gre_tunnel_change_mtu(struct net_device *dev, int new_mtu) + } + + static int ip6gre_header(struct sk_buff *skb, struct net_device *dev, +- unsigned short type, +- const void *daddr, const void *saddr, unsigned int len) ++ unsigned short type, const void *daddr, ++ const void *saddr, unsigned int len) + { + struct ip6_tnl *t = netdev_priv(dev); +- struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen); +- __be16 *p = (__be16 *)(ipv6h+1); ++ struct ipv6hdr *ipv6h; ++ __be16 *p; + +- ip6_flow_hdr(ipv6h, 0, +- ip6_make_flowlabel(dev_net(dev), skb, +- t->fl.u.ip6.flowlabel, true, +- &t->fl.u.ip6)); ++ ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen + sizeof(*ipv6h)); ++ ip6_flow_hdr(ipv6h, 0, ip6_make_flowlabel(dev_net(dev), skb, ++ t->fl.u.ip6.flowlabel, ++ true, &t->fl.u.ip6)); + ipv6h->hop_limit = t->parms.hop_limit; + ipv6h->nexthdr = NEXTHDR_GRE; + ipv6h->saddr = t->parms.laddr; + ipv6h->daddr = t->parms.raddr; + +- p[0] = t->parms.o_flags; +- p[1] = htons(type); ++ p = (__be16 *)(ipv6h + 1); ++ p[0] = t->parms.o_flags; ++ p[1] = htons(type); + + /* + * Set the source hardware address. +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index bdcc4d9cedd3..7ebb14def2cb 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -434,6 +434,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + struct dst_entry *dst = skb_dst(skb); + struct net_device *tdev; + struct xfrm_state *x; ++ int pkt_len = skb->len; + int err = -1; + int mtu; + +@@ -487,7 +488,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) + struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); + + u64_stats_update_begin(&tstats->syncp); +- tstats->tx_bytes += skb->len; ++ tstats->tx_bytes += pkt_len; + tstats->tx_packets++; + u64_stats_update_end(&tstats->syncp); + } else { +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 6fd4af3b5b79..6eb1e9293b6f 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1007,6 +1007,7 @@ static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb, + */ + offset = skb_transport_offset(skb); + skb->csum = skb_checksum(skb, offset, skb->len - offset, 0); ++ csum = skb->csum; + + skb->ip_summed = CHECKSUM_NONE; + +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index d3dec414fd44..d48281ca9c72 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -1321,6 +1321,9 @@ static void l2tp_tunnel_del_work(struct work_struct *work) + struct sock *sk = NULL; + + tunnel = container_of(work, struct l2tp_tunnel, del_work); ++ ++ l2tp_tunnel_closeall(tunnel); ++ + sk = l2tp_tunnel_sock_lookup(tunnel); + if (!sk) + goto out; +@@ -1640,15 +1643,12 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create); + + /* This function is used by the netlink TUNNEL_DELETE command. + */ +-int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) ++void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel) + { +- l2tp_tunnel_inc_refcount(tunnel); +- l2tp_tunnel_closeall(tunnel); +- if (false == queue_work(l2tp_wq, &tunnel->del_work)) { +- l2tp_tunnel_dec_refcount(tunnel); +- return 1; ++ if (!test_and_set_bit(0, &tunnel->dead)) { ++ l2tp_tunnel_inc_refcount(tunnel); ++ queue_work(l2tp_wq, &tunnel->del_work); + } +- return 0; + } + EXPORT_SYMBOL_GPL(l2tp_tunnel_delete); + +diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h +index 555d962a62d2..9cf546846edb 100644 +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -169,6 +169,9 @@ struct l2tp_tunnel_cfg { + + struct l2tp_tunnel { + int magic; /* Should be L2TP_TUNNEL_MAGIC */ ++ ++ unsigned long dead; ++ + struct rcu_head rcu; + rwlock_t hlist_lock; /* protect session_hlist */ + struct hlist_head session_hlist[L2TP_HASH_SIZE]; +@@ -253,7 +256,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, + u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, + struct l2tp_tunnel **tunnelp); + void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel); +-int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); ++void l2tp_tunnel_delete(struct l2tp_tunnel *tunnel); + struct l2tp_session *l2tp_session_create(int priv_size, + struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 63ea6cbac5ad..7e7b9ef29d8d 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -661,7 +661,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) + } + + /* No need to do anything if the driver does all */ +- if (ieee80211_hw_check(&local->hw, AP_LINK_PS)) ++ if (ieee80211_hw_check(&local->hw, AP_LINK_PS) && !local->ops->set_tim) + return; + + if (sta->dead) +diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c +index acf5c7b3f378..7f16d19d6198 100644 +--- a/net/netfilter/nf_conntrack_expect.c ++++ b/net/netfilter/nf_conntrack_expect.c +@@ -395,7 +395,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) + struct net *net = nf_ct_exp_net(expect); + struct hlist_node *next; + unsigned int h; +- int ret = 1; ++ int ret = 0; + + if (!master_help) { + ret = -ESHUTDOWN; +@@ -445,7 +445,7 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, + + spin_lock_bh(&nf_conntrack_expect_lock); + ret = __nf_ct_expect_check(expect); +- if (ret <= 0) ++ if (ret < 0) + goto out; + + ret = nf_ct_expect_insert(expect); +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index b70055fc30cb..241f69039a72 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1652,10 +1652,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) + + mutex_lock(&fanout_mutex); + +- err = -EINVAL; +- if (!po->running) +- goto out; +- + err = -EALREADY; + if (po->fanout) + goto out; +@@ -1704,7 +1700,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) + list_add(&match->list, &fanout_list); + } + err = -EINVAL; +- if (match->type == type && ++ ++ spin_lock(&po->bind_lock); ++ if (po->running && ++ match->type == type && + match->prot_hook.type == po->prot_hook.type && + match->prot_hook.dev == po->prot_hook.dev) { + err = -ENOSPC; +@@ -1716,6 +1715,13 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) + err = 0; + } + } ++ spin_unlock(&po->bind_lock); ++ ++ if (err && !atomic_read(&match->sk_ref)) { ++ list_del(&match->list); ++ kfree(match); ++ } ++ + out: + if (err && rollover) { + kfree(rollover); +@@ -2650,6 +2656,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + int vnet_hdr_len; + struct packet_sock *po = pkt_sk(sk); + unsigned short gso_type = 0; ++ bool has_vnet_hdr = false; + int hlen, tlen, linear; + int extra_len = 0; + ssize_t n; +@@ -2737,6 +2744,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + goto out_unlock; + + } ++ has_vnet_hdr = true; + } + + if (unlikely(sock_flag(sk, SOCK_NOFCS))) { +@@ -2796,7 +2804,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + + packet_pick_tx_queue(dev, skb); + +- if (po->has_vnet_hdr) { ++ if (has_vnet_hdr) { + if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + u16 s = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_start); + u16 o = __virtio16_to_cpu(vio_le(), vnet_hdr.csum_offset); +@@ -2938,13 +2946,15 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex, + int ret = 0; + bool unlisted = false; + +- if (po->fanout) +- return -EINVAL; +- + lock_sock(sk); + spin_lock(&po->bind_lock); + rcu_read_lock(); + ++ if (po->fanout) { ++ ret = -EINVAL; ++ goto out_unlock; ++ } ++ + if (name) { + dev = dev_get_by_name_rcu(sock_net(sk), name); + if (!dev) { +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index 8740930f0787..67bddcb2ff46 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -541,7 +541,7 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err) + return false; + if (msg_errcode(msg)) + return false; +- *err = -TIPC_ERR_NO_NAME; ++ *err = TIPC_ERR_NO_NAME; + if (skb_linearize(skb)) + return false; + msg = buf_msg(skb); diff --git a/patch/kernel/mvebu-default/03-patch-4.4.94-95.patch b/patch/kernel/mvebu-default/03-patch-4.4.94-95.patch new file mode 100644 index 000000000..d5f069211 --- /dev/null +++ b/patch/kernel/mvebu-default/03-patch-4.4.94-95.patch @@ -0,0 +1,1587 @@ +diff --git a/Makefile b/Makefile +index ff9d6bbf2210..57e1ea2a189a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 94 ++SUBLEVEL = 95 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S +index a86b19fccb63..c6b855f7892c 100644 +--- a/arch/parisc/kernel/syscall.S ++++ b/arch/parisc/kernel/syscall.S +@@ -479,11 +479,6 @@ lws_start: + comiclr,>> __NR_lws_entries, %r20, %r0 + b,n lws_exit_nosys + +- /* WARNING: Trashing sr2 and sr3 */ +- mfsp %sr7,%r1 /* get userspace into sr3 */ +- mtsp %r1,%sr3 +- mtsp %r0,%sr2 /* get kernel space into sr2 */ +- + /* Load table start */ + ldil L%lws_table, %r1 + ldo R%lws_table(%r1), %r28 /* Scratch use of r28 */ +@@ -632,9 +627,9 @@ cas_action: + stw %r1, 4(%sr2,%r20) + #endif + /* The load and store could fail */ +-1: ldw,ma 0(%sr3,%r26), %r28 ++1: ldw,ma 0(%r26), %r28 + sub,<> %r28, %r25, %r0 +-2: stw,ma %r24, 0(%sr3,%r26) ++2: stw,ma %r24, 0(%r26) + /* Free lock */ + stw,ma %r20, 0(%sr2,%r20) + #if ENABLE_LWS_DEBUG +@@ -711,9 +706,9 @@ lws_compare_and_swap_2: + nop + + /* 8bit load */ +-4: ldb 0(%sr3,%r25), %r25 ++4: ldb 0(%r25), %r25 + b cas2_lock_start +-5: ldb 0(%sr3,%r24), %r24 ++5: ldb 0(%r24), %r24 + nop + nop + nop +@@ -721,9 +716,9 @@ lws_compare_and_swap_2: + nop + + /* 16bit load */ +-6: ldh 0(%sr3,%r25), %r25 ++6: ldh 0(%r25), %r25 + b cas2_lock_start +-7: ldh 0(%sr3,%r24), %r24 ++7: ldh 0(%r24), %r24 + nop + nop + nop +@@ -731,9 +726,9 @@ lws_compare_and_swap_2: + nop + + /* 32bit load */ +-8: ldw 0(%sr3,%r25), %r25 ++8: ldw 0(%r25), %r25 + b cas2_lock_start +-9: ldw 0(%sr3,%r24), %r24 ++9: ldw 0(%r24), %r24 + nop + nop + nop +@@ -742,14 +737,14 @@ lws_compare_and_swap_2: + + /* 64bit load */ + #ifdef CONFIG_64BIT +-10: ldd 0(%sr3,%r25), %r25 +-11: ldd 0(%sr3,%r24), %r24 ++10: ldd 0(%r25), %r25 ++11: ldd 0(%r24), %r24 + #else +- /* Load new value into r22/r23 - high/low */ +-10: ldw 0(%sr3,%r25), %r22 +-11: ldw 4(%sr3,%r25), %r23 ++ /* Load old value into r22/r23 - high/low */ ++10: ldw 0(%r25), %r22 ++11: ldw 4(%r25), %r23 + /* Load new value into fr4 for atomic store later */ +-12: flddx 0(%sr3,%r24), %fr4 ++12: flddx 0(%r24), %fr4 + #endif + + cas2_lock_start: +@@ -799,30 +794,30 @@ cas2_action: + ldo 1(%r0),%r28 + + /* 8bit CAS */ +-13: ldb,ma 0(%sr3,%r26), %r29 ++13: ldb,ma 0(%r26), %r29 + sub,= %r29, %r25, %r0 + b,n cas2_end +-14: stb,ma %r24, 0(%sr3,%r26) ++14: stb,ma %r24, 0(%r26) + b cas2_end + copy %r0, %r28 + nop + nop + + /* 16bit CAS */ +-15: ldh,ma 0(%sr3,%r26), %r29 ++15: ldh,ma 0(%r26), %r29 + sub,= %r29, %r25, %r0 + b,n cas2_end +-16: sth,ma %r24, 0(%sr3,%r26) ++16: sth,ma %r24, 0(%r26) + b cas2_end + copy %r0, %r28 + nop + nop + + /* 32bit CAS */ +-17: ldw,ma 0(%sr3,%r26), %r29 ++17: ldw,ma 0(%r26), %r29 + sub,= %r29, %r25, %r0 + b,n cas2_end +-18: stw,ma %r24, 0(%sr3,%r26) ++18: stw,ma %r24, 0(%r26) + b cas2_end + copy %r0, %r28 + nop +@@ -830,22 +825,22 @@ cas2_action: + + /* 64bit CAS */ + #ifdef CONFIG_64BIT +-19: ldd,ma 0(%sr3,%r26), %r29 ++19: ldd,ma 0(%r26), %r29 + sub,*= %r29, %r25, %r0 + b,n cas2_end +-20: std,ma %r24, 0(%sr3,%r26) ++20: std,ma %r24, 0(%r26) + copy %r0, %r28 + #else + /* Compare first word */ +-19: ldw,ma 0(%sr3,%r26), %r29 ++19: ldw 0(%r26), %r29 + sub,= %r29, %r22, %r0 + b,n cas2_end + /* Compare second word */ +-20: ldw,ma 4(%sr3,%r26), %r29 ++20: ldw 4(%r26), %r29 + sub,= %r29, %r23, %r0 + b,n cas2_end + /* Perform the store */ +-21: fstdx %fr4, 0(%sr3,%r26) ++21: fstdx %fr4, 0(%r26) + copy %r0, %r28 + #endif + +diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c +index 8f3056cd0399..2516e97c58f1 100644 +--- a/crypto/asymmetric_keys/pkcs7_parser.c ++++ b/crypto/asymmetric_keys/pkcs7_parser.c +@@ -90,6 +90,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) + bool want; + + sinfo = msg->signed_infos; ++ if (!sinfo) ++ goto inconsistent; ++ + if (sinfo->authattrs) { + want = true; + msg->have_authattrs = true; +diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c +index c43c3d2baf73..0d628becf37f 100644 +--- a/drivers/bus/mvebu-mbus.c ++++ b/drivers/bus/mvebu-mbus.c +@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) + if (mbus->hw_io_coherency) + w->mbus_attr |= ATTR_HW_COHERENCY; + w->base = base & DDR_BASE_CS_LOW_MASK; +- w->size = (size | ~DDR_SIZE_MASK) + 1; ++ w->size = (u64)(size | ~DDR_SIZE_MASK) + 1; + } + } + mvebu_mbus_dram_info.num_cs = cs; +diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c +index 9a7e37cf56b0..e1d7373e63e0 100644 +--- a/drivers/clocksource/cs5535-clockevt.c ++++ b/drivers/clocksource/cs5535-clockevt.c +@@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) + /* Turn off the clock (and clear the event) */ + disable_timer(cs5535_event_clock); + +- if (clockevent_state_shutdown(&cs5535_clockevent)) ++ if (clockevent_state_detached(&cs5535_clockevent) || ++ clockevent_state_shutdown(&cs5535_clockevent)) + return IRQ_HANDLED; + + /* Clear the counter */ +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +index 3ef01071f073..103471ff4dc4 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +@@ -40,5 +40,5 @@ int + g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine) + { + return nvkm_xtensa_new_(&g84_bsp, device, index, +- true, 0x103000, pengine); ++ device->chipset != 0x92, 0x103000, pengine); + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +index e04a2296ecd0..5bb7f7e0f11f 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +@@ -240,6 +240,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde) + mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem); + } + ++ mmu->func->flush(vm); ++ + nvkm_memory_del(&pgt); + } + } +diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c +index 639d1a9c8793..1111cb966a44 100644 +--- a/drivers/i2c/busses/i2c-ismt.c ++++ b/drivers/i2c/busses/i2c-ismt.c +@@ -338,12 +338,15 @@ static int ismt_process_desc(const struct ismt_desc *desc, + data->word = dma_buffer[0] | (dma_buffer[1] << 8); + break; + case I2C_SMBUS_BLOCK_DATA: +- case I2C_SMBUS_I2C_BLOCK_DATA: + if (desc->rxbytes != dma_buffer[0] + 1) + return -EMSGSIZE; + + memcpy(data->block, dma_buffer, desc->rxbytes); + break; ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ memcpy(&data->block[1], dma_buffer, desc->rxbytes); ++ data->block[0] = desc->rxbytes; ++ break; + } + return 0; + } +diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c +index 113e64fcd73b..4c6707ecc619 100644 +--- a/drivers/net/can/usb/esd_usb2.c ++++ b/drivers/net/can/usb/esd_usb2.c +@@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, + } + + cf->can_id = id & ESD_IDMASK; +- cf->can_dlc = get_can_dlc(msg->msg.rx.dlc); ++ cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR); + + if (id & ESD_EXTID) + cf->can_id |= CAN_EFF_FLAG; +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index ae5709354546..27e2352fcc42 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -356,6 +356,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) + + gs_free_tx_context(txc); + ++ atomic_dec(&dev->active_tx_urbs); ++ + netif_wake_queue(netdev); + } + +@@ -444,14 +446,6 @@ static void gs_usb_xmit_callback(struct urb *urb) + urb->transfer_buffer_length, + urb->transfer_buffer, + urb->transfer_dma); +- +- atomic_dec(&dev->active_tx_urbs); +- +- if (!netif_device_present(netdev)) +- return; +- +- if (netif_queue_stopped(netdev)) +- netif_wake_queue(netdev); + } + + static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, struct net_device *netdev) +diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +index 99dac9b8a082..c75bfd3f8cb3 100644 +--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +@@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) + } + + static void +-wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, +- u8 len) ++wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events, ++ const u8 *dlys, u8 len) + { + u32 t1_offset, t2_offset; + u8 ctr; +@@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) + static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + { + u16 currband; +- s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; +- s8 *lna1_gain_db = NULL; +- s8 *lna1_gain_db_2 = NULL; +- s8 *lna2_gain_db = NULL; +- s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; +- s8 *tia_gain_db; +- s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; +- s8 *tia_gainbits; +- u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; +- u16 *rfseq_init_gain; ++ static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; ++ const s8 *lna1_gain_db = NULL; ++ const s8 *lna1_gain_db_2 = NULL; ++ const s8 *lna2_gain_db = NULL; ++ static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; ++ const s8 *tia_gain_db; ++ static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; ++ const s8 *tia_gainbits; ++ static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; ++ const u16 *rfseq_init_gain; + u16 init_gaincode; + u16 clip1hi_gaincode; + u16 clip1md_gaincode = 0; +@@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + + if ((freq <= 5080) || (freq == 5825)) { + +- s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 11, 17, 22, 25}; +- s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; ++ static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25}; ++ static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x3e; + lna1_gain_db = lna1A_gain_db_rev7; +@@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + lna2_gain_db = lna2A_gain_db_rev7; + } else if ((freq >= 5500) && (freq <= 5700)) { + +- s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 12, 18, 22, 26}; +- s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; ++ static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; ++ static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; + + crsminu_th = 0x45; + clip1md_gaincode_B = 0x14; +@@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) + lna2_gain_db = lna2A_gain_db_rev7; + } else { + +- s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; +- s8 lna1A_gain_db_2_rev7[] = { +- 12, 18, 22, 26}; +- s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; ++ static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; ++ static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; ++ static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x41; + lna1_gain_db = lna1A_gain_db_rev7; +@@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_RFSEQ_CMD_SET_HPF_BW + }; +- u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; +- s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; +- s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; +- s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; +- s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; +- s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; +- s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; +- s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; +- s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; +- s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; +- s8 *lna1_gain_db = NULL; +- s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; +- s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; +- s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; +- s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; +- s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; +- s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; +- s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; +- s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; +- s8 *lna2_gain_db = NULL; +- s8 tiaG_gain_db[] = { ++ static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; ++ static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; ++ static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; ++ static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; ++ static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; ++ static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; ++ static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; ++ static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; ++ static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; ++ static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; ++ const s8 *lna1_gain_db = NULL; ++ static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; ++ static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; ++ static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; ++ static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; ++ static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; ++ static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; ++ static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; ++ static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; ++ const s8 *lna2_gain_db = NULL; ++ static const s8 tiaG_gain_db[] = { + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; +- s8 tiaA_gain_db[] = { ++ static const s8 tiaA_gain_db[] = { + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; +- s8 tiaA_gain_db_rev4[] = { ++ static const s8 tiaA_gain_db_rev4[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 tiaA_gain_db_rev5[] = { ++ static const s8 tiaA_gain_db_rev5[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 tiaA_gain_db_rev6[] = { ++ static const s8 tiaA_gain_db_rev6[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; +- s8 *tia_gain_db; +- s8 tiaG_gainbits[] = { ++ const s8 *tia_gain_db; ++ static const s8 tiaG_gainbits[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; +- s8 tiaA_gainbits[] = { ++ static const s8 tiaA_gainbits[] = { + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; +- s8 tiaA_gainbits_rev4[] = { ++ static const s8 tiaA_gainbits_rev4[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 tiaA_gainbits_rev5[] = { ++ static const s8 tiaA_gainbits_rev5[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 tiaA_gainbits_rev6[] = { ++ static const s8 tiaA_gainbits_rev6[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; +- s8 *tia_gainbits; +- s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; +- s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; +- u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; +- u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; +- u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; +- u16 rfseqG_init_gain_rev5_elna[] = { ++ const s8 *tia_gainbits; ++ static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; ++ static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; ++ static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; ++ static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; ++ static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; ++ static const u16 rfseqG_init_gain_rev5_elna[] = { + 0x013f, 0x013f, 0x013f, 0x013f }; +- u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; +- u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; +- u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; +- u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; +- u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; +- u16 rfseqA_init_gain_rev4_elna[] = { ++ static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; ++ static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; ++ static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; ++ static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; ++ static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; ++ static const u16 rfseqA_init_gain_rev4_elna[] = { + 0x314f, 0x314f, 0x314f, 0x314f }; +- u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; +- u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; +- u16 *rfseq_init_gain; ++ static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; ++ static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; ++ const u16 *rfseq_init_gain; + u16 initG_gaincode = 0x627e; + u16 initG_gaincode_rev4 = 0x527e; + u16 initG_gaincode_rev5 = 0x427e; +@@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + u16 clip1mdA_gaincode_rev6 = 0x2084; + u16 clip1md_gaincode = 0; + u16 clip1loG_gaincode = 0x0074; +- u16 clip1loG_gaincode_rev5[] = { ++ static const u16 clip1loG_gaincode_rev5[] = { + 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c + }; +- u16 clip1loG_gaincode_rev6[] = { ++ static const u16 clip1loG_gaincode_rev6[] = { + 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e + }; + u16 clip1loG_gaincode_rev6_224B0 = 0x1074; +@@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) + + static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + { +- u8 rfseq_rx2tx_events[] = { ++ static const u8 rfseq_rx2tx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_TR_SWITCH, +@@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_EXT_PA + }; + u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; +- u8 rfseq_tx2rx_events[] = { ++ static const u8 rfseq_tx2rx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_EXT_PA, + NPHY_RFSEQ_CMD_TX_GAIN, +@@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS + }; +- u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; +- u8 rfseq_tx2rx_events_rev3[] = { ++ static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; ++ static const u8 rfseq_tx2rx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_EXT_PA, + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_TX_GAIN, +@@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_REV3_RFSEQ_CMD_END + }; +- u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; ++ static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; + u8 rfseq_rx2tx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, +@@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + }; + u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; + +- u8 rfseq_rx2tx_events_rev3_ipa[] = { ++ static const u8 rfseq_rx2tx_events_rev3_ipa[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, + NPHY_REV3_RFSEQ_CMD_TR_SWITCH, +@@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_END + }; +- u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; +- u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; ++ static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; ++ static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; + + s16 alpha0, alpha1, alpha2; + s16 beta0, beta1, beta2; + u32 leg_data_weights, ht_data_weights, nss1_data_weights, + stbc_data_weights; + u8 chan_freq_range = 0; +- u16 dac_control = 0x0002; ++ static const u16 dac_control = 0x0002; + u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; + u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; + u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; +@@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 *aux_adc_gain; +- u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; +- u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; ++ static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; ++ static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; + s32 min_nvar_val = 0x18d; + s32 min_nvar_offset_6mbps = 20; + u8 pdetrange; +@@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) + u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; +- u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; +- u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; +- u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; ++ static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; ++ static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; ++ static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + u16 ipalvlshift_3p3_war_en = 0; + u16 rccal_bcap_val, rccal_scap_val; + u16 rccal_tx20_11b_bcap = 0; +@@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) + u16 bbmult; + u16 tblentry; + +- struct nphy_txiqcal_ladder ladder_lo[] = { ++ static const struct nphy_txiqcal_ladder ladder_lo[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, + {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} + }; + +- struct nphy_txiqcal_ladder ladder_iq[] = { ++ static const struct nphy_txiqcal_ladder ladder_iq[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, + {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} +@@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, + u16 cal_gain[2]; + struct nphy_iqcal_params cal_params[2]; + u32 tbl_len; +- void *tbl_ptr; ++ const void *tbl_ptr; + bool ladder_updated[2]; + u8 mphase_cal_lastphase = 0; + int bcmerror = 0; + bool phyhang_avoid_state = false; + +- u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { ++ static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { + 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, + 0x1902, + 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, + 0x6407 + }; + +- u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { ++ static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { + 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, + 0x3200, + 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, + 0x6407 + }; + +- u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { ++ static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { + 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, + 0x1202, + 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, + 0x4707 + }; + +- u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { ++ static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { + 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, + 0x2300, + 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, + 0x4707 + }; + +- u16 tbl_tx_iqlo_cal_startcoefs[] = { ++ static const u16 tbl_tx_iqlo_cal_startcoefs[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + +- u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { + 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, + 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 + }; + +- u16 tbl_tx_iqlo_cal_cmds_recal[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_recal[] = { + 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, + 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 + }; + +- u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + +- u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, + 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 + }; + +- u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { ++ static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { + 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, + 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 + }; +diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +index c2103e7a8132..bbb789f8990b 100644 +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +@@ -1127,7 +1127,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr) + } + if (0 == tmp) { + read_addr = REG_DBI_RDATA + addr % 4; +- ret = rtl_read_byte(rtlpriv, read_addr); ++ ret = rtl_read_word(rtlpriv, read_addr); + } + return ret; + } +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index df96f5f88c15..3f6bb3fff890 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1762,6 +1762,9 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */ + .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ + }, ++ { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ ++ .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ ++ }, + + { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ + .driver_info = CLEAR_HALT_CONDITIONS, +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index d9d048fc9082..5172bec612eb 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -926,10 +926,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) + for (i = 0; i < num; i++) { + buffer += length; + cap = (struct usb_dev_cap_header *)buffer; +- length = cap->bLength; + +- if (total_len < length) ++ if (total_len < sizeof(*cap) || total_len < cap->bLength) { ++ dev->bos->desc->bNumDeviceCaps = i; + break; ++ } ++ length = cap->bLength; + total_len -= length; + + if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index bd9419213d06..873ba02d59e6 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1417,11 +1417,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + totlen += isopkt[u].length; + } + u *= sizeof(struct usb_iso_packet_descriptor); +- if (totlen <= uurb->buffer_length) +- uurb->buffer_length = totlen; +- else +- WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d", +- totlen, uurb->buffer_length); ++ uurb->buffer_length = totlen; + break; + + default: +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 51bba58c0c3b..22e61786354a 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2656,13 +2656,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, + if (!(portstatus & USB_PORT_STAT_CONNECTION)) + return -ENOTCONN; + +- /* bomb out completely if the connection bounced. A USB 3.0 +- * connection may bounce if multiple warm resets were issued, ++ /* Retry if connect change is set but status is still connected. ++ * A USB 3.0 connection may bounce if multiple warm resets were issued, + * but the device may have successfully re-connected. Ignore it. + */ + if (!hub_is_superspeed(hub->hdev) && +- (portchange & USB_PORT_STAT_C_CONNECTION)) +- return -ENOTCONN; ++ (portchange & USB_PORT_STAT_C_CONNECTION)) { ++ usb_clear_port_feature(hub->hdev, port1, ++ USB_PORT_FEAT_C_CONNECTION); ++ return -EAGAIN; ++ } + + if (!(portstatus & USB_PORT_STAT_ENABLE)) + return -EBUSY; +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 82806e311202..a6aaf2f193a4 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -221,6 +221,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Corsair Strafe RGB */ + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + ++ /* MIDI keyboard WORLDE MINI */ ++ { USB_DEVICE(0x1c75, 0x0204), .driver_info = ++ USB_QUIRK_CONFIG_INTF_STRINGS }, ++ + /* Acer C120 LED Projector */ + { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, + +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index 00eed5d66fda..06d83825923a 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -877,7 +877,7 @@ b_host: + */ + if (int_usb & MUSB_INTR_RESET) { + handled = IRQ_HANDLED; +- if (devctl & MUSB_DEVCTL_HM) { ++ if (is_host_active(musb)) { + /* + * When BABBLE happens what we can depends on which + * platform MUSB is running, because some platforms +@@ -887,9 +887,7 @@ b_host: + * drop the session. + */ + dev_err(musb->controller, "Babble\n"); +- +- if (is_host_active(musb)) +- musb_recover_from_babble(musb); ++ musb_recover_from_babble(musb); + } else { + dev_dbg(musb->controller, "BUS RESET as %s\n", + usb_otg_state_string(musb->xceiv->otg->state)); +diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c +index d9b0dc461439..2d3be66fb563 100644 +--- a/drivers/usb/musb/sunxi.c ++++ b/drivers/usb/musb/sunxi.c +@@ -320,6 +320,8 @@ static int sunxi_musb_exit(struct musb *musb) + if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) + sunxi_sram_release(musb->controller->parent); + ++ devm_usb_put_phy(glue->dev, glue->xceiv); ++ + return 0; + } + +diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c +index 39e683096e94..45182c65fa1f 100644 +--- a/drivers/usb/serial/metro-usb.c ++++ b/drivers/usb/serial/metro-usb.c +@@ -45,6 +45,7 @@ struct metrousb_private { + static const struct usb_device_id id_table[] = { + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) }, /* MS7820 */ + { }, /* Terminating entry. */ + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c +index 505f8afde57c..9a1bc638abce 100644 +--- a/fs/ext4/crypto_key.c ++++ b/fs/ext4/crypto_key.c +@@ -204,6 +204,12 @@ int ext4_get_encryption_info(struct inode *inode) + } + down_read(&keyring_key->sem); + ukp = user_key_payload(keyring_key); ++ if (!ukp) { ++ /* key was revoked before we acquired its semaphore */ ++ res = -EKEYREVOKED; ++ up_read(&keyring_key->sem); ++ goto out; ++ } + if (ukp->datalen != sizeof(struct ext4_encryption_key)) { + res = -EINVAL; + up_read(&keyring_key->sem); +diff --git a/fs/f2fs/crypto.c b/fs/f2fs/crypto.c +index 4a62ef14e932..d879c6c846b7 100644 +--- a/fs/f2fs/crypto.c ++++ b/fs/f2fs/crypto.c +@@ -362,7 +362,6 @@ static int f2fs_page_crypto(struct f2fs_crypto_ctx *ctx, + else + res = crypto_ablkcipher_encrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { +- BUG_ON(req->base.data != &ecr); + wait_for_completion(&ecr.completion); + res = ecr.res; + } +diff --git a/fs/f2fs/crypto_fname.c b/fs/f2fs/crypto_fname.c +index 38349ed5ea51..0fce444dd5ae 100644 +--- a/fs/f2fs/crypto_fname.c ++++ b/fs/f2fs/crypto_fname.c +@@ -124,7 +124,6 @@ static int f2fs_fname_encrypt(struct inode *inode, + ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv); + res = crypto_ablkcipher_encrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { +- BUG_ON(req->base.data != &ecr); + wait_for_completion(&ecr.completion); + res = ecr.res; + } +@@ -180,7 +179,6 @@ static int f2fs_fname_decrypt(struct inode *inode, + ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv); + res = crypto_ablkcipher_decrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { +- BUG_ON(req->base.data != &ecr); + wait_for_completion(&ecr.completion); + res = ecr.res; + } +diff --git a/fs/f2fs/crypto_key.c b/fs/f2fs/crypto_key.c +index 18595d7a0efc..7e62889a1d3d 100644 +--- a/fs/f2fs/crypto_key.c ++++ b/fs/f2fs/crypto_key.c +@@ -75,7 +75,6 @@ static int f2fs_derive_key_aes(char deriving_key[F2FS_AES_128_ECB_KEY_SIZE], + F2FS_AES_256_XTS_KEY_SIZE, NULL); + res = crypto_ablkcipher_encrypt(req); + if (res == -EINPROGRESS || res == -EBUSY) { +- BUG_ON(req->base.data != &ecr); + wait_for_completion(&ecr.completion); + res = ecr.res; + } +@@ -189,18 +188,38 @@ int f2fs_get_encryption_info(struct inode *inode) + keyring_key = NULL; + goto out; + } +- BUG_ON(keyring_key->type != &key_type_logon); ++ if (keyring_key->type != &key_type_logon) { ++ printk_once(KERN_WARNING "f2fs: key type must be logon\n"); ++ res = -ENOKEY; ++ goto out; ++ } ++ down_read(&keyring_key->sem); + ukp = user_key_payload(keyring_key); ++ if (!ukp) { ++ /* key was revoked before we acquired its semaphore */ ++ res = -EKEYREVOKED; ++ up_read(&keyring_key->sem); ++ goto out; ++ } + if (ukp->datalen != sizeof(struct f2fs_encryption_key)) { + res = -EINVAL; ++ up_read(&keyring_key->sem); + goto out; + } + master_key = (struct f2fs_encryption_key *)ukp->data; + BUILD_BUG_ON(F2FS_AES_128_ECB_KEY_SIZE != + F2FS_KEY_DERIVATION_NONCE_SIZE); +- BUG_ON(master_key->size != F2FS_AES_256_XTS_KEY_SIZE); ++ if (master_key->size != F2FS_AES_256_XTS_KEY_SIZE) { ++ printk_once(KERN_WARNING ++ "f2fs: key size incorrect: %d\n", ++ master_key->size); ++ res = -ENOKEY; ++ up_read(&keyring_key->sem); ++ goto out; ++ } + res = f2fs_derive_key_aes(ctx.nonce, master_key->raw, + raw_key); ++ up_read(&keyring_key->sem); + if (res) + goto out; + +diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c +index 4b449d263333..01eed94b01ea 100644 +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1541,12 +1541,18 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) + sizeof(policy))) + return -EFAULT; + ++ err = mnt_want_write_file(filp); ++ if (err) ++ return err; ++ + mutex_lock(&inode->i_mutex); + + err = f2fs_process_policy(&policy, inode); + + mutex_unlock(&inode->i_mutex); + ++ mnt_drop_write_file(filp); ++ + return err; + #else + return -EOPNOTSUPP; +diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c +index 6b028b7c4250..926580a85153 100644 +--- a/fs/fscache/object-list.c ++++ b/fs/fscache/object-list.c +@@ -330,6 +330,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data) + rcu_read_lock(); + + confkey = user_key_payload(key); ++ if (!confkey) { ++ /* key was revoked */ ++ rcu_read_unlock(); ++ key_put(key); ++ goto no_config; ++ } ++ + buf = confkey->data; + + for (len = confkey->datalen - 1; len >= 0; len--) { +diff --git a/include/linux/key.h b/include/linux/key.h +index dcc115e8dd03..af071ca73079 100644 +--- a/include/linux/key.h ++++ b/include/linux/key.h +@@ -126,6 +126,11 @@ static inline bool is_key_possessed(const key_ref_t key_ref) + return (unsigned long) key_ref & 1UL; + } + ++enum key_state { ++ KEY_IS_UNINSTANTIATED, ++ KEY_IS_POSITIVE, /* Positively instantiated */ ++}; ++ + /*****************************************************************************/ + /* + * authentication token / access credential / keyring +@@ -157,6 +162,7 @@ struct key { + * - may not match RCU dereferenced payload + * - payload should contain own length + */ ++ short state; /* Key state (+) or rejection error (-) */ + + #ifdef KEY_DEBUGGING + unsigned magic; +@@ -165,19 +171,17 @@ struct key { + #endif + + unsigned long flags; /* status flags (change with bitops) */ +-#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */ +-#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */ +-#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */ +-#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ +-#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ +-#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ +-#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ +-#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ +-#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ +-#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ +-#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ +-#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ +-#define KEY_FLAG_UID_KEYRING 12 /* set if key is a user or user session keyring */ ++#define KEY_FLAG_DEAD 0 /* set if key type has been deleted */ ++#define KEY_FLAG_REVOKED 1 /* set if key had been revoked */ ++#define KEY_FLAG_IN_QUOTA 2 /* set if key consumes quota */ ++#define KEY_FLAG_USER_CONSTRUCT 3 /* set if key is being constructed in userspace */ ++#define KEY_FLAG_ROOT_CAN_CLEAR 4 /* set if key can be cleared by root without permission */ ++#define KEY_FLAG_INVALIDATED 5 /* set if key has been invalidated */ ++#define KEY_FLAG_TRUSTED 6 /* set if key is trusted */ ++#define KEY_FLAG_TRUSTED_ONLY 7 /* set if keyring only accepts links to trusted keys */ ++#define KEY_FLAG_BUILTIN 8 /* set if key is builtin */ ++#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ ++#define KEY_FLAG_UID_KEYRING 10 /* set if key is a user or user session keyring */ + + /* the key type and key description string + * - the desc is used to match a key against search criteria +@@ -203,7 +207,6 @@ struct key { + struct list_head name_link; + struct assoc_array keys; + }; +- int reject_error; + }; + }; + +@@ -319,17 +322,27 @@ extern void key_set_timeout(struct key *, unsigned); + #define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */ + #define KEY_NEED_ALL 0x3f /* All the above permissions */ + ++static inline short key_read_state(const struct key *key) ++{ ++ /* Barrier versus mark_key_instantiated(). */ ++ return smp_load_acquire(&key->state); ++} ++ + /** +- * key_is_instantiated - Determine if a key has been positively instantiated ++ * key_is_positive - Determine if a key has been positively instantiated + * @key: The key to check. + * + * Return true if the specified key has been positively instantiated, false + * otherwise. + */ +-static inline bool key_is_instantiated(const struct key *key) ++static inline bool key_is_positive(const struct key *key) ++{ ++ return key_read_state(key) == KEY_IS_POSITIVE; ++} ++ ++static inline bool key_is_negative(const struct key *key) + { +- return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && +- !test_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ return key_read_state(key) < 0; + } + + #define rcu_dereference_key(KEY) \ +diff --git a/include/linux/mbus.h b/include/linux/mbus.h +index 1f7bc630d225..71a5a56b0bba 100644 +--- a/include/linux/mbus.h ++++ b/include/linux/mbus.h +@@ -29,8 +29,8 @@ struct mbus_dram_target_info + struct mbus_dram_window { + u8 cs_index; + u8 mbus_attr; +- u32 base; +- u32 size; ++ u64 base; ++ u64 size; + } cs[4]; + }; + +diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c +index 750ed601ddf7..8620fd01b3d0 100644 +--- a/kernel/sched/auto_group.c ++++ b/kernel/sched/auto_group.c +@@ -111,14 +111,11 @@ bool task_wants_autogroup(struct task_struct *p, struct task_group *tg) + { + if (tg != &root_task_group) + return false; +- + /* +- * We can only assume the task group can't go away on us if +- * autogroup_move_group() can see us on ->thread_group list. ++ * If we race with autogroup_move_group() the caller can use the old ++ * value of signal->autogroup but in this case sched_move_task() will ++ * be called again before autogroup_kref_put(). + */ +- if (p->flags & PF_EXITING) +- return false; +- + return true; + } + +@@ -138,13 +135,17 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) + } + + p->signal->autogroup = autogroup_kref_get(ag); +- +- if (!READ_ONCE(sysctl_sched_autogroup_enabled)) +- goto out; +- ++ /* ++ * We can't avoid sched_move_task() after we changed signal->autogroup, ++ * this process can already run with task_group() == prev->tg or we can ++ * race with cgroup code which can read autogroup = prev under rq->lock. ++ * In the latter case for_each_thread() can not miss a migrating thread, ++ * cpu_cgroup_attach() must not be possible after cgroup_exit() and it ++ * can't be removed from thread list, we hold ->siglock. ++ */ + for_each_thread(p, t) + sched_move_task(t); +-out: ++ + unlock_task_sighand(p, &flags); + autogroup_kref_put(prev); + } +diff --git a/lib/digsig.c b/lib/digsig.c +index 07be6c1ef4e2..00c5c8179393 100644 +--- a/lib/digsig.c ++++ b/lib/digsig.c +@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key, + down_read(&key->sem); + ukp = user_key_payload(key); + ++ if (!ukp) { ++ /* key was revoked before we acquired its semaphore */ ++ err = -EKEYREVOKED; ++ goto err1; ++ } ++ + if (ukp->datalen < sizeof(*pkh)) + goto err1; + +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index c79b85eb4d4c..6abc5012200b 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data) + static void dns_resolver_describe(const struct key *key, struct seq_file *m) + { + seq_puts(m, key->description); +- if (key_is_instantiated(key)) { ++ if (key_is_positive(key)) { + int err = PTR_ERR(key->payload.data[dns_key_error]); + + if (err) +diff --git a/security/keys/big_key.c b/security/keys/big_key.c +index 907c1522ee46..08c4cc5c2973 100644 +--- a/security/keys/big_key.c ++++ b/security/keys/big_key.c +@@ -138,7 +138,7 @@ void big_key_revoke(struct key *key) + + /* clear the quota */ + key_payload_reserve(key, 0); +- if (key_is_instantiated(key) && ++ if (key_is_positive(key) && + (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) + vfs_truncate(path, 0); + } +@@ -170,7 +170,7 @@ void big_key_describe(const struct key *key, struct seq_file *m) + + seq_puts(m, key->description); + +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, ": %zu [%s]", + datalen, + datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 31898856682e..ce295c0c1da0 100644 +--- a/security/keys/encrypted-keys/encrypted.c ++++ b/security/keys/encrypted-keys/encrypted.c +@@ -315,6 +315,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k + + down_read(&ukey->sem); + upayload = user_key_payload(ukey); ++ if (!upayload) { ++ /* key was revoked before we acquired its semaphore */ ++ up_read(&ukey->sem); ++ key_put(ukey); ++ ukey = ERR_PTR(-EKEYREVOKED); ++ goto error; ++ } + *master_key = upayload->data; + *master_keylen = upayload->datalen; + error: +@@ -845,7 +852,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) + size_t datalen = prep->datalen; + int ret = 0; + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_negative(key)) + return -ENOKEY; + if (datalen <= 0 || datalen > 32767 || !prep->data) + return -EINVAL; +diff --git a/security/keys/gc.c b/security/keys/gc.c +index 9cb4fe4478a1..1659094d684d 100644 +--- a/security/keys/gc.c ++++ b/security/keys/gc.c +@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) + while (!list_empty(keys)) { + struct key *key = + list_entry(keys->next, struct key, graveyard_link); ++ short state = key->state; ++ + list_del(&key->graveyard_link); + + kdebug("- %u", key->serial); + key_check(key); + + /* Throw away the key data if the key is instantiated */ +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && +- !test_bit(KEY_FLAG_NEGATIVE, &key->flags) && +- key->type->destroy) ++ if (state == KEY_IS_POSITIVE && key->type->destroy) + key->type->destroy(key); + + security_key_free(key); +@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys) + } + + atomic_dec(&key->user->nkeys); +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) ++ if (state != KEY_IS_UNINSTANTIATED) + atomic_dec(&key->user->nikeys); + + key_user_put(key->user); +diff --git a/security/keys/key.c b/security/keys/key.c +index 51d23c623424..4d971bf88ac3 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -395,6 +395,18 @@ int key_payload_reserve(struct key *key, size_t datalen) + } + EXPORT_SYMBOL(key_payload_reserve); + ++/* ++ * Change the key state to being instantiated. ++ */ ++static void mark_key_instantiated(struct key *key, int reject_error) ++{ ++ /* Commit the payload before setting the state; barrier versus ++ * key_read_state(). ++ */ ++ smp_store_release(&key->state, ++ (reject_error < 0) ? reject_error : KEY_IS_POSITIVE); ++} ++ + /* + * Instantiate a key and link it into the target keyring atomically. Must be + * called with the target keyring's semaphore writelocked. The target key's +@@ -418,14 +430,14 @@ static int __key_instantiate_and_link(struct key *key, + mutex_lock(&key_construction_mutex); + + /* can't instantiate twice */ +- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state == KEY_IS_UNINSTANTIATED) { + /* instantiate the key */ + ret = key->type->instantiate(key, prep); + + if (ret == 0) { + /* mark the key as being instantiated */ + atomic_inc(&key->user->nikeys); +- set_bit(KEY_FLAG_INSTANTIATED, &key->flags); ++ mark_key_instantiated(key, 0); + + if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) + awaken = 1; +@@ -553,13 +565,10 @@ int key_reject_and_link(struct key *key, + mutex_lock(&key_construction_mutex); + + /* can't instantiate twice */ +- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state == KEY_IS_UNINSTANTIATED) { + /* mark the key as being negatively instantiated */ + atomic_inc(&key->user->nikeys); +- key->reject_error = -error; +- smp_wmb(); +- set_bit(KEY_FLAG_NEGATIVE, &key->flags); +- set_bit(KEY_FLAG_INSTANTIATED, &key->flags); ++ mark_key_instantiated(key, -error); + now = current_kernel_time(); + key->expiry = now.tv_sec + timeout; + key_schedule_gc(key->expiry + key_gc_delay); +@@ -731,8 +740,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, + + ret = key->type->update(key, prep); + if (ret == 0) +- /* updating a negative key instantiates it */ +- clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ /* Updating a negative key positively instantiates it */ ++ mark_key_instantiated(key, 0); + + up_write(&key->sem); + +@@ -907,6 +916,16 @@ error: + */ + __key_link_end(keyring, &index_key, edit); + ++ key = key_ref_to_ptr(key_ref); ++ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) { ++ ret = wait_for_key_construction(key, true); ++ if (ret < 0) { ++ key_ref_put(key_ref); ++ key_ref = ERR_PTR(ret); ++ goto error_free_prep; ++ } ++ } ++ + key_ref = __key_update(key_ref, &prep); + goto error_free_prep; + } +@@ -957,8 +976,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) + + ret = key->type->update(key, &prep); + if (ret == 0) +- /* updating a negative key instantiates it */ +- clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ++ /* Updating a negative key positively instantiates it */ ++ mark_key_instantiated(key, 0); + + up_write(&key->sem); + +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index a009dc66eb8f..2e741e1a8712 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -738,10 +738,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) + + key = key_ref_to_ptr(key_ref); + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { +- ret = -ENOKEY; +- goto error2; +- } ++ ret = key_read_state(key); ++ if (ret < 0) ++ goto error2; /* Negatively instantiated */ + + /* see if we can read it directly */ + ret = key_permission(key_ref, KEY_NEED_READ); +@@ -873,7 +872,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) + atomic_dec(&key->user->nkeys); + atomic_inc(&newowner->nkeys); + +- if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { ++ if (key->state != KEY_IS_UNINSTANTIATED) { + atomic_dec(&key->user->nikeys); + atomic_inc(&newowner->nikeys); + } +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index 0c8dd4fbe130..ef828238cdc0 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -407,7 +407,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) + else + seq_puts(m, "[anon]"); + +- if (key_is_instantiated(keyring)) { ++ if (key_is_positive(keyring)) { + if (keyring->keys.nr_leaves_on_tree != 0) + seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree); + else +@@ -522,7 +522,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) + { + struct keyring_search_context *ctx = iterator_data; + const struct key *key = keyring_ptr_to_key(object); +- unsigned long kflags = key->flags; ++ unsigned long kflags = READ_ONCE(key->flags); ++ short state = READ_ONCE(key->state); + + kenter("{%d}", key->serial); + +@@ -566,9 +567,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) + + if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { + /* we set a different error code if we pass a negative key */ +- if (kflags & (1 << KEY_FLAG_NEGATIVE)) { +- smp_rmb(); +- ctx->result = ERR_PTR(key->reject_error); ++ if (state < 0) { ++ ctx->result = ERR_PTR(state); + kleave(" = %d [neg]", ctx->skipped_ret); + goto skipped; + } +diff --git a/security/keys/proc.c b/security/keys/proc.c +index b9f531c9e4fa..036128682463 100644 +--- a/security/keys/proc.c ++++ b/security/keys/proc.c +@@ -182,6 +182,7 @@ static int proc_keys_show(struct seq_file *m, void *v) + unsigned long timo; + key_ref_t key_ref, skey_ref; + char xbuf[16]; ++ short state; + int rc; + + struct keyring_search_context ctx = { +@@ -240,17 +241,19 @@ static int proc_keys_show(struct seq_file *m, void *v) + sprintf(xbuf, "%luw", timo / (60*60*24*7)); + } + ++ state = key_read_state(key); ++ + #define showflag(KEY, LETTER, FLAG) \ + (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') + + seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", + key->serial, +- showflag(key, 'I', KEY_FLAG_INSTANTIATED), ++ state != KEY_IS_UNINSTANTIATED ? 'I' : '-', + showflag(key, 'R', KEY_FLAG_REVOKED), + showflag(key, 'D', KEY_FLAG_DEAD), + showflag(key, 'Q', KEY_FLAG_IN_QUOTA), + showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), +- showflag(key, 'N', KEY_FLAG_NEGATIVE), ++ state < 0 ? 'N' : '-', + showflag(key, 'i', KEY_FLAG_INVALIDATED), + atomic_read(&key->usage), + xbuf, +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 7dd050f24261..ac1d5b2b1626 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -727,7 +727,7 @@ try_again: + + ret = -EIO; + if (!(lflags & KEY_LOOKUP_PARTIAL) && +- !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) ++ key_read_state(key) == KEY_IS_UNINSTANTIATED) + goto invalid_key; + + /* check the permissions */ +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index c7a117c9a8f3..2ce733342b5a 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -594,10 +594,9 @@ int wait_for_key_construction(struct key *key, bool intr) + intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); + if (ret) + return -ERESTARTSYS; +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { +- smp_rmb(); +- return key->reject_error; +- } ++ ret = key_read_state(key); ++ if (ret < 0) ++ return ret; + return key_validate(key); + } + EXPORT_SYMBOL(wait_for_key_construction); +diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c +index 4f0f112fe276..217775fcd0f3 100644 +--- a/security/keys/request_key_auth.c ++++ b/security/keys/request_key_auth.c +@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key, + + seq_puts(m, "key:"); + seq_puts(m, key->description); +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); + } + +diff --git a/security/keys/trusted.c b/security/keys/trusted.c +index 16dec53184b6..509aedcf8310 100644 +--- a/security/keys/trusted.c ++++ b/security/keys/trusted.c +@@ -1014,7 +1014,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) + char *datablob; + int ret = 0; + +- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_negative(key)) + return -ENOKEY; + p = key->payload.data[0]; + if (!p->migratable) +diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c +index 8705d79b2c6f..eba8a516ee9e 100644 +--- a/security/keys/user_defined.c ++++ b/security/keys/user_defined.c +@@ -120,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) + + if (ret == 0) { + /* attach the new data, displacing the old */ +- if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) ++ if (key_is_positive(key)) + zap = key->payload.data[0]; + else + zap = NULL; +@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(user_destroy); + void user_describe(const struct key *key, struct seq_file *m) + { + seq_puts(m, key->description); +- if (key_is_instantiated(key)) ++ if (key_is_positive(key)) + seq_printf(m, ": %u", key->datalen); + } + +diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c +index 12ba83367b1b..ba5752ee9af3 100644 +--- a/sound/core/seq/seq_lock.c ++++ b/sound/core/seq/seq_lock.c +@@ -23,8 +23,6 @@ + #include + #include "seq_lock.h" + +-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) +- + /* wait until all locks are released */ + void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + { +@@ -42,5 +40,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) + } + + EXPORT_SYMBOL(snd_use_lock_sync_helper); +- +-#endif +diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h +index 54044bc2c9ef..ac38031c370e 100644 +--- a/sound/core/seq/seq_lock.h ++++ b/sound/core/seq/seq_lock.h +@@ -3,8 +3,6 @@ + + #include + +-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) +- + typedef atomic_t snd_use_lock_t; + + /* initialize lock */ +@@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t; + void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line); + #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__) + +-#else /* SMP || CONFIG_SND_DEBUG */ +- +-typedef spinlock_t snd_use_lock_t; /* dummy */ +-#define snd_use_lock_init(lockp) /**/ +-#define snd_use_lock_use(lockp) /**/ +-#define snd_use_lock_free(lockp) /**/ +-#define snd_use_lock_sync(lockp) /**/ +- +-#endif /* SMP || CONFIG_SND_DEBUG */ +- + #endif /* __SND_SEQ_LOCK_H */ +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index 83741887faa1..3324f98c35f6 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -1755,7 +1755,7 @@ static int get_kctl_0dB_offset(struct hda_codec *codec, + return -1; + if (*step_to_check && *step_to_check != step) { + codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n", +-- *step_to_check, step); ++ *step_to_check, step); + return -1; + } + *step_to_check = step; +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 1cc20d138dae..9c5368e7ee23 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1305,6 +1305,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, + case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ + case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ + case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ ++ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ + if (fp->altsetting == 2) + return SNDRV_PCM_FMTBIT_DSD_U32_BE; + break; diff --git a/patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled b/patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0001-gpio-mvebu-Add-limited-PWM-support.patch.disabled rename to patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled diff --git a/patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled b/patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0002-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled rename to patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled diff --git a/patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch b/patch/kernel/mvebu-default/92-libata-add-ledtrig-support.patch similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0004-libata-add-ledtrig-support.patch rename to patch/kernel/mvebu-default/92-libata-add-ledtrig-support.patch diff --git a/patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch b/patch/kernel/mvebu-default/93-Enable-ATA-port-LED-trigger.patch similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0005-Enable-ATA-port-LED-trigger.patch rename to patch/kernel/mvebu-default/93-Enable-ATA-port-LED-trigger.patch diff --git a/patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled b/patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0003-ARM-mvebu-Enable-SENSORS_PWM_FAN-in-defconfig.patch.disabled rename to patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled diff --git a/patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch similarity index 100% rename from patch/kernel/mvebu-default/board_helios4/0006-helios4-device-tree.patch rename to patch/kernel/mvebu-default/95-helios4-device-tree.patch diff --git a/patch/kernel/mvebu-default/board_clearfogbase/add-dtb-file-for-backwards-compatibility.patch b/patch/kernel/mvebu-default/add-dtb-file-for-backwards-compatibility.patch similarity index 97% rename from patch/kernel/mvebu-default/board_clearfogbase/add-dtb-file-for-backwards-compatibility.patch rename to patch/kernel/mvebu-default/add-dtb-file-for-backwards-compatibility.patch index b3f11fb83..4e636de3d 100644 --- a/patch/kernel/mvebu-default/board_clearfogbase/add-dtb-file-for-backwards-compatibility.patch +++ b/patch/kernel/mvebu-default/add-dtb-file-for-backwards-compatibility.patch @@ -7,9 +7,9 @@ index face816..9dc5e06 100644 armada-388-clearfog-base.dtb \ armada-388-clearfog-pro.dtb \ + armada-388-clearfog.dtb \ + armada-388-helios4.dtb \ armada-388-db.dtb \ armada-388-gp.dtb \ - armada-388-rd.dtb diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts new file mode 100644 index 0000000..7d906da diff --git a/patch/kernel/mvebu-default/board_clearfogbase/add-spi-flash.patch b/patch/kernel/mvebu-default/add-spi-flash.patch similarity index 100% rename from patch/kernel/mvebu-default/board_clearfogbase/add-spi-flash.patch rename to patch/kernel/mvebu-default/add-spi-flash.patch diff --git a/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch b/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch deleted file mode 100644 index b3f11fb83..000000000 --- a/patch/kernel/mvebu-default/board_clearfogpro/add-dtb-file-for-backwards-compatibility.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index face816..9dc5e06 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -751,6 +751,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ - armada-385-linksys-cobra.dtb \ - armada-388-clearfog-base.dtb \ - armada-388-clearfog-pro.dtb \ -+ armada-388-clearfog.dtb \ - armada-388-db.dtb \ - armada-388-gp.dtb \ - armada-388-rd.dtb -diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts -new file mode 100644 -index 0000000..7d906da ---- /dev/null -+++ b/arch/arm/boot/dts/armada-388-clearfog.dts -@@ -0,0 +1,11 @@ -+/* -+ * Device Tree file for backwards compatibility with old file name expected by boot script -+ * -+ * This file is distributed in the hope that it will be useful -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include "armada-388-clearfog-pro.dts" diff --git a/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch b/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch deleted file mode 100644 index 4dd79d3d0..000000000 --- a/patch/kernel/mvebu-default/board_clearfogpro/add-spi-flash.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi -index 1307e83e..e019ca23 100644 ---- a/arch/arm/boot/dts/armada-388-clearfog.dtsi -+++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi -@@ -263,7 +263,28 @@ - compatible = "w25q32", "jedec,spi-nor"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <3000000>; -- status = "enabled"; -+ status = "okay"; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x0 0x100000>; -+ }; -+ -+ partition@100000 { -+ label = "env"; -+ reg = <0x100000 0x100000>; -+ }; -+ -+ partition@200000 { -+ label = "data"; -+ reg = <0x200000 0x200000>; -+ }; -+ }; - }; - }; - From 768e85abb160f52e6343b71560e289e0019676a4 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Wed, 27 Dec 2017 02:20:35 +0800 Subject: [PATCH 03/20] Various Helios4 device tree changes - Fixed wrong gpio assigned to fault led & pwm fan due to old schematic reference - Removes unrelated SDIO option - Increase i2c0 clock, refer to http://git.arm.linux.org.uk/cgit/linux- arm.git/commit/?h=clearfog-4.9&id=46d963450400eebf60a8c3568aa6ccaf4516bcff - Production board use 2GB ECC memory - Reassign IO expander INT pin - Added PHY0 INT --- .../95-helios4-device-tree.patch | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/patch/kernel/mvebu-default/95-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch index 0a1ec90cc..404468fe0 100644 --- a/patch/kernel/mvebu-default/95-helios4-device-tree.patch +++ b/patch/kernel/mvebu-default/95-helios4-device-tree.patch @@ -13,13 +13,13 @@ Subject: Initial device tree - Enable IO expander interrupt - Allocate GPIOs for fans --- - arch/arm/boot/dts/armada-388-helios4.dts | 318 ++++++++++++++++++++++++++++++ - 1 file changed, 318 insertions(+) + arch/arm/boot/dts/armada-388-helios4.dts | 346 +++++++++++++++++++++ + 1 file changed, 346 insertions(+) create mode 100644 arch/arm/boot/dts/armada-388-helios4.dts diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts new file mode 100644 -index 0000000..b7a2122 +index 0000000..295f962 --- /dev/null +++ b/arch/arm/boot/dts/armada-388-helios4.dts @@ -0,0 +1,346 @@ @@ -42,7 +42,7 @@ index 0000000..b7a2122 + + memory { + device_type = "memory"; -+ reg = <0x00000000 0x40000000>; /* 1 GB */ ++ reg = <0x00000000 0x80000000>; /* 2 GB */ + }; + + aliases { @@ -116,7 +116,7 @@ index 0000000..b7a2122 + + fault-led { + label = "helios4:red:fault"; -+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; ++ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + default-state = "keep"; + }; + }; @@ -157,12 +157,12 @@ index 0000000..b7a2122 + + fan1: j10-pwm { + compatible = "pwm-fan"; -+ pwms = <&gpio1 9 3000>; ++ pwms = <&gpio1 9 3800>; + }; + + fan2: j17-pwm { + compatible = "pwm-fan"; -+ pwms = <&gpio1 4 4500>; ++ pwms = <&gpio1 23 3800>; + }; + + usb2_phy: usb2-phy { @@ -178,7 +178,7 @@ index 0000000..b7a2122 + soc { + internal-regs { + i2c@11000 { -+ clock-frequency = <100000>; ++ clock-frequency = <400000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; @@ -234,8 +234,6 @@ index 0000000..b7a2122 + reg = <0x4c>; + vcc-supply = <®_3p3v>; + }; -+ -+ /* What device at 0x64 ? */ + }; + + i2c@11100 { @@ -308,8 +306,6 @@ index 0000000..b7a2122 + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; -+ keep-power-in-suspend; -+ wakeup-source; + }; + + usb@58000 { @@ -327,7 +323,11 @@ index 0000000..b7a2122 + }; + + pinctrl@18000 { -+ pca0_pins: pca0_pins { ++ pca0_pins: pca0-pins { ++ marvell,pins = "mpp23"; ++ marvell,function = "gpio"; ++ }; ++ microsom_phy0_int_pins: microsom-phy0-int-pins { + marvell,pins = "mpp18"; + marvell,function = "gpio"; + }; @@ -354,7 +354,7 @@ index 0000000..b7a2122 + }; + helios_fan_pins: helios-fan-pins { + marvell,pins = "mpp41", "mpp43", -+ "mpp36", "mpp25"; ++ "mpp48", "mpp55"; + marvell,function = "gpio"; + }; + microsom_spi1_cs_pins: spi1-cs-pins { From 610d811b00c03ce99d46b84e8b1e00cab072ca78 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Fri, 29 Dec 2017 04:26:07 +0800 Subject: [PATCH 04/20] [dts] remove SD card UHS option/support on helios4 (Ultra) High Speed timing have compability issue on SanDisk and Toshiba card. Known brand that works with the UHS timing: - Transcend - Strontium --- .../95-helios4-remove_sd_uhs_option.patch | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 patch/kernel/mvebu-default/95-helios4-remove_sd_uhs_option.patch diff --git a/patch/kernel/mvebu-default/95-helios4-remove_sd_uhs_option.patch b/patch/kernel/mvebu-default/95-helios4-remove_sd_uhs_option.patch new file mode 100644 index 000000000..3039bf781 --- /dev/null +++ b/patch/kernel/mvebu-default/95-helios4-remove_sd_uhs_option.patch @@ -0,0 +1,16 @@ +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +index 295f962..9c536d7 100644 +--- a/arch/arm/boot/dts/armada-388-helios4.dts ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -276,11 +276,6 @@ + status = "okay"; + vmmc = <®_3p3v>; + wp-inverted; +- max-frequency = <50000000>; +- cap-sd-highspeed; +- sd-uhs-sdr12; +- sd-uhs-sdr25; +- sd-uhs-sdr50; + }; + + usb@58000 { From 89baa9130c4b99f10c78281b0903cb29666840e3 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Fri, 29 Dec 2017 04:30:41 +0800 Subject: [PATCH 05/20] [dts] Use GPIO-fan instead of PWM-fan on Helios4 Hardware PWM on mvebu GPIO officially supported on Linux Kernel 4.13. Backport to Linux Kernel 4.4 still in progress --- ...-helios4-gpio-fan_instead_of_pwm-fan.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch diff --git a/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch b/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch new file mode 100644 index 000000000..b72ccb00d --- /dev/null +++ b/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch @@ -0,0 +1,26 @@ +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +index ec7a5ce..1075535 100644 +--- a/arch/arm/boot/dts/armada-388-helios4.dts ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -131,13 +131,17 @@ + }; + + fan1: j10-pwm { +- compatible = "pwm-fan"; +- pwms = <&gpio1 9 3800>; ++ compatible = "gpio-fan"; ++ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; ++ gpio-fan,speed-map = < 0 0 ++ 3800 1>; + }; + + fan2: j17-pwm { +- compatible = "pwm-fan"; +- pwms = <&gpio1 23 3800>; ++ compatible = "gpio-fan"; ++ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; ++ gpio-fan,speed-map = < 0 0 ++ 3800 1>; + }; + + usb2_phy: usb2-phy { From 860efdc8e8aa013662164aa6b31fa69d97988639 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Fri, 29 Dec 2017 04:33:50 +0800 Subject: [PATCH 06/20] [dts] Disable SPI NOR flash on Helios4 Any activity on SPI NOR flash will interrupt SATA activity and caused SATA device to reset (Sometime downgrade the speed to SATA II - 3Gbps) --- .../95-helios4-remove-spi-nor-flash.patch | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch diff --git a/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch b/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch new file mode 100644 index 000000000..4b88135e8 --- /dev/null +++ b/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch @@ -0,0 +1,21 @@ +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +index 1075535..2045dc0 100644 +--- a/arch/arm/boot/dts/armada-388-helios4.dts ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -258,16 +258,6 @@ + µsom_spi1_cs_pins>; + pinctrl-names = "default"; + status = "okay"; +- +- spi-flash@0 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "w25q32", "jedec,spi-nor"; +- reg = <0>; /* Chip select 0 */ +- spi-max-frequency = <104000000>; +- spi-cpha; +- status = "okay"; +- }; + }; + + sdhci@d8000 { From 2cc7b312f3603093118d3f5d513ffd73c2523762 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Fri, 29 Dec 2017 04:37:32 +0800 Subject: [PATCH 07/20] [net] Fixed Ethernet Act LED on Marvell 88E1512 The PHY is used by SolidRun microSOM. Backport 88E1510 family driver from Linux Kernel 4.13 --- ...et-phy-marvell-88e1510_fixed_led_act.patch | 365 ++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch diff --git a/patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch b/patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch new file mode 100644 index 000000000..27312e0cc --- /dev/null +++ b/patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch @@ -0,0 +1,365 @@ +diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c +index 7cfb3f4..8143b07 100644 +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -39,6 +39,8 @@ + #include + + #define MII_MARVELL_PHY_PAGE 22 ++#define MII_MARVELL_COPPER_PAGE 0x00 ++#define MII_MARVELL_FIBER_PAGE 0x01 + + #define MII_M1011_IEVENT 0x13 + #define MII_M1011_IEVENT_CLEAR 0x0000 +@@ -136,6 +138,24 @@ + #define MII_88E1510_PHY_INTERNAL_REG_1 16 + #define MII_88E1510_PHY_INTERNAL_REG_2 17 + #define MII_88E1510_PHY_GENERAL_CTRL_1 20 ++#define MII_88E1510_PHY_GENERAL_CTRL_1_MODE_MASK 0x7 ++#define MII_88E1510_PHY_GENERAL_CTRL_1_MODE_SGMII 0x1 /* SGMII to copper */ ++#define MII_88E1510_PHY_GENERAL_CTRL_1_RESET 0x8000 /* Soft reset */ ++ ++#define LPA_FIBER_1000HALF 0x40 ++#define LPA_FIBER_1000FULL 0x20 ++ ++#define LPA_PAUSE_FIBER 0x180 ++#define LPA_PAUSE_ASYM_FIBER 0x100 ++ ++#define ADVERTISE_FIBER_1000HALF 0x40 ++#define ADVERTISE_FIBER_1000FULL 0x20 ++ ++#define ADVERTISE_PAUSE_FIBER 0x180 ++#define ADVERTISE_PAUSE_ASYM_FIBER 0x100 ++ ++#define REGISTER_LINK_STATUS 0x400 ++#define NB_FIBER_STATS 1 + + MODULE_DESCRIPTION("Marvell PHY driver"); + MODULE_AUTHOR("Andy Fleming"); +@@ -149,8 +169,9 @@ struct marvell_hw_stat { + }; + + static struct marvell_hw_stat marvell_hw_stats[] = { +- { "phy_receive_errors", 0, 21, 16}, ++ { "phy_receive_errors_copper", 0, 21, 16}, + { "phy_idle_errors", 0, 10, 8 }, ++ { "phy_receive_errors_fiber", 1, 21, 16}, + }; + + struct marvell_priv { +@@ -378,7 +399,6 @@ static int m88e1121_config_aneg(struct phy_device *phydev) + return err; + + if (phy_interface_is_rgmii(phydev)) { +- + mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & + MII_88E1121_PHY_MSCR_DELAY_MASK; + +@@ -406,15 +426,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev) + if (err < 0) + return err; + +- oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); +- +- phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); +- phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); +- phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); +- +- err = genphy_config_aneg(phydev); +- +- return err; ++ return genphy_config_aneg(phydev); + } + + static int m88e1318_config_aneg(struct phy_device *phydev) +@@ -422,6 +434,8 @@ static int m88e1318_config_aneg(struct phy_device *phydev) + int err, oldpage, mscr; + + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); ++ if (oldpage < 0) ++ return oldpage; + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1121_PHY_MSCR_PAGE); +@@ -442,15 +456,122 @@ static int m88e1318_config_aneg(struct phy_device *phydev) + return m88e1121_config_aneg(phydev); + } + ++/** ++ * ethtool_adv_to_fiber_adv_t ++ * @ethadv: the ethtool advertisement settings ++ * ++ * A small helper function that translates ethtool advertisement ++ * settings to phy autonegotiation advertisements for the ++ * MII_ADV register for fiber link. ++ */ ++static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv) ++{ ++ u32 result = 0; ++ ++ if (ethadv & ADVERTISED_1000baseT_Half) ++ result |= ADVERTISE_FIBER_1000HALF; ++ if (ethadv & ADVERTISED_1000baseT_Full) ++ result |= ADVERTISE_FIBER_1000FULL; ++ ++ if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP)) ++ result |= LPA_PAUSE_ASYM_FIBER; ++ else if (ethadv & ADVERTISE_PAUSE_CAP) ++ result |= (ADVERTISE_PAUSE_FIBER ++ & (~ADVERTISE_PAUSE_ASYM_FIBER)); ++ ++ return result; ++} ++ ++/** ++ * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR ++ * @phydev: target phy_device struct ++ * ++ * Description: If auto-negotiation is enabled, we configure the ++ * advertising, and then restart auto-negotiation. If it is not ++ * enabled, then we write the BMCR. Adapted for fiber link in ++ * some Marvell's devices. ++ */ ++static int marvell_config_aneg_fiber(struct phy_device *phydev) ++{ ++ int changed = 0; ++ int err; ++ int adv, oldadv; ++ u32 advertise; ++ ++ if (phydev->autoneg != AUTONEG_ENABLE) ++ return genphy_setup_forced(phydev); ++ ++ /* Only allow advertising what this PHY supports */ ++ phydev->advertising &= phydev->supported; ++ advertise = phydev->advertising; ++ ++ /* Setup fiber advertisement */ ++ adv = phy_read(phydev, MII_ADVERTISE); ++ if (adv < 0) ++ return adv; ++ ++ oldadv = adv; ++ adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL ++ | LPA_PAUSE_FIBER); ++ adv |= ethtool_adv_to_fiber_adv_t(advertise); ++ ++ if (adv != oldadv) { ++ err = phy_write(phydev, MII_ADVERTISE, adv); ++ if (err < 0) ++ return err; ++ ++ changed = 1; ++ } ++ ++ if (changed == 0) { ++ /* Advertisement hasn't changed, but maybe aneg was never on to ++ * begin with? Or maybe phy was isolated? ++ */ ++ int ctl = phy_read(phydev, MII_BMCR); ++ ++ if (ctl < 0) ++ return ctl; ++ ++ if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) ++ changed = 1; /* do restart aneg */ ++ } ++ ++ /* Only restart aneg if we are advertising something different ++ * than we were before. ++ */ ++ if (changed > 0) ++ changed = genphy_restart_aneg(phydev); ++ ++ return changed; ++} ++ + static int m88e1510_config_aneg(struct phy_device *phydev) + { + int err; + ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE); ++ if (err < 0) ++ goto error; ++ ++ /* Configure the copper link first */ + err = m88e1318_config_aneg(phydev); + if (err < 0) +- return err; ++ goto error; + +- return 0; ++ /* Then the fiber link */ ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_FIBER_PAGE); ++ if (err < 0) ++ goto error; ++ ++ err = marvell_config_aneg_fiber(phydev); ++ if (err < 0) ++ goto error; ++ ++ return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE); ++ ++error: ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE); ++ return err; + } + + static int marvell_config_init(struct phy_device *phydev) +@@ -635,109 +756,65 @@ static int m88e1111_config_init(struct phy_device *phydev) + return phy_write(phydev, MII_BMCR, BMCR_RESET); + } + +-static int m88e1510_phy_writebits(struct phy_device *phydev, +- u8 reg_num, u16 offset, u16 len, u16 data) ++static int m88e1121_config_init(struct phy_device *phydev) + { +- int err; +- int reg; +- u16 mask; ++ int err, oldpage; + +- if ((len + offset) >= 16) +- mask = 0 - (1 << offset); +- else +- mask = (1 << (len + offset)) - (1 << offset); ++ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); ++ if (oldpage < 0) ++ return oldpage; + +- reg = phy_read(phydev, reg_num); +- if (reg < 0) +- return reg; ++ phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); + +- reg &= ~mask; +- reg |= data << offset; ++ /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */ ++ err = phy_write(phydev, MII_88E1121_PHY_LED_CTRL, ++ MII_88E1121_PHY_LED_DEF); ++ if (err < 0) ++ return err; + +- err = phy_write(phydev, reg_num, (u16)reg); ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); ++ if (err < 0) ++ return err; + +- return err; ++ /* Set marvell,reg-init configuration from device tree */ ++ return marvell_config_init(phydev); + } + +-/* For Marvell 88E1510/88E1518/88E1512/88E1514, need to fix the Errata in +- * SGMII mode, which is described in Marvell Release Notes Errata Section 3.1. +- * Besides of that, the 88E151X serial PHY should be initialized as legacy +- * Marvell 88E1111 PHY. +- */ + static int m88e1510_config_init(struct phy_device *phydev) + { + int err; ++ int temp; + +- /* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 +- * /88E1514 Rev A0, Errata Section 3.1 +- */ ++ /* SGMII-to-Copper mode initialization */ + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { +- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00ff); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0x214B); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2144); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0x0C28); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2146); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0xB233); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x214D); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_2, 0xCC0C); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_88E1510_PHY_INTERNAL_REG_1, 0x2159); +- if (err < 0) +- return err; +- +- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); +- if (err < 0) +- return err; +- ++ /* Select page 18 */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18); + if (err < 0) + return err; + +- /* Write HWCFG_MODE = SGMII to Copper */ +- err = m88e1510_phy_writebits(phydev, +- MII_88E1510_PHY_GENERAL_CTRL_1, +- 0, 3, 1); ++ /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ ++ temp = phy_read(phydev, MII_88E1510_PHY_GENERAL_CTRL_1); ++ temp &= ~MII_88E1510_PHY_GENERAL_CTRL_1_MODE_MASK; ++ temp |= MII_88E1510_PHY_GENERAL_CTRL_1_MODE_SGMII; ++ err = phy_write(phydev, MII_88E1510_PHY_GENERAL_CTRL_1, temp); + if (err < 0) + return err; + +- /* Phy reset */ +- err = m88e1510_phy_writebits(phydev, +- MII_88E1510_PHY_GENERAL_CTRL_1, +- 15, 1, 1); ++ /* PHY reset is necessary after changing MODE[2:0] */ ++ temp |= MII_88E1510_PHY_GENERAL_CTRL_1_RESET; ++ err = phy_write(phydev, MII_88E1510_PHY_GENERAL_CTRL_1, temp); + if (err < 0) + return err; + +- err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); ++ /* Reset page selection */ ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_COPPER_PAGE); + if (err < 0) + return err; + + usleep_range(100, 200); + } + +- return m88e1111_config_init(phydev); ++ return m88e1121_config_init(phydev); + } + + static int m88e1118_config_aneg(struct phy_device *phydev) +@@ -1372,7 +1449,7 @@ static struct phy_driver marvell_drivers[] = { + .phy_id = MARVELL_PHY_ID_88E1510, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E1510", +- .features = PHY_GBIT_FEATURES | SUPPORTED_Pause, ++ .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE | SUPPORTED_Pause, + .flags = PHY_HAS_INTERRUPT, + .config_init = &m88e1510_config_init, + .config_aneg = &m88e1510_config_aneg, +@@ -1391,7 +1468,6 @@ static struct phy_driver marvell_drivers[] = { + .flags = PHY_HAS_INTERRUPT, + .probe = marvell_probe, + .config_init = &marvell_config_init, +- .config_init = &marvell_config_init, + .config_aneg = &m88e1510_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, From 63fca0a876210fe716e1d43d523e8275ac8ad5bd Mon Sep 17 00:00:00 2001 From: aprayoga Date: Sat, 30 Dec 2017 16:41:37 +0800 Subject: [PATCH 08/20] enable "next" branch on Helios4 --- config/boards/helios4.wip | 2 +- config/bootenv/helios4-next.txt | 3 + config/kernel/linux-mvebu-next.config | 101 +++-- .../91-01-libata-add-ledtrig-support.patch | 179 +++++++++ .../91-02--Enable-ATA-port-LED-trigger.patch | 37 ++ ...io-remove-hardcoded-timer-assignment.patch | 352 ++++++++++++++++++ .../mvebu-next/93-helios4-device-tree.patch | 331 ++++++++++++++++ .../93-helios4-remove-spi-nor-flash.patch | 17 + .../93-helios4-remove_sd_uhs_option.patch | 16 + 9 files changed, 1004 insertions(+), 34 deletions(-) create mode 100644 config/bootenv/helios4-next.txt create mode 100644 patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch create mode 100644 patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch create mode 100644 patch/kernel/mvebu-next/92-mvebu-gpio-remove-hardcoded-timer-assignment.patch create mode 100644 patch/kernel/mvebu-next/93-helios4-device-tree.patch create mode 100644 patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch create mode 100644 patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch diff --git a/config/boards/helios4.wip b/config/boards/helios4.wip index b0870a72a..3decda5ba 100644 --- a/config/boards/helios4.wip +++ b/config/boards/helios4.wip @@ -5,7 +5,7 @@ BOOTCONFIG="armada_38x_helios4_config" MODULES="mv_cesa" BUILD_DESKTOP="no" # -KERNEL_TARGET="default" +KERNEL_TARGET="default,next" CLI_TARGET="" CLI_BETA_TARGET="" diff --git a/config/bootenv/helios4-next.txt b/config/bootenv/helios4-next.txt new file mode 100644 index 000000000..682c692d2 --- /dev/null +++ b/config/bootenv/helios4-next.txt @@ -0,0 +1,3 @@ +verbosity=1 +ethaddr=00:50:43:84:fb:2f + diff --git a/config/kernel/linux-mvebu-next.config b/config/kernel/linux-mvebu-next.config index 758112640..ae9886639 100644 --- a/config/kernel/linux-mvebu-next.config +++ b/config/kernel/linux-mvebu-next.config @@ -1608,7 +1608,7 @@ CONFIG_MTD_BLOCK=y # RAM/ROM/Flash chip drivers # CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_JEDECPROBE=m CONFIG_MTD_GEN_PROBE=y # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y @@ -1634,9 +1634,8 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set +# CONFIG_MTD_PHYSMAP_OF is not set +# CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set @@ -1675,6 +1674,7 @@ CONFIG_OF=y # CONFIG_OF_UNITTEST is not set CONFIG_OF_FLATTREE=y CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_ADDRESS_PCI=y CONFIG_OF_IRQ=y @@ -1683,7 +1683,8 @@ CONFIG_OF_MDIO=y CONFIG_OF_PCI=y CONFIG_OF_PCI_IRQ=y CONFIG_OF_RESERVED_MEM=y -# CONFIG_OF_OVERLAY is not set +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y @@ -1887,6 +1888,8 @@ CONFIG_SCSI_LOWLEVEL=y CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ARCH_WANT_LIBATA_LEDS=y +CONFIG_ATA_LEDS=y CONFIG_SATA_PMP=y # @@ -2566,12 +2569,20 @@ CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set # CONFIG_NOZOMI is not set +# CONFIG_ISI is not set +# CONFIG_N_HDLC is not set # CONFIG_N_GSM is not set # CONFIG_TRACE_SINK is not set CONFIG_DEVMEM=y @@ -2590,8 +2601,12 @@ CONFIG_SERIAL_8250_PCI=y # CONFIG_SERIAL_8250_EXAR is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set -CONFIG_SERIAL_8250_ASPEED_VUART=m +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y # CONFIG_SERIAL_8250_EM is not set @@ -2781,6 +2796,7 @@ CONFIG_GPIOLIB=y CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y # # Memory mapped GPIO drivers @@ -2789,12 +2805,12 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_ALTERA is not set # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_FTGPIO010 is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set +CONFIG_GPIO_GENERIC_PLATFORM=y # CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_MOCKUP is not set # CONFIG_GPIO_MPC8XXX is not set CONFIG_GPIO_MVEBU=y -# CONFIG_GPIO_SYSCON is not set +CONFIG_GPIO_SYSCON=y # CONFIG_GPIO_XILINX is not set # CONFIG_GPIO_ZEVIO is not set @@ -2875,7 +2891,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_G762 is not set -CONFIG_SENSORS_GPIO_FAN=y +CONFIG_SENSORS_GPIO_FAN=m # CONFIG_SENSORS_HIH6130 is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_JC42 is not set @@ -2906,7 +2922,7 @@ CONFIG_SENSORS_MAX31790=m # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set +CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set # CONFIG_SENSORS_LM80 is not set @@ -2928,6 +2944,7 @@ CONFIG_SENSORS_MAX31790=m # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set +CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHT3x is not set @@ -2976,7 +2993,7 @@ CONFIG_THERMAL=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y -# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set @@ -2998,7 +3015,7 @@ CONFIG_ARMADA_THERMAL=y # CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y # CONFIG_WATCHDOG_SYSFS is not set @@ -3179,7 +3196,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_DA9210 is not set # CONFIG_REGULATOR_DA9211 is not set # CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_GPIO is not set +CONFIG_REGULATOR_GPIO=m # CONFIG_REGULATOR_ISL9305 is not set # CONFIG_REGULATOR_ISL6271A is not set # CONFIG_REGULATOR_LP3971 is not set @@ -3198,6 +3215,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_PV88060 is not set # CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set +# CONFIG_REGULATOR_PWM is not set # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set @@ -3389,7 +3407,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_DYNAMIC_MINORS=y # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set CONFIG_USB_LEDS_TRIGGER_USBPORT=y @@ -3450,7 +3468,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_UAS is not set +CONFIG_USB_UAS=m # # USB Imaging devices @@ -3563,9 +3581,9 @@ CONFIG_USB_ATM=m # # USB Physical Layer drivers # -# CONFIG_USB_PHY is not set +CONFIG_USB_PHY=y # CONFIG_NOP_USB_XCEIV is not set -# CONFIG_USB_GPIO_VBUS is not set +CONFIG_USB_GPIO_VBUS=y # CONFIG_USB_ISP1301 is not set # CONFIG_USB_ULPI is not set # CONFIG_USB_GADGET is not set @@ -3614,7 +3632,7 @@ CONFIG_MMC_MVSDIO=y # CONFIG_MMC_SDHCI_XENON is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m +CONFIG_LEDS_CLASS=y # CONFIG_LEDS_CLASS_FLASH is not set CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y @@ -3626,7 +3644,7 @@ CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y # CONFIG_LEDS_LM3530 is not set # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_PCA9532 is not set -# CONFIG_LEDS_GPIO is not set +CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP3952 is not set # CONFIG_LEDS_LP5521 is not set @@ -3637,6 +3655,7 @@ CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set # CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set # CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set @@ -3651,6 +3670,7 @@ CONFIG_LEDS_IS31FL32XX=m # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_SYSCON=y CONFIG_LEDS_USER=m # @@ -3658,21 +3678,21 @@ CONFIG_LEDS_USER=m # CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_ONESHOT is not set +CONFIG_LEDS_TRIGGER_ONESHOT=m CONFIG_LEDS_TRIGGER_DISK=y -# CONFIG_LEDS_TRIGGER_MTD is not set +CONFIG_LEDS_TRIGGER_MTD=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_CPU is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m # # iptables trigger is under Netfilter config (LED target) # -# CONFIG_LEDS_TRIGGER_TRANSIENT is not set -# CONFIG_LEDS_TRIGGER_CAMERA is not set -# CONFIG_LEDS_TRIGGER_PANIC is not set +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_LEDS_TRIGGER_PANIC=y # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y @@ -3896,6 +3916,7 @@ CONFIG_COMMON_CLK=y # CONFIG_COMMON_CLK_CS2000_CP is not set CONFIG_CLK_QORIQ=y # CONFIG_COMMON_CLK_NXP is not set +# CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_PIC32 is not set # CONFIG_COMMON_CLK_VC5 is not set @@ -3961,13 +3982,25 @@ CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set -# CONFIG_EXTCON is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +CONFIG_EXTCON_USB_GPIO=m CONFIG_MEMORY=y CONFIG_MVEBU_DEVBUS=y # CONFIG_IIO is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set -# CONFIG_PWM is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARM_GIC_MAX_NR=1 @@ -4322,7 +4355,9 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y # CONFIG_DEBUG_KERNEL is not set # diff --git a/patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch b/patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch new file mode 100644 index 000000000..272964ec1 --- /dev/null +++ b/patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch @@ -0,0 +1,179 @@ +From 5843af891d0dabf9bb80039cfe807d01e9495154 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 12 Dec 2014 13:38:33 +0100 +Subject: libata: add ledtrig support + +This adds a LED trigger for each ATA port indicating disk activity. + +As this is needed only on specific platforms (NAS SoCs and such), +these platforms should define ARCH_WANTS_LIBATA_LEDS if there +are boards with LED(s) intended to indicate ATA disk activity and +need the OS to take care of that. +In that way, if not selected, LED trigger support not will be +included in libata-core and both, codepaths and structures remain +untouched. + +Signed-off-by: Daniel Golle +--- + drivers/ata/Kconfig | 16 ++++++++++++++ + drivers/ata/libata-core.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/libata.h | 7 ++++++ + 3 files changed, 79 insertions(+) + +diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig +index 6aaa3f8..4e24b64 100644 +--- a/drivers/ata/Kconfig ++++ b/drivers/ata/Kconfig +@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR + + If unsure, say Y. + ++config ARCH_WANT_LIBATA_LEDS ++ bool ++ ++config ATA_LEDS ++ bool "support ATA port LED triggers" ++ depends on ARCH_WANT_LIBATA_LEDS ++ select NEW_LEDS ++ select LEDS_CLASS ++ select LEDS_TRIGGERS ++ default y ++ help ++ This option adds a LED trigger for each registered ATA port. ++ It is used to drive disk activity leds connected via GPIO. ++ ++ If unsure, say N. ++ + config ATA_ACPI + bool "ATA ACPI Support" + depends on ACPI +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index b0b77b6..1400f4d 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -728,6 +728,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) + return block; + } + ++ + /** + * ata_build_rw_tf - Build ATA taskfile for given read/write request + * @tf: Target ATA taskfile +@@ -4757,6 +4758,30 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) + } + + /** ++ * ata_led_act - Trigger port activity LED ++ * @ap: indicating port ++ * ++ * Blinks any LEDs registered to the trigger. ++ * Commonly used with leds-gpio on NAS systems with disk activity ++ * indicator LEDs. ++ * ++ * LOCKING: ++ * None. ++ */ ++static inline void ata_led_act(struct ata_port *ap) ++{ ++#if CONFIG_ATA_LEDS ++#define LIBATA_BLINK_DELAY 20 /* ms */ ++ unsigned long led_delay = LIBATA_BLINK_DELAY; ++ ++ if (unlikely(!ap->ledtrig)) ++ return; ++ ++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); ++#endif /* CONFIG_ATA_LEDS */ ++} ++ ++/** + * ata_qc_new_init - Request an available ATA command, and initialize it + * @dev: Device from whom we request an available command structure + * @tag: tag +@@ -4780,6 +4805,9 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) + if (tag < 0) + return NULL; + } ++#if CONFIG_ATA_LEDS ++ ata_led_act(ap); ++#endif + + qc = __ata_qc_from_tag(ap, tag); + qc->tag = tag; +@@ -5677,6 +5705,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) + ap->stats.unhandled_irq = 1; + ap->stats.idle_irq = 1; + #endif ++#if CONFIG_ATA_LEDS ++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); ++#endif + ata_sff_port_init(ap); + + return ap; +@@ -5698,6 +5729,12 @@ static void ata_host_release(struct device *gendev, void *res) + + kfree(ap->pmp_link); + kfree(ap->slave_link); ++#if CONFIG_ATA_LEDS ++ if (ap->ledtrig) { ++ led_trigger_unregister(ap->ledtrig); ++ kfree(ap->ledtrig); ++ }; ++#endif + kfree(ap); + host->ports[i] = NULL; + } +@@ -6145,6 +6182,25 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) + host->ports[i]->local_port_no = i + 1; + } + ++#if CONFIG_ATA_LEDS ++ /* register LED triggers for all ports */ ++ for (i = 0; i < host->n_ports; i++) { ++ if (unlikely(!host->ports[i]->ledtrig)) ++ continue; ++ ++ snprintf(host->ports[i]->ledtrig_name, ++ sizeof(host->ports[i]->ledtrig_name), "ata%u", ++ host->ports[i]->print_id); ++ ++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; ++ ++ if (led_trigger_register(host->ports[i]->ledtrig)) { ++ kfree(host->ports[i]->ledtrig); ++ host->ports[i]->ledtrig = NULL; ++ } ++ } ++#endif ++ + /* Create associated sysfs transport objects */ + for (i = 0; i < host->n_ports; i++) { + rc = ata_tport_add(host->dev,host->ports[i]); +diff --git a/include/linux/libata.h b/include/linux/libata.h +index b20a275..50eeee3 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + /* + * Define if arch has non-standard setup. This is a _PCI_ standard +@@ -877,6 +878,12 @@ struct ata_port { + #ifdef CONFIG_ATA_ACPI + struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ + #endif ++ ++#ifdef CONFIG_ATA_LEDS ++ struct led_trigger *ledtrig; ++ char ledtrig_name[8]; ++#endif ++ + /* owned by EH */ + u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; + }; +-- +2.7.4 + diff --git a/patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch b/patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch new file mode 100644 index 000000000..472d9b994 --- /dev/null +++ b/patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch @@ -0,0 +1,37 @@ +From 9ee6345ef82f7af5f98e17a40e667f8ad6b2fa1b Mon Sep 17 00:00:00 2001 +From: aprayoga +Date: Sun, 3 Sep 2017 18:10:12 +0800 +Subject: Enable ATA port LED trigger + +--- + arch/arm/configs/mvebu_v7_defconfig | 1 + + arch/arm/mach-mvebu/Kconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig +index cf363ab..19449d3 100644 +--- a/arch/arm/configs/mvebu_v7_defconfig ++++ b/arch/arm/configs/mvebu_v7_defconfig +@@ -61,6 +61,7 @@ CONFIG_MTD_SPI_NOR=y + CONFIG_EEPROM_AT24=y + CONFIG_BLK_DEV_SD=y + CONFIG_ATA=y ++CONFIG_ATA_LEDS=y + CONFIG_SATA_AHCI=y + CONFIG_AHCI_MVEBU=y + CONFIG_SATA_MV=y +diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig +index 053ea9d..aa1f389 100644 +--- a/arch/arm/mach-mvebu/Kconfig ++++ b/arch/arm/mach-mvebu/Kconfig +@@ -57,6 +57,7 @@ config MACH_ARMADA_375 + config MACH_ARMADA_38X + bool "Marvell Armada 380/385 boards" + depends on ARCH_MULTI_V7 ++ select ARCH_WANT_LIBATA_LEDS + select ARM_ERRATA_720789 + select ARM_ERRATA_753970 + select ARM_GIC +-- +2.7.4 + diff --git a/patch/kernel/mvebu-next/92-mvebu-gpio-remove-hardcoded-timer-assignment.patch b/patch/kernel/mvebu-next/92-mvebu-gpio-remove-hardcoded-timer-assignment.patch new file mode 100644 index 000000000..bcc3976d0 --- /dev/null +++ b/patch/kernel/mvebu-next/92-mvebu-gpio-remove-hardcoded-timer-assignment.patch @@ -0,0 +1,352 @@ +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index 45c65f8..2ec4a15 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -93,20 +93,41 @@ + + #define MVEBU_MAX_GPIO_PER_BANK 32 + +-struct mvebu_pwm { ++enum mvebu_pwm_ctrl { ++ MVEBU_PWM_CTRL_SET_A = 0, ++ MVEBU_PWM_CTRL_SET_B, ++ MVEBU_PWM_CTRL_MAX ++}; ++ ++struct mvebu_pwmchip { + void __iomem *membase; + unsigned long clk_rate; ++ spinlock_t lock; ++ bool in_use; ++ ++ /* Used to preserve GPIO/PWM registers across suspend/resume */ ++ u32 blink_on_duration; ++ u32 blink_off_duration; ++}; ++ ++struct mvebu_pwm_chip_drv { ++ enum mvebu_pwm_ctrl ctrl; + struct gpio_desc *gpiod; ++ bool master; ++}; ++ ++struct mvebu_pwm { + struct pwm_chip chip; +- spinlock_t lock; + struct mvebu_gpio_chip *mvchip; ++ struct mvebu_pwmchip controller; ++ enum mvebu_pwm_ctrl default_counter; + + /* Used to preserve GPIO/PWM registers across suspend/resume */ + u32 blink_select; +- u32 blink_on_duration; +- u32 blink_off_duration; + }; + ++static struct mvebu_pwmchip *mvebu_pwm_list[MVEBU_PWM_CTRL_MAX]; ++ + struct mvebu_gpio_chip { + struct gpio_chip chip; + struct regmap *regs; +@@ -283,12 +304,12 @@ mvebu_gpio_write_level_mask(struct mvebu_gpio_chip *mvchip, u32 val) + * Functions returning addresses of individual registers for a given + * PWM controller. + */ +-static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwm *mvpwm) ++static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwmchip *mvpwm) + { + return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF; + } + +-static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwm *mvpwm) ++static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwmchip *mvpwm) + { + return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF; + } +@@ -600,46 +621,80 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) + struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); + struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; + struct gpio_desc *desc; ++ enum mvebu_pwm_ctrl id; + unsigned long flags; + int ret = 0; ++ struct mvebu_pwm_chip_drv *chip_data; + +- spin_lock_irqsave(&mvpwm->lock, flags); ++ spin_lock_irqsave(&mvpwm->controller.lock, flags); + +- if (mvpwm->gpiod) { +- ret = -EBUSY; +- } else { +- desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm); +- if (!desc) { +- ret = -ENODEV; +- goto out; +- } ++ regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, ++ &mvchip->blink_en_reg); ++ if (pwm->chip_data || (mvchip->blink_en_reg & BIT(pwm->hwpwm))) ++ return -EBUSY; + +- ret = gpiod_request(desc, "mvebu-pwm"); +- if (ret) +- goto out; ++ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm); ++ if (!desc) { ++ ret = -ENODEV; ++ goto out; ++ } + +- ret = gpiod_direction_output(desc, 0); +- if (ret) { +- gpiod_free(desc); +- goto out; +- } ++ ret = gpiod_request(desc, "mvebu-pwm"); ++ if (ret) ++ goto out; + +- mvpwm->gpiod = desc; ++ ret = gpiod_direction_output(desc, 0); ++ if (ret) { ++ gpiod_free(desc); ++ goto out; + } ++ ++ chip_data = kzalloc(sizeof(struct mvebu_pwm_chip_drv), GFP_KERNEL); ++ if (!chip_data) { ++ gpiod_free(desc); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ for (id = MVEBU_PWM_CTRL_SET_A;id < MVEBU_PWM_CTRL_MAX; id++) { ++ if (!mvebu_pwm_list[id]->in_use) { ++ chip_data->ctrl = id; ++ chip_data->master = true; ++ mvebu_pwm_list[id]->in_use = true; ++ break; ++ } ++ } ++ ++ if (!chip_data->master) ++ chip_data->ctrl = mvpwm->default_counter; ++ ++ regmap_update_bits(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, ++ BIT(pwm->hwpwm), chip_data->ctrl ? BIT(pwm->hwpwm) : 0); ++ ++ chip_data->gpiod = desc; ++ pwm->chip_data = chip_data; ++ ++ regmap_read(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, ++ &mvpwm->blink_select); + out: +- spin_unlock_irqrestore(&mvpwm->lock, flags); ++ spin_unlock_irqrestore(&mvpwm->controller.lock, flags); + return ret; + } + + static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) + { + struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data; + unsigned long flags; + +- spin_lock_irqsave(&mvpwm->lock, flags); +- gpiod_free(mvpwm->gpiod); +- mvpwm->gpiod = NULL; +- spin_unlock_irqrestore(&mvpwm->lock, flags); ++ spin_lock_irqsave(&mvpwm->controller.lock, flags); ++ if (chip_data->master) ++ mvebu_pwm_list[chip_data->ctrl]->in_use = false; ++ ++ gpiod_free(chip_data->gpiod); ++ kfree(chip_data); ++ pwm->chip_data = NULL; ++ spin_unlock_irqrestore(&mvpwm->controller.lock, flags); + } + + static void mvebu_pwm_get_state(struct pwm_chip *chip, +@@ -647,17 +702,24 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip, + struct pwm_state *state) { + + struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data; ++ struct mvebu_pwmchip *controller; + struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; + unsigned long long val; + unsigned long flags; + u32 u; + +- spin_lock_irqsave(&mvpwm->lock, flags); ++ if (chip_data) ++ controller = mvebu_pwm_list[chip_data->ctrl]; ++ else ++ controller = &mvpwm->controller; ++ ++ spin_lock_irqsave(&controller->lock, flags); + + val = (unsigned long long) +- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); ++ readl_relaxed(mvebu_pwmreg_blink_on_duration(controller)); + val *= NSEC_PER_SEC; +- do_div(val, mvpwm->clk_rate); ++ do_div(val, controller->clk_rate); + if (val > UINT_MAX) + state->duty_cycle = UINT_MAX; + else if (val) +@@ -666,9 +728,9 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip, + state->duty_cycle = 1; + + val = (unsigned long long) +- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); ++ readl_relaxed(mvebu_pwmreg_blink_off_duration(controller)); + val *= NSEC_PER_SEC; +- do_div(val, mvpwm->clk_rate); ++ do_div(val, controller->clk_rate); + if (val < state->duty_cycle) { + state->period = 1; + } else { +@@ -687,19 +749,21 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip, + else + state->enabled = false; + +- spin_unlock_irqrestore(&mvpwm->lock, flags); ++ spin_unlock_irqrestore(&controller->lock, flags); + } + + static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) + { + struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data; ++ struct mvebu_pwmchip *controller = mvebu_pwm_list[chip_data->ctrl]; + struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; + unsigned long long val; + unsigned long flags; + unsigned int on, off; + +- val = (unsigned long long) mvpwm->clk_rate * state->duty_cycle; ++ val = (unsigned long long) controller->clk_rate * state->duty_cycle; + do_div(val, NSEC_PER_SEC); + if (val > UINT_MAX) + return -EINVAL; +@@ -708,7 +772,7 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + else + on = 1; + +- val = (unsigned long long) mvpwm->clk_rate * ++ val = (unsigned long long) controller->clk_rate * + (state->period - state->duty_cycle); + do_div(val, NSEC_PER_SEC); + if (val > UINT_MAX) +@@ -718,16 +782,16 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + else + off = 1; + +- spin_lock_irqsave(&mvpwm->lock, flags); ++ spin_lock_irqsave(&controller->lock, flags); + +- writel_relaxed(on, mvebu_pwmreg_blink_on_duration(mvpwm)); +- writel_relaxed(off, mvebu_pwmreg_blink_off_duration(mvpwm)); ++ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(controller)); ++ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(controller)); + if (state->enabled) + mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 1); + else + mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 0); + +- spin_unlock_irqrestore(&mvpwm->lock, flags); ++ spin_unlock_irqrestore(&controller->lock, flags); + + return 0; + } +@@ -746,10 +810,10 @@ static void __maybe_unused mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) + + regmap_read(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, + &mvpwm->blink_select); +- mvpwm->blink_on_duration = +- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); +- mvpwm->blink_off_duration = +- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); ++ mvpwm->controller.blink_on_duration = ++ readl_relaxed(mvebu_pwmreg_blink_on_duration(&mvpwm->controller)); ++ mvpwm->controller.blink_off_duration = ++ readl_relaxed(mvebu_pwmreg_blink_off_duration(&mvpwm->controller)); + } + + static void __maybe_unused mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) +@@ -758,10 +822,10 @@ static void __maybe_unused mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) + + regmap_write(mvchip->regs, GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, + mvpwm->blink_select); +- writel_relaxed(mvpwm->blink_on_duration, +- mvebu_pwmreg_blink_on_duration(mvpwm)); +- writel_relaxed(mvpwm->blink_off_duration, +- mvebu_pwmreg_blink_off_duration(mvpwm)); ++ writel_relaxed(mvpwm->controller.blink_on_duration, ++ mvebu_pwmreg_blink_on_duration(&mvpwm->controller)); ++ writel_relaxed(mvpwm->controller.blink_off_duration, ++ mvebu_pwmreg_blink_off_duration(&mvpwm->controller)); + } + + static int mvebu_pwm_probe(struct platform_device *pdev, +@@ -772,6 +836,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + struct mvebu_pwm *mvpwm; + struct resource *res; + u32 set; ++ enum mvebu_pwm_ctrl ctrl_set; + + if (!of_device_is_compatible(mvchip->chip.of_node, + "marvell,armada-370-gpio")) +@@ -794,12 +859,15 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + * Use set A for lines of GPIO chip with id 0, B for GPIO chip + * with id 1. Don't allow further GPIO chips to be used for PWM. + */ +- if (id == 0) ++ if (id == 0) { + set = 0; +- else if (id == 1) ++ ctrl_set = MVEBU_PWM_CTRL_SET_A; ++ } else if (id == 1) { + set = U32_MAX; +- else ++ ctrl_set = MVEBU_PWM_CTRL_SET_B; ++ } else { + return -EINVAL; ++ } + regmap_write(mvchip->regs, + GPIO_BLINK_CNT_SELECT_OFF + mvchip->offset, set); + +@@ -809,15 +877,13 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + mvchip->mvpwm = mvpwm; + mvpwm->mvchip = mvchip; + +- mvpwm->membase = devm_ioremap_resource(dev, res); +- if (IS_ERR(mvpwm->membase)) +- return PTR_ERR(mvpwm->membase); ++ mvpwm->controller.membase = devm_ioremap_resource(dev, res); ++ if (IS_ERR(mvpwm->controller.membase)) ++ return PTR_ERR(mvpwm->controller.membase); + +- mvpwm->clk_rate = clk_get_rate(mvchip->clk); +- if (!mvpwm->clk_rate) { +- dev_err(dev, "failed to get clock rate\n"); ++ mvpwm->controller.clk_rate = clk_get_rate(mvchip->clk); ++ if (!mvpwm->controller.clk_rate) + return -EINVAL; +- } + + mvpwm->chip.dev = dev; + mvpwm->chip.ops = &mvebu_pwm_ops; +@@ -830,7 +896,9 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + */ + mvpwm->chip.base = -1; + +- spin_lock_init(&mvpwm->lock); ++ spin_lock_init(&mvpwm->controller.lock); ++ mvpwm->default_counter = ctrl_set; ++ mvebu_pwm_list[ctrl_set] = &mvpwm->controller; + + return pwmchip_add(&mvpwm->chip); + } diff --git a/patch/kernel/mvebu-next/93-helios4-device-tree.patch b/patch/kernel/mvebu-next/93-helios4-device-tree.patch new file mode 100644 index 000000000..ff18c48d8 --- /dev/null +++ b/patch/kernel/mvebu-next/93-helios4-device-tree.patch @@ -0,0 +1,331 @@ + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/armada-388-helios4.dts | 309 +++++++++++++++++++++ + 2 files changed, 310 insertions(+) + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 4b17f35..c6b6038 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1020,6 +1020,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ + armada-388-clearfog.dtb \ + armada-388-clearfog-base.dtb \ + armada-388-clearfog-pro.dtb \ ++ armada-388-helios4.dtb \ + armada-388-db.dtb \ + armada-388-gp.dtb \ + armada-388-rd.dtb +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +new file mode 100644 +index 0000000..93d0132 +--- /dev/null ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -0,0 +1,309 @@ ++/* ++ * Device Tree file for Helios4 ++ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) ++ * ++ * Copyright (C) 2017 Kobol.io ++ * ++ */ ++ ++/dts-v1/; ++#include "armada-388.dtsi" ++#include "armada-38x-solidrun-microsom.dtsi" ++ ++/ { ++ model = "Helios4"; ++ compatible = "marvell,armada388", ++ "marvell,armada385", "marvell,armada380"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x00000000 0x80000000>; /* 2 GB */ ++ }; ++ ++ aliases { ++ /* So that mvebu u-boot can update the MAC addresses */ ++ ethernet1 = ð0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ reg_12v: regulator-12v { ++ compatible = "regulator-fixed"; ++ regulator-name = "power_brick_12V"; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "3P3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <®_12v>; ++ }; ++ ++ reg_5p0v_hdd: regulator-5v-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "5V_HDD"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ vin-supply = <®_12v>; ++ }; ++ ++ reg_5p0v_usb: regulator-5v-usb { ++ compatible = "regulator-fixed"; ++ regulator-name = "USB-PWR"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ enable-active-high; ++ gpio = <&expander0 6 GPIO_ACTIVE_HIGH>; ++ vin-supply = <®_12v>; ++ }; ++ ++ system-leds { ++ compatible = "gpio-leds"; ++ status-led { ++ label = "helios4:green:status"; ++ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ ++ fault-led { ++ label = "helios4:red:fault"; ++ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; ++ default-state = "keep"; ++ }; ++ }; ++ ++ io-leds { ++ compatible = "gpio-leds"; ++ sata1-led { ++ label = "helios4:green:ata1"; ++ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata1"; ++ default-state = "off"; ++ }; ++ sata2-led { ++ label = "helios4:green:ata2"; ++ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata2"; ++ default-state = "off"; ++ }; ++ sata3-led { ++ label = "helios4:green:ata3"; ++ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata3"; ++ default-state = "off"; ++ }; ++ sata4-led { ++ label = "helios4:green:ata4"; ++ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "ata4"; ++ default-state = "off"; ++ }; ++ usb-led { ++ label = "helios4:green:usb"; ++ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "usb-host"; ++ default-state = "off"; ++ }; ++ }; ++ ++ fan1: j10-pwm { ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 9 40000>; /* Target freq:25 kHz */ ++ }; ++ ++ fan2: j17-pwm { ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 23 40000>; /* Target freq:25 kHz */ ++ }; ++ ++ usb2_phy: usb2-phy { ++ compatible = "usb-nop-xceiv"; ++ vbus-regulator = <®_5p0v_usb>; ++ }; ++ ++ usb3_phy: usb3-phy { ++ compatible = "usb-nop-xceiv"; ++ //vbus-regulator = <®_5p0v_usb>; ++ }; ++ ++ soc { ++ internal-regs { ++ sata@a8000 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sata0: sata-port@0 { ++ reg = <0>; ++ }; ++ ++ sata1: sata-port@1 { ++ reg = <1>; ++ }; ++ }; ++ ++ sata@e0000 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sata2: sata-port@0 { ++ reg = <0>; ++ }; ++ ++ sata3: sata-port@1 { ++ reg = <1>; ++ }; ++ }; ++ ++ sdhci@d8000 { ++ bus-width = <4>; ++ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; ++ no-1-8-v; ++ pinctrl-0 = <µsom_sdhci_pins ++ &helios_sdhci_cd_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ vmmc = <®_3p3v>; ++ wp-inverted; ++ max-frequency = <50000000>; ++ cap-sd-highspeed; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ }; ++ ++ usb@58000 { ++ //vcc-supply = <®_5p0v_usb>; ++ usb-phy = <&usb2_phy>; ++ status = "okay"; ++ }; ++ ++ usb3@f0000 { ++ status = "okay"; ++ }; ++ ++ usb3@f8000 { ++ status = "okay"; ++ }; ++ }; ++ }; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ pinctrl-0 = <&i2c0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ /* ++ * PCA9655 GPIO expander, up to 1MHz clock. ++ * 0-Board Revision bit 0 # ++ * 1-Board Revision bit 1 # ++ * 5-USB3 overcurrent ++ * 6-USB3 power ++ */ ++ expander0: gpio-expander@20 { ++ /* ++ * This is how it should be: ++ * compatible = "onnn,pca9655", "nxp,pca9555"; ++ * but you can't do this because of the way I2C works. ++ */ ++ compatible = "nxp,pca9555"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ reg = <0x20>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pca0_pins>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <23 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ board_rev_bit_0 { ++ gpio-hog; ++ gpios = <0 GPIO_ACTIVE_LOW>; ++ input; ++ line-name = "board-rev-0"; ++ }; ++ board_rev_bit_1 { ++ gpio-hog; ++ gpios = <1 GPIO_ACTIVE_LOW>; ++ input; ++ line-name = "board-rev-1"; ++ }; ++ usb3_ilimit { ++ gpio-hog; ++ gpios = <5 GPIO_ACTIVE_HIGH>; ++ input; ++ line-name = "usb-overcurrent-status"; ++ }; ++ }; ++ ++ temp_sensor: temp@4c { ++ compatible = "ti,lm75"; ++ reg = <0x4c>; ++ vcc-supply = <®_3p3v>; ++ }; ++}; ++ ++&i2c1 { ++ /* ++ * External I2C Bus for user peripheral ++ */ ++ clock-frequency = <400000>; ++ pinctrl-0 = <&helios_i2c1_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++&pinctrl { ++ pca0_pins: pca0_pins { ++ marvell,pins = "mpp23"; ++ marvell,function = "gpio"; ++ }; ++ microsom_phy0_int_pins: microsom-phy0-int-pins { ++ marvell,pins = "mpp18"; ++ marvell,function = "gpio"; ++ }; ++ helios_i2c1_pins: i2c1-pins { ++ marvell,pins = "mpp26", "mpp27"; ++ marvell,function = "i2c1"; ++ }; ++ helios_sdhci_cd_pins: helios-sdhci-cd-pins { ++ marvell,pins = "mpp20"; ++ marvell,function = "gpio"; ++ }; ++ helios_led_pins: helios-led-pins { ++ marvell,pins = "mpp24", "mpp25", ++ "mpp49", "mpp50", ++ "mpp52", "mpp53", ++ "mpp54"; ++ marvell,function = "gpio"; ++ }; ++ helios_fan_pins: helios-fan-pins { ++ marvell,pins = "mpp41", "mpp43", ++ "mpp48", "mpp55"; ++ marvell,function = "gpio"; ++ }; ++}; ++ ++&spi1 { ++ status = "okay"; ++ ++ spi-flash@0 { ++ spi-max-frequency = <104000000>; ++ status = "okay"; ++ }; ++}; diff --git a/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch b/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch new file mode 100644 index 000000000..eec08df38 --- /dev/null +++ b/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch @@ -0,0 +1,17 @@ +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +index 93d0132..47699bd 100644 +--- a/arch/arm/boot/dts/armada-388-helios4.dts ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -298,12 +298,3 @@ + marvell,function = "gpio"; + }; + }; +- +-&spi1 { +- status = "okay"; +- +- spi-flash@0 { +- spi-max-frequency = <104000000>; +- status = "okay"; +- }; +-}; diff --git a/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch b/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch new file mode 100644 index 000000000..08e364d4a --- /dev/null +++ b/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch @@ -0,0 +1,16 @@ +diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts +index 47699bd..4a5e8fc 100644 +--- a/arch/arm/boot/dts/armada-388-helios4.dts ++++ b/arch/arm/boot/dts/armada-388-helios4.dts +@@ -177,11 +177,6 @@ + status = "okay"; + vmmc = <®_3p3v>; + wp-inverted; +- max-frequency = <50000000>; +- cap-sd-highspeed; +- sd-uhs-sdr12; +- sd-uhs-sdr25; +- sd-uhs-sdr50; + }; + + usb@58000 { From 6446a20a7fb5d8188d96d37427869428454e5f2d Mon Sep 17 00:00:00 2001 From: aprayoga Date: Sat, 30 Dec 2017 16:50:10 +0800 Subject: [PATCH 09/20] Enable minimal kernel debug info - Enable KGDB support - Enable earlycon and earlyprintk support --- config/kernel/linux-mvebu-next.config | 101 +++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 3 deletions(-) diff --git a/config/kernel/linux-mvebu-next.config b/config/kernel/linux-mvebu-next.config index ae9886639..a9743ae13 100644 --- a/config/kernel/linux-mvebu-next.config +++ b/config/kernel/linux-mvebu-next.config @@ -142,6 +142,7 @@ CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y +# CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y # CONFIG_CHECKPOINT_RESTORE is not set CONFIG_NAMESPACES=y @@ -175,6 +176,7 @@ CONFIG_SYSFS_SYSCALL=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_POSIX_TIMERS=y CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_PRINTK=y @@ -204,6 +206,7 @@ CONFIG_PERF_USE_VMALLOC=y # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y # CONFIG_SLUB_MEMCG_SYSFS_ON is not set @@ -516,6 +519,7 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set CONFIG_PCI_MSI=y CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -615,6 +619,7 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_CLEANCACHE is not set CONFIG_FRONTSWAP=y CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y @@ -1231,6 +1236,11 @@ CONFIG_INET_DCCP_DIAG=m CONFIG_IP_DCCP_CCID3=y # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_OBJCNT is not set CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y @@ -1430,6 +1440,7 @@ CONFIG_BT_HS=y CONFIG_BT_LE=y CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y +# CONFIG_BT_SELFTEST is not set # CONFIG_BT_DEBUGFS is not set # @@ -1543,6 +1554,9 @@ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_WANT_DEV_COREDUMP=y CONFIG_ALLOW_DEV_COREDUMP=y CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_GENERIC_CPU_DEVICES is not set @@ -2618,11 +2632,13 @@ CONFIG_SERIAL_OF_PLATFORM=y # Non-8250 serial port support # # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_KGDB_NMI is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set # CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_SC16IS7XX is not set @@ -2719,6 +2735,7 @@ CONFIG_I2C_MV64XXX=y # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y # @@ -2780,6 +2797,7 @@ CONFIG_PINCTRL=y # CONFIG_PINMUX=y CONFIG_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set # CONFIG_PINCTRL_AMD is not set # CONFIG_PINCTRL_MCP23S08 is not set # CONFIG_PINCTRL_SINGLE is not set @@ -2795,6 +2813,7 @@ CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_GPIOLIB=y CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y CONFIG_GPIO_GENERIC=y @@ -4246,6 +4265,7 @@ CONFIG_NFSD_V4=y # CONFIG_NFSD_SCSILAYOUT is not set # CONFIG_NFSD_FLEXFILELAYOUT is not set # CONFIG_NFSD_V4_SECURITY_LABEL is not set +# CONFIG_NFSD_FAULT_INJECTION is not set CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -4341,66 +4361,113 @@ CONFIG_NLS_UTF8=y CONFIG_PRINTK_TIME=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=2 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_DYNAMIC_DEBUG is not set # # Compile-time checks and compiler options # +# CONFIG_DEBUG_INFO is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set # CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y -# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_KERNEL=y # # Memory Debugging # CONFIG_PAGE_EXTENSION=y +# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SHIRQ is not set # # Debug Lockups and Hangs # +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y CONFIG_SCHED_INFO=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set # # Lock Debugging (spinlocks, mutexes, etc...) # +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set # CONFIG_STACKTRACE is not set # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # # RCU Debugging # # CONFIG_PROVE_RCU is not set # CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_TRACE=y +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # CONFIG_DMA_API_DEBUG is not set @@ -4411,6 +4478,10 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_ASYNC_RAID6_TEST is not set CONFIG_TEST_HEXDUMP=m @@ -4433,15 +4504,39 @@ CONFIG_TEST_HEXDUMP=m # CONFIG_BUG_ON_DATA_CORRUPTION is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_KDB=y +CONFIG_KDB_DEFAULT_ENABLE=0x1 +CONFIG_KDB_KEYBOARD=y +CONFIG_KDB_CONTINUE_CATASTROPHIC=0 # CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set # CONFIG_UBSAN is not set CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM_PTDUMP is not set CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_USER is not set -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -# CONFIG_DEBUG_UART_8250 is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_MVEBU_UART0 is not set +CONFIG_DEBUG_MVEBU_UART0_ALTERNATE=y +# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +# CONFIG_DEBUG_LL_UART_8250 is not set +# CONFIG_DEBUG_LL_UART_PL01X is not set +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_UART_8250=y +CONFIG_DEBUG_UART_PHYS=0xf1012000 +CONFIG_DEBUG_UART_VIRT=0xfec12000 +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +# CONFIG_DEBUG_UART_8250_PALMCHIP is not set +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UNCOMPRESS=y CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_EARLY_PRINTK=y # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_CORESIGHT is not set From 2e86ccf4c59418639962777e5af2d061286cfc3d Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sat, 6 Jan 2018 18:57:18 +0800 Subject: [PATCH 10/20] Update Helios4 Device Tree - board rev1.1 - Change GPIO for I2C IO expander interrupt pin - Remove gpio-key button0 --- .../95-helios4-device-tree.patch | 27 ++++--------------- .../95-helios4-remove-spi-nor-flash.patch | 2 +- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/patch/kernel/mvebu-default/95-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch index 404468fe0..b71509555 100644 --- a/patch/kernel/mvebu-default/95-helios4-device-tree.patch +++ b/patch/kernel/mvebu-default/95-helios4-device-tree.patch @@ -13,16 +13,16 @@ Subject: Initial device tree - Enable IO expander interrupt - Allocate GPIOs for fans --- - arch/arm/boot/dts/armada-388-helios4.dts | 346 +++++++++++++++++++++ - 1 file changed, 346 insertions(+) + arch/arm/boot/dts/armada-388-helios4.dts | 329 +++++++++++++++++++++ + 1 file changed, 329 insertions(+) create mode 100644 arch/arm/boot/dts/armada-388-helios4.dts diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts new file mode 100644 -index 0000000..295f962 +index 0000000..19a0256 --- /dev/null +++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -0,0 +1,346 @@ +@@ -0,0 +1,329 @@ +/* + * Device Tree file for Helios4 + * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) @@ -92,19 +92,6 @@ index 0000000..295f962 + vin-supply = <®_12v>; + }; + -+ gpio-keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&user_button_pins>; -+ pinctrl-names = "default"; -+ -+ button_0 { -+ label = "User Button"; -+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; -+ linux,can-disable; -+ linux,code = ; -+ }; -+ }; -+ + system-leds { + compatible = "gpio-leds"; + status-led { @@ -205,7 +192,7 @@ index 0000000..295f962 + pinctrl-names = "default"; + pinctrl-0 = <&pca0_pins>; + interrupt-parent = <&gpio0>; -+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>; ++ interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + @@ -361,10 +348,6 @@ index 0000000..295f962 + marvell,pins = "mpp59"; + marvell,function = "spi1"; + }; -+ user_button_pins: user-button-pins { -+ marvell,pins = "mpp23"; -+ marvell,function = "gpio"; -+ }; + }; + }; + }; diff --git a/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch b/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch index 4b88135e8..dab0a3481 100644 --- a/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch +++ b/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch @@ -2,7 +2,7 @@ diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada index 1075535..2045dc0 100644 --- a/arch/arm/boot/dts/armada-388-helios4.dts +++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -258,16 +258,6 @@ +@@ -244,16 +244,6 @@ µsom_spi1_cs_pins>; pinctrl-names = "default"; status = "okay"; From 3b9a66e1fcc1c3e5cbe399f3dbae41baf6dff5ca Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sat, 6 Jan 2018 19:15:12 +0800 Subject: [PATCH 11/20] Add install fancontrol func in customize-image.sh template. Include in template Helios4 fancontrol conf --- config/templates/customize-image.sh.template | 58 ++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/config/templates/customize-image.sh.template b/config/templates/customize-image.sh.template index 285de0d35..ae81d7eda 100644 --- a/config/templates/customize-image.sh.template +++ b/config/templates/customize-image.sh.template @@ -20,6 +20,7 @@ Main() { case $RELEASE in jessie) # your code here + # InstallFanControl # uncomment to install fancontrol # InstallOpenMediaVault # uncomment to get an OMV 3 image ;; xenial) @@ -27,6 +28,7 @@ Main() { ;; stretch) # your code here + # InstallFanControl # uncomment to install fancontrol # InstallOpenMediaVault # uncomment to get an OMV 4 image ;; esac @@ -203,5 +205,61 @@ InstallOpenMediaVault() { chage -d 0 root } # InstallOpenMediaVault + +InstallFanControl() { + apt-get update + apt-get --yes install fancontrol + if [ "${BOARD}" = "helios4" ]; then + case ${RELEASE} in + jessie) + cat > /etc/fancontrol <<-EOF + # Helios4 GPIO Fan Control Configuration + # This is a temporary configuration while relying on gpio-fan driver. + # Only low or full speed is supported. + # Temp source : lm75 sensor + INTERVAL=10 + DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c + DEVNAME=hwmon0=gpio_fan hwmon1=gpio_fan hwmon2=lm75 + FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input + MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 + MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 + MINSTART=hwmon0/pwm1=1 hwmon1/pwm1=1 + MINSTOP=hwmon0/pwm1=0 hwmon1/pwm1=0 + EOF + ;; + stretch) + cat > /etc/fancontrol <<-EOF + # Helios4 PWM Fan Control Configuration + # Temp source : armada_thermal sensor + INTERVAL=10 + DEVPATH=hwmon1=devices/virtual hwmon2=devices/platform/j10-pwm hwmon3=devices/platform/j17-pwm hwmon4=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c + DEVNAME=hwmon1=armada_thermal hwmon2=pwmfan hwmon3=pwmfan hwmon4=lm75 + FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input + MINTEMP=hwmon2/pwm1=55 hwmon3/pwm1=55 + MAXTEMP=hwmon2/pwm1=95 hwmon3/pwm1=95 + MINSTART=hwmon2/pwm1=100 hwmon3/pwm1=100 + MINSTOP=hwmon2/pwm1=50 hwmon3/pwm1=50 + EOF + + # Patching fancontrol + patch -b /usr/sbin/fancontrol <<-'EOF' + @@ -157,9 +157,9 @@ + + function DevicePath() + { + - if [ -h "$1/device" ] + + if [ -h "$1" ] + then + - readlink -f "$1/device" | sed -e 's/^\/sys\///' + + readlink -f "$1" | sed -e 's/^\/sys\///;s/\/hwmon\/.*//' + fi + } + + EOF + ;; + esac + fi +} # InstallFanControl + Main "$@" From 47c7c814de5826d8a78eb438868b418f6a06387f Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sat, 6 Jan 2018 20:23:21 +0800 Subject: [PATCH 12/20] Remove wrong Helios4 Device Tree patch from mvebu-next. --- patch/kernel/mvebu-next/add-helios4.patch | 357 ---------------------- 1 file changed, 357 deletions(-) delete mode 100644 patch/kernel/mvebu-next/add-helios4.patch diff --git a/patch/kernel/mvebu-next/add-helios4.patch b/patch/kernel/mvebu-next/add-helios4.patch deleted file mode 100644 index 7da28c9c9..000000000 --- a/patch/kernel/mvebu-next/add-helios4.patch +++ /dev/null @@ -1,357 +0,0 @@ -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index eff87a3..3efb92f ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1028,6 +1028,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \ - armada-385-linksys-rango.dtb \ - armada-385-linksys-shelby.dtb \ - armada-385-synology-ds116.dtb \ -+ armada-388-helios4.dtb \ - armada-385-turris-omnia.dtb \ - armada-388-clearfog.dtb \ - armada-388-clearfog-base.dtb \ -diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts -new file mode 100644 -index 0000000..4edb552 ---- /dev/null -+++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -0,0 +1,339 @@ -+/* -+ * Device Tree file for Helios-4 -+ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) -+ * -+ * Copyright (C) 2017 -+ * -+ */ -+ -+/dts-v1/; -+#include "armada-388.dtsi" -+#include "armada-38x-solidrun-microsom.dtsi" -+ -+/ { -+ model = "Helios4"; -+ compatible = "marvell,armada388", -+ "marvell,armada385", "marvell,armada380"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x00000000 0x40000000>; /* 1 GB */ -+ }; -+ -+ aliases { -+ /* So that mvebu u-boot can update the MAC addresses */ -+ ethernet1 = ð0; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ reg_12v: regulator-12v { -+ compatible = "regulator-fixed"; -+ regulator-name = "power_brick_12V"; -+ regulator-min-microvolt = <12000000>; -+ regulator-max-microvolt = <12000000>; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "3P3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ vin-supply = <®_12v>; -+ }; -+ -+ reg_5p0v_hdd: regulator-5v-hdd { -+ compatible = "regulator-fixed"; -+ regulator-name = "5V_HDD"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-always-on; -+ vin-supply = <®_12v>; -+ }; -+ -+ reg_5p0v_usb: regulator-5v-usb { -+ compatible = "regulator-fixed"; -+ regulator-name = "USB-PWR"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ enable-active-high; -+ gpio = <&expander0 6 GPIO_ACTIVE_HIGH>; -+ vin-supply = <®_12v>; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ pinctrl-0 = <&user_button_pins>; -+ pinctrl-names = "default"; -+ -+ button_0 { -+ label = "User Button"; -+ gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; -+ linux,can-disable; -+ linux,code = ; -+ }; -+ }; -+ -+ system-leds { -+ compatible = "gpio-leds"; -+ status-led { -+ label = "helios4:green:status"; -+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "on"; -+ }; -+ -+ fault-led { -+ label = "helios4:red:fault"; -+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; -+ default-state = "keep"; -+ }; -+ }; -+ -+ io-leds { -+ compatible = "gpio-leds"; -+ sata1-led { -+ label = "helios4:green:ata1"; -+ gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "ata1"; -+ default-state = "off"; -+ }; -+ sata2-led { -+ label = "helios4:green:ata2"; -+ gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "ata2"; -+ default-state = "off"; -+ }; -+ sata3-led { -+ label = "helios4:green:ata3"; -+ gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "ata3"; -+ default-state = "off"; -+ }; -+ sata4-led { -+ label = "helios4:green:ata4"; -+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "ata4"; -+ default-state = "off"; -+ }; -+ usb-led { -+ label = "helios4:green:usb"; -+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; -+ linux,default-trigger = "usb-host"; -+ default-state = "off"; -+ }; -+ }; -+ -+ fan1: j10-pwm { -+ compatible = "pwm-fan"; -+ pwms = <&gpio1 9 3000>; -+ }; -+ -+ fan2: j17-pwm { -+ compatible = "pwm-fan"; -+ pwms = <&gpio1 4 4500>; -+ }; -+ -+ usb2_phy: usb2-phy { -+ compatible = "usb-nop-xceiv"; -+ vbus-regulator = <®_5p0v_usb>; -+ }; -+ -+ usb3_phy: usb3-phy { -+ compatible = "usb-nop-xceiv"; -+ //vbus-regulator = <®_5p0v_usb>; -+ }; -+ -+ soc { -+ internal-regs { -+ i2c@11000 { -+ clock-frequency = <100000>; -+ pinctrl-0 = <&i2c0_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ /* -+ * PCA9655 GPIO expander, up to 1MHz clock. -+ * 0-Board Revision bit 0 # -+ * 1-Board Revision bit 1 # -+ * 5-USB3 overcurrent -+ * 6-USB3 power -+ */ -+ expander0: gpio-expander@20 { -+ /* -+ * This is how it should be: -+ * compatible = "onnn,pca9655", -+ * "nxp,pca9555"; -+ * but you can't do this because of -+ * the way I2C works. -+ */ -+ compatible = "nxp,pca9555"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ reg = <0x20>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pca0_pins>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ -+ board_rev_bit_0 { -+ gpio-hog; -+ gpios = <0 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "board-rev-0"; -+ }; -+ board_rev_bit_1 { -+ gpio-hog; -+ gpios = <1 GPIO_ACTIVE_LOW>; -+ input; -+ line-name = "board-rev-1"; -+ }; -+ usb3_ilimit { -+ gpio-hog; -+ gpios = <5 GPIO_ACTIVE_HIGH>; -+ input; -+ line-name = "usb-overcurrent-status"; -+ }; -+ }; -+ -+ temp_sensor: temp@4c { -+ compatible = "ti,lm75"; -+ reg = <0x4c>; -+ vcc-supply = <®_3p3v>; -+ }; -+ -+ /* What device at 0x64 ? */ -+ }; -+ -+ i2c@11100 { -+ /* -+ * External I2C Bus for user peripheral -+ */ -+ clock-frequency = <400000>; -+ pinctrl-0 = <&helios_i2c1_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ }; -+ -+ sata@a8000 { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sata0: sata-port@0 { -+ reg = <0>; -+ }; -+ -+ sata1: sata-port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ sata@e0000 { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sata2: sata-port@0 { -+ reg = <0>; -+ }; -+ -+ sata3: sata-port@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ spi@10680 { -+ pinctrl-0 = <&spi1_pins -+ µsom_spi1_cs_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ spi-flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "w25q32", "jedec,spi-nor"; -+ reg = <0>; /* Chip select 0 */ -+ spi-max-frequency = <104000000>; -+ spi-cpha; -+ status = "okay"; -+ }; -+ }; -+ -+ sdhci@d8000 { -+ bus-width = <4>; -+ cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; -+ no-1-8-v; -+ pinctrl-0 = <&helios_sdhci_pins -+ &helios_sdhci_cd_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ vmmc = <®_3p3v>; -+ wp-inverted; -+ }; -+ -+ usb@58000 { -+ //vcc-supply = <®_5p0v_usb>; -+ usb-phy = <&usb2_phy>; -+ status = "okay"; -+ }; -+ -+ usb3@f0000 { -+ status = "okay"; -+ }; -+ -+ usb3@f8000 { -+ status = "okay"; -+ }; -+ -+ pinctrl@18000 { -+ pca0_pins: pca0_pins { -+ marvell,pins = "mpp18"; -+ marvell,function = "gpio"; -+ }; -+ helios_i2c1_pins: i2c1-pins { -+ marvell,pins = "mpp26", "mpp27"; -+ marvell,function = "i2c1"; -+ }; -+ helios_sdhci_cd_pins: helios-sdhci-cd-pins { -+ marvell,pins = "mpp20"; -+ marvell,function = "gpio"; -+ }; -+ helios_sdhci_pins: helios-sdhci-pins { -+ marvell,pins = "mpp21", "mpp28", -+ "mpp37", "mpp38", -+ "mpp39", "mpp40"; -+ marvell,function = "sd0"; -+ }; -+ helios_led_pins: helios-led-pins { -+ marvell,pins = "mpp24", "mpp25", -+ "mpp49", "mpp50", -+ "mpp52", "mpp53", -+ "mpp54"; -+ marvell,function = "gpio"; -+ }; -+ helios_fan_pins: helios-fan-pins { -+ marvell,pins = "mpp41", "mpp43", -+ "mpp48", "mpp55"; -+ marvell,function = "gpio"; -+ }; -+ microsom_spi1_cs_pins: spi1-cs-pins { -+ marvell,pins = "mpp59"; -+ marvell,function = "spi1"; -+ }; -+ user_button_pins: user-button-pins { -+ marvell,pins = "mpp23"; -+ marvell,function = "gpio"; -+ }; -+ }; -+ }; -+ }; -+}; From 945572718a0c0ea6b7fcd6b2cfae03368da3de42 Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sun, 7 Jan 2018 13:24:34 +0800 Subject: [PATCH 13/20] Helios4 intergation cleanup - move fancontrol install under a family_tweak func - remove unused helios4 bootenv and bootscript - clean-up patches --- config/bootenv/helios4-next.txt | 3 - config/bootscripts/boot-helios4.cmd | 37 -- ...u-boot-clearfog.inc => mvebu-clearfog.inc} | 0 config/sources/mvebu-helios4.inc | 33 ++ config/sources/mvebu-u-boot-helios4.inc | 15 - config/sources/mvebu.conf | 7 +- config/templates/customize-image.sh.template | 58 --- packages/bsp/helios4/fancontrol.patch | 12 + packages/bsp/helios4/fancontrol_gpio-fan.conf | 12 + packages/bsp/helios4/fancontrol_pwm-fan.conf | 11 + ...ebu-Add-limited-PWM-support.patch.disabled | 488 ------------------ ...perties-to-.dtsi-armada-38x.patch.disabled | 62 --- ...t-phy-marvell-88e1510_fixed_led_act.patch} | 0 ...> 94-01-Enable-ATA-port-LED-trigger.patch} | 0 ...=> 94-01-libata-add-ledtrig-support.patch} | 0 ...vebu-Enable-SENSORS_PWM_FAN.patch.disabled | 35 -- .../95-helios4-device-tree.patch | 17 +- ...> 91-02-Enable-ATA-port-LED-trigger.patch} | 0 18 files changed, 83 insertions(+), 707 deletions(-) delete mode 100644 config/bootenv/helios4-next.txt delete mode 100644 config/bootscripts/boot-helios4.cmd rename config/sources/{mvebu-u-boot-clearfog.inc => mvebu-clearfog.inc} (100%) create mode 100644 config/sources/mvebu-helios4.inc delete mode 100644 config/sources/mvebu-u-boot-helios4.inc create mode 100644 packages/bsp/helios4/fancontrol.patch create mode 100644 packages/bsp/helios4/fancontrol_gpio-fan.conf create mode 100644 packages/bsp/helios4/fancontrol_pwm-fan.conf delete mode 100644 patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled delete mode 100644 patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled rename patch/kernel/mvebu-default/{96-net-phy-marvell-88e1510_fixed_led_act.patch => 93-net-phy-marvell-88e1510_fixed_led_act.patch} (100%) rename patch/kernel/mvebu-default/{93-Enable-ATA-port-LED-trigger.patch => 94-01-Enable-ATA-port-LED-trigger.patch} (100%) rename patch/kernel/mvebu-default/{92-libata-add-ledtrig-support.patch => 94-01-libata-add-ledtrig-support.patch} (100%) delete mode 100644 patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled rename patch/kernel/mvebu-next/{91-02--Enable-ATA-port-LED-trigger.patch => 91-02-Enable-ATA-port-LED-trigger.patch} (100%) diff --git a/config/bootenv/helios4-next.txt b/config/bootenv/helios4-next.txt deleted file mode 100644 index 682c692d2..000000000 --- a/config/bootenv/helios4-next.txt +++ /dev/null @@ -1,3 +0,0 @@ -verbosity=1 -ethaddr=00:50:43:84:fb:2f - diff --git a/config/bootscripts/boot-helios4.cmd b/config/bootscripts/boot-helios4.cmd deleted file mode 100644 index 7c0ea6aaf..000000000 --- a/config/bootscripts/boot-helios4.cmd +++ /dev/null @@ -1,37 +0,0 @@ -# DO NOT EDIT THIS FILE -# -# Please edit /boot/armbianEnv.txt to set supported parameters -# - -# default values -setenv rootdev "/dev/mmcblk0p1" -setenv rootfstype "ext4" -setenv verbosity "1" -setenv ethaddr "00:50:43:84:fb:2f" - -# fdtfile should come from compile-time u-boot patches -if test -z "${fdtfile}"; then - setenv fdtfile "armada-388-helios4.dtb" -fi - -test -z "${boot_interface}" && setenv boot_interface "mmc" - -echo "Boot script loaded from ${boot_interface}" - -if load ${boot_interface} 0:1 ${loadaddr} ${prefix}armbianEnv.txt; then - env import -t ${loadaddr} ${filesize} -fi - -setenv bootargs "console=ttyS0,115200 root=${rootdev} rootwait rootfstype=${rootfstype} ubootdev=${boot_interface} scandelay loglevel=${verbosity} ${extraargs}" - -load ${boot_interface} 0:1 ${fdt_addr} ${prefix}dtb/${fdtfile} -load ${boot_interface} 0:1 ${ramdisk_addr_r} ${prefix}uInitrd -load ${boot_interface} 0:1 ${kernel_addr_r} ${prefix}zImage - -setenv fdt_high 0xffffffff -setenv initrd_high 0xffffffff - -bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr} - -# Recompile with: -# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr diff --git a/config/sources/mvebu-u-boot-clearfog.inc b/config/sources/mvebu-clearfog.inc similarity index 100% rename from config/sources/mvebu-u-boot-clearfog.inc rename to config/sources/mvebu-clearfog.inc diff --git a/config/sources/mvebu-helios4.inc b/config/sources/mvebu-helios4.inc new file mode 100644 index 000000000..e88826109 --- /dev/null +++ b/config/sources/mvebu-helios4.inc @@ -0,0 +1,33 @@ +case $BRANCH in + default|next) + BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git' + BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4' + BOOTDIR='u-boot-armada' + BOOTSCRIPT='boot-marvell.cmd:boot.cmd' + + UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc" + + UBOOT_USE_GCC='== 4.9' + UBOOT_COMPILER='arm-linux-gnueabi-' + + BOOTPATCHDIR='u-boot-helios4' + ;; +esac + + +# Helios4 tweak : install and configure fancontrol +family_tweaks_s() +{ + chroot $SDCARD /bin/bash -c "apt-get -y -qq install fancontrol >/dev/null 2>&1" + case $BRANCH in + default) + cp -R $SRC/packages/bsp/helios4/fancontrol_gpio-fan.conf $SDCARD/etc/fancontrol + ;; + + next) + cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan.conf $SDCARD/etc/fancontrol + patch $SDCARD/usr/sbin/fancontrol < $SRC/packages/bsp/helios4/fancontrol.patch + ;; + esac +} + diff --git a/config/sources/mvebu-u-boot-helios4.inc b/config/sources/mvebu-u-boot-helios4.inc deleted file mode 100644 index cdf276ede..000000000 --- a/config/sources/mvebu-u-boot-helios4.inc +++ /dev/null @@ -1,15 +0,0 @@ -case $BRANCH in - default|next) - BOOTSOURCE='https://github.com/helios-4/u-boot-marvell.git' - BOOTBRANCH='branch:u-boot-2013.01-15t1-helios4' - BOOTDIR='u-boot-armada' - BOOTSCRIPT='boot-marvell.cmd:boot.cmd' - - UBOOT_TARGET_MAP="u-boot.mmc;;u-boot.mmc" - - UBOOT_USE_GCC='== 4.9' - UBOOT_COMPILER='arm-linux-gnueabi-' - - BOOTPATCHDIR='u-boot-helios4' - ;; -esac diff --git a/config/sources/mvebu.conf b/config/sources/mvebu.conf index 810336dc8..e16e0845e 100644 --- a/config/sources/mvebu.conf +++ b/config/sources/mvebu.conf @@ -1,10 +1,10 @@ HAS_UUID_SUPPORT=yes if [[ $BOARD == helios4 ]]; then - source "${BASH_SOURCE%/*}/mvebu-u-boot-helios4.inc" + source "${BASH_SOURCE%/*}/mvebu-helios4.inc" BOOTENV_FILE='helios4-default.txt' else - source "${BASH_SOURCE%/*}/mvebu-u-boot-clearfog.inc" + source "${BASH_SOURCE%/*}/mvebu-clearfog.inc" BOOTENV_FILE='clearfog-default.txt' fi @@ -57,5 +57,8 @@ write_uboot_platform() family_tweaks() { + # execute specific tweaks function if present + [[ $(type -t family_tweaks_s) == function ]] && family_tweaks_s + chroot $SDCARD /bin/bash -c "apt-get -y -qq remove --auto-remove linux-sound-base alsa-base alsa-utils bluez>/dev/null 2>&1" } diff --git a/config/templates/customize-image.sh.template b/config/templates/customize-image.sh.template index ae81d7eda..285de0d35 100644 --- a/config/templates/customize-image.sh.template +++ b/config/templates/customize-image.sh.template @@ -20,7 +20,6 @@ Main() { case $RELEASE in jessie) # your code here - # InstallFanControl # uncomment to install fancontrol # InstallOpenMediaVault # uncomment to get an OMV 3 image ;; xenial) @@ -28,7 +27,6 @@ Main() { ;; stretch) # your code here - # InstallFanControl # uncomment to install fancontrol # InstallOpenMediaVault # uncomment to get an OMV 4 image ;; esac @@ -205,61 +203,5 @@ InstallOpenMediaVault() { chage -d 0 root } # InstallOpenMediaVault - -InstallFanControl() { - apt-get update - apt-get --yes install fancontrol - if [ "${BOARD}" = "helios4" ]; then - case ${RELEASE} in - jessie) - cat > /etc/fancontrol <<-EOF - # Helios4 GPIO Fan Control Configuration - # This is a temporary configuration while relying on gpio-fan driver. - # Only low or full speed is supported. - # Temp source : lm75 sensor - INTERVAL=10 - DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c - DEVNAME=hwmon0=gpio_fan hwmon1=gpio_fan hwmon2=lm75 - FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input - MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 - MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 - MINSTART=hwmon0/pwm1=1 hwmon1/pwm1=1 - MINSTOP=hwmon0/pwm1=0 hwmon1/pwm1=0 - EOF - ;; - stretch) - cat > /etc/fancontrol <<-EOF - # Helios4 PWM Fan Control Configuration - # Temp source : armada_thermal sensor - INTERVAL=10 - DEVPATH=hwmon1=devices/virtual hwmon2=devices/platform/j10-pwm hwmon3=devices/platform/j17-pwm hwmon4=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c - DEVNAME=hwmon1=armada_thermal hwmon2=pwmfan hwmon3=pwmfan hwmon4=lm75 - FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input - MINTEMP=hwmon2/pwm1=55 hwmon3/pwm1=55 - MAXTEMP=hwmon2/pwm1=95 hwmon3/pwm1=95 - MINSTART=hwmon2/pwm1=100 hwmon3/pwm1=100 - MINSTOP=hwmon2/pwm1=50 hwmon3/pwm1=50 - EOF - - # Patching fancontrol - patch -b /usr/sbin/fancontrol <<-'EOF' - @@ -157,9 +157,9 @@ - - function DevicePath() - { - - if [ -h "$1/device" ] - + if [ -h "$1" ] - then - - readlink -f "$1/device" | sed -e 's/^\/sys\///' - + readlink -f "$1" | sed -e 's/^\/sys\///;s/\/hwmon\/.*//' - fi - } - - EOF - ;; - esac - fi -} # InstallFanControl - Main "$@" diff --git a/packages/bsp/helios4/fancontrol.patch b/packages/bsp/helios4/fancontrol.patch new file mode 100644 index 000000000..ce9ee7670 --- /dev/null +++ b/packages/bsp/helios4/fancontrol.patch @@ -0,0 +1,12 @@ +@@ -157,9 +157,9 @@ + + function DevicePath() + { +- if [ -h "$1/device" ] ++ if [ -h "$1" ] + then +- readlink -f "$1/device" | sed -e 's/^\/sys\///' ++ readlink -f "$1" | sed -e 's/^\/sys\///;s/\/hwmon\/.*//' + fi + } + diff --git a/packages/bsp/helios4/fancontrol_gpio-fan.conf b/packages/bsp/helios4/fancontrol_gpio-fan.conf new file mode 100644 index 000000000..556c823c4 --- /dev/null +++ b/packages/bsp/helios4/fancontrol_gpio-fan.conf @@ -0,0 +1,12 @@ +# Helios4 GPIO Fan Control Configuration +# This is a temporary configuration while relying on gpio-fan driver. +# Only low or full speed is supported. +# Temp source : lm75 sensor +INTERVAL=10 +DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c +DEVNAME=hwmon0=gpio_fan hwmon1=gpio_fan hwmon2=lm75 +FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input +MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 +MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 +MINSTART=hwmon0/pwm1=1 hwmon1/pwm1=1 +MINSTOP=hwmon0/pwm1=0 hwmon1/pwm1=0 diff --git a/packages/bsp/helios4/fancontrol_pwm-fan.conf b/packages/bsp/helios4/fancontrol_pwm-fan.conf new file mode 100644 index 000000000..9bd9dc181 --- /dev/null +++ b/packages/bsp/helios4/fancontrol_pwm-fan.conf @@ -0,0 +1,11 @@ +# Helios4 PWM Fan Control Configuration +# Temp source : armada_thermal sensor +INTERVAL=10 +DEVPATH=hwmon1=devices/virtual hwmon2=devices/platform/j10-pwm hwmon3=devices/platform/j17-pwm hwmon4=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c +DEVNAME=hwmon1=armada_thermal hwmon2=pwmfan hwmon3=pwmfan hwmon4=lm75 +FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input +MINTEMP=hwmon2/pwm1=55 hwmon3/pwm1=55 +MAXTEMP=hwmon2/pwm1=95 hwmon3/pwm1=95 +MINSTART=hwmon2/pwm1=100 hwmon3/pwm1=100 +MINSTOP=hwmon2/pwm1=50 hwmon3/pwm1=50 + diff --git a/patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled b/patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled deleted file mode 100644 index 045c82886..000000000 --- a/patch/kernel/mvebu-default/90-gpio-mvebu-Add-limited-PWM-support.patch.disabled +++ /dev/null @@ -1,488 +0,0 @@ -From 65bce3cd01230b283915be86196f5e1318c18dd6 Mon Sep 17 00:00:00 2001 -From: aprayoga -Date: Sun, 3 Sep 2017 15:59:11 +0800 -Subject: gpio: mvebu: Add limited PWM support - -backported from https://patchwork.kernel.org/patch/9681399/ - -* Remove atomic PWM API portion as this is not supported on LK4.4 -and use https://patchwork.ozlabs.org/patch/739591/ instead. ---- - .../devicetree/bindings/gpio/gpio-mvebu.txt | 31 +++ - MAINTAINERS | 2 + - drivers/gpio/gpio-mvebu.c | 309 ++++++++++++++++++++- - 3 files changed, 328 insertions(+), 14 deletions(-) - -diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt -index 6b76891..b6cdcb2 100644 ---- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt -+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.txt -@@ -46,6 +46,23 @@ Optional: - The base of CP0 bank0 should be 20 (after AP-806 pins) the base of CP0 bank1 should be - 52 (after AP-806, and CP0 bank0 pins) - -+Optional properties: -+ -+In order to use the gpio lines in PWM mode, some additional optional -+properties are required. Only Armada 370 and XP support these properties. -+ -+- reg: an additional register set is needed, for the GPIO Blink -+ Counter on/off registers. -+ -+- reg-names: Must contain an entry "pwm" corresponding to the -+ additional register range needed for pwm operation. -+ -+- #pwm-cells: Should be two. The first cell is the pin number. The -+ second cell is reserved for flags and should be set to 0, so it has a -+ known value. It then becomes possible to use it in the future. -+ -+- clocks: Must be a phandle to the clock for the gpio controller. -+ - Example: - - gpio0: gpio@d0018100 { -@@ -59,3 +76,17 @@ Example: - #interrupt-cells = <2>; - interrupts = <16>, <17>, <18>, <19>; - }; -+ -+ gpio1: gpio@18140 { -+ compatible = "marvell,armada-370-xp-gpio"; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; -+ ngpios = <17>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ #pwm-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ interrupts = <87>, <88>, <89>; -+ clocks = <&coreclk 0>; -+ }; -diff --git a/MAINTAINERS b/MAINTAINERS -index 7008b0d..d272aca 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -8635,6 +8635,8 @@ F: include/linux/pwm.h - F: drivers/pwm/ - F: drivers/video/backlight/pwm_bl.c - F: include/linux/pwm_backlight.h -+F: drivers/gpio/gpio-mvebu.c -+F: Documentation/devicetree/bindings/gpio/gpio-mvebu.txt - - PXA2xx/PXA3xx SUPPORT - M: Daniel Mack -diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c -index ffea532..8775123 100644 ---- a/drivers/gpio/gpio-mvebu.c -+++ b/drivers/gpio/gpio-mvebu.c -@@ -42,29 +42,43 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include -+ -+#include "gpiolib.h" - - /* - * GPIO unit register offsets. - */ --#define GPIO_OUT_OFF 0x0000 --#define GPIO_IO_CONF_OFF 0x0004 --#define GPIO_BLINK_EN_OFF 0x0008 --#define GPIO_IN_POL_OFF 0x000c --#define GPIO_DATA_IN_OFF 0x0010 --#define GPIO_EDGE_CAUSE_OFF 0x0014 --#define GPIO_EDGE_MASK_OFF 0x0018 --#define GPIO_LEVEL_MASK_OFF 0x001c -+#define GPIO_OUT_OFF 0x0000 -+#define GPIO_IO_CONF_OFF 0x0004 -+#define GPIO_BLINK_EN_OFF 0x0008 -+#define GPIO_IN_POL_OFF 0x000c -+#define GPIO_DATA_IN_OFF 0x0010 -+#define GPIO_EDGE_CAUSE_OFF 0x0014 -+#define GPIO_EDGE_MASK_OFF 0x0018 -+#define GPIO_LEVEL_MASK_OFF 0x001c -+#define GPIO_BLINK_CNT_SELECT_OFF 0x0020 -+ -+/* -+ * PWM register offsets. -+ */ -+#define PWM_BLINK_ON_DURATION_OFF 0x0 -+#define PWM_BLINK_OFF_DURATION_OFF 0x4 -+ - - /* The MV78200 has per-CPU registers for edge mask and level mask */ - #define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18) - #define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C) - --/* The Armada XP has per-CPU registers for interrupt cause, interrupt -+/* -+ * The Armada XP has per-CPU registers for interrupt cause, interrupt - * mask and interrupt level mask. Those are relative to the -- * percpu_membase. */ -+ * percpu_membase. -+ */ - #define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4) - #define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4) - #define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4) -@@ -75,6 +89,23 @@ - - #define MVEBU_MAX_GPIO_PER_BANK 32 - -+struct mvebu_pwm { -+ void __iomem *membase; -+ unsigned long clk_rate; -+ struct gpio_desc *gpiod; -+ bool used; -+ unsigned int pin; -+ struct pwm_chip chip; -+ int id; -+ spinlock_t lock; -+ struct mvebu_gpio_chip *mvchip; -+ -+ /* Used to preserve GPIO/PWM registers across suspend/resume */ -+ u32 blink_select; -+ u32 blink_on_duration; -+ u32 blink_off_duration; -+}; -+ - struct mvebu_gpio_chip { - struct gpio_chip chip; - spinlock_t lock; -@@ -84,6 +115,10 @@ struct mvebu_gpio_chip { - struct irq_domain *domain; - int soc_variant; - -+ /* Used for PWM support */ -+ struct clk *clk; -+ struct mvebu_pwm *mvpwm; -+ - /* Used to preserve GPIO registers across suspend/resume */ - u32 out_reg; - u32 io_conf_reg; -@@ -102,6 +137,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) - return mvchip->membase + GPIO_OUT_OFF; - } - -+static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip) -+{ -+ return mvchip->membase + GPIO_BLINK_CNT_SELECT_OFF; -+} -+ - static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) - { - return mvchip->membase + GPIO_BLINK_EN_OFF; -@@ -182,6 +222,20 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) - } - - /* -+ * Functions returning addresses of individual registers for a given -+ * PWM controller. -+ */ -+static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwm *mvpwm) -+{ -+ return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF; -+} -+ -+static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwm *mvpwm) -+{ -+ return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF; -+} -+ -+/* - * Functions implementing the gpio_chip methods - */ - -@@ -489,6 +543,220 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) - chained_irq_exit(chip, desc); - } - -+/* -+ * Functions implementing the pwm_chip methods -+ */ -+static struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip) -+{ -+ return container_of(chip, struct mvebu_pwm, chip); -+} -+ -+static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; -+ struct gpio_desc *desc; -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&mvpwm->lock, flags); -+ if (mvpwm->gpiod) { -+ ret = -EBUSY; -+ } else { -+ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm); -+ if (!desc) { -+ ret = -ENODEV; -+ goto out; -+ } -+ ret = gpiod_request(desc, "mvebu-pwm"); -+ if (ret) -+ goto out; -+ -+ ret = gpiod_direction_output(desc, 0); -+ if (ret) { -+ gpiod_free(desc); -+ goto out; -+ } -+ -+ mvpwm->gpiod = desc; -+ mvpwm->pin = pwm->pwm - mvchip->chip.base; -+ mvpwm->used = true; -+ } -+ -+out: -+ spin_unlock_irqrestore(&mvpwm->lock, flags); -+ return ret; -+} -+ -+static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&mvpwm->lock, flags); -+ gpiod_free(mvpwm->gpiod); -+ mvpwm->used = false; -+ spin_unlock_irqrestore(&mvpwm->lock, flags); -+} -+ -+static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd, -+ int duty_ns, int period_ns) -+{ -+ struct mvebu_pwm *pwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = pwm->mvchip; -+ unsigned int on, off; -+ unsigned long long val; -+ u32 u; -+ -+ val = (unsigned long long) pwm->clk_rate * duty_ns; -+ do_div(val, NSEC_PER_SEC); -+ if (val > UINT_MAX) -+ return -EINVAL; -+ if (val) -+ on = val; -+ else -+ on = 1; -+ -+ val = (unsigned long long) pwm->clk_rate * (period_ns - duty_ns); -+ do_div(val, NSEC_PER_SEC); -+ if (val > UINT_MAX) -+ return -EINVAL; -+ if (val) -+ off = val; -+ else -+ off = 1; -+ -+ u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); -+ u &= ~(1 << pwm->pin); -+ u |= (pwm->id << pwm->pin); -+ writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip)); -+ -+ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(pwm)); -+ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(pwm)); -+ -+ return 0; -+} -+ -+static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; -+ -+ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 1); -+ -+ return 0; -+} -+ -+static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); -+ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; -+ -+ mvebu_gpio_blink(&mvchip->chip, mvpwm->pin, 0); -+} -+ -+static const struct pwm_ops mvebu_pwm_ops = { -+ .request = mvebu_pwm_request, -+ .free = mvebu_pwm_free, -+ .config = mvebu_pwm_config, -+ .enable = mvebu_pwm_enable, -+ .disable = mvebu_pwm_disable, -+ .owner = THIS_MODULE, -+}; -+ -+static void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) -+{ -+ struct mvebu_pwm *mvpwm = mvchip->mvpwm; -+ -+ mvpwm->blink_select = -+ readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); -+ mvpwm->blink_on_duration = -+ readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); -+ mvpwm->blink_off_duration = -+ readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); -+} -+ -+static void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) -+{ -+ struct mvebu_pwm *mvpwm = mvchip->mvpwm; -+ -+ writel_relaxed(mvpwm->blink_select, -+ mvebu_gpioreg_blink_select(mvchip)); -+ writel_relaxed(mvpwm->blink_on_duration, -+ mvebu_pwmreg_blink_on_duration(mvpwm)); -+ writel_relaxed(mvpwm->blink_off_duration, -+ mvebu_pwmreg_blink_off_duration(mvpwm)); -+} -+ -+/* -+ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs -+ * don't have this hardware. So if we don't have the necessary -+ * resource, it is not an error. -+ */ -+static int mvebu_pwm_probe(struct platform_device *pdev, -+ struct mvebu_gpio_chip *mvchip, -+ int id) -+{ -+ struct device *dev = &pdev->dev; -+ struct mvebu_pwm *mvpwm; -+ struct resource *res; -+ u32 set; -+ -+ if (!of_device_is_compatible(mvchip->chip.of_node, -+ "marvell,armada-370-xp-gpio")) -+ return 0; -+ -+ if (IS_ERR(mvchip->clk)) -+ return PTR_ERR(mvchip->clk); -+ -+ /* -+ * There are only two sets of PWM configuration registers for -+ * all the GPIO lines on those SoCs which this driver reserves -+ * for the first two GPIO chips. So if the resource is missing -+ * we can't treat it as an error. -+ */ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); -+ if (!res) -+ return 0; -+ -+ /* -+ * Use set A for lines of GPIO chip with id 0, B for GPIO chip -+ * with id 1. Don't allow further GPIO chips to be used for PWM. -+ */ -+ if (id == 0) -+ set = 0; -+ else if (id == 1) -+ set = U32_MAX; -+ else -+ return -EINVAL; -+ writel_relaxed(set, mvebu_gpioreg_blink_select(mvchip)); -+ mvpwm->id = id; -+ -+ mvpwm = devm_kzalloc(dev, sizeof(struct mvebu_pwm), GFP_KERNEL); -+ if (!mvpwm) -+ return -ENOMEM; -+ mvchip->mvpwm = mvpwm; -+ mvpwm->mvchip = mvchip; -+ -+ mvpwm->membase = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mvpwm->membase)) -+ return PTR_ERR(mvpwm->membase); -+ -+ mvpwm->clk_rate = clk_get_rate(mvchip->clk); -+ if (!mvpwm->clk_rate) { -+ dev_err(dev, "failed to get clock rate\n"); -+ return -EINVAL; -+ } -+ -+ mvpwm->chip.dev = dev; -+ mvpwm->chip.ops = &mvebu_pwm_ops; -+ mvpwm->chip.npwm = mvchip->chip.ngpio; -+ -+ spin_lock_init(&mvpwm->lock); -+ -+ return pwmchip_add(&mvpwm->chip); -+} -+ - #ifdef CONFIG_DEBUG_FS - #include - -@@ -561,6 +829,10 @@ static const struct of_device_id mvebu_gpio_of_match[] = { - .data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP, - }, - { -+ .compatible = "marvell,armada-370-xp-gpio", -+ .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION, -+ }, -+ { - /* sentinel */ - }, - }; -@@ -607,6 +879,9 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state) - BUG(); - } - -+ if (IS_ENABLED(CONFIG_PWM)) -+ mvebu_pwm_suspend(mvchip); -+ - return 0; - } - -@@ -650,6 +925,9 @@ static int mvebu_gpio_resume(struct platform_device *pdev) - BUG(); - } - -+ if (IS_ENABLED(CONFIG_PWM)) -+ mvebu_pwm_resume(mvchip); -+ - return 0; - } - -@@ -661,7 +939,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) - struct resource *res; - struct irq_chip_generic *gc; - struct irq_chip_type *ct; -- struct clk *clk; - unsigned int ngpios; - unsigned int gpio_base = -1; - int soc_variant; -@@ -695,10 +972,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) - return id; - } - -- clk = devm_clk_get(&pdev->dev, NULL); -+ mvchip->clk = devm_clk_get(&pdev->dev, NULL); - /* Not all SoCs require a clock.*/ -- if (!IS_ERR(clk)) -- clk_prepare_enable(clk); -+ if (!IS_ERR(mvchip->clk)) -+ clk_prepare_enable(mvchip->clk); - - mvchip->soc_variant = soc_variant; - mvchip->chip.label = dev_name(&pdev->dev); -@@ -835,6 +1112,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) - goto err_generic_chip; - } - -+ /* Armada 370/XP has simple PWM support for GPIO lines */ -+ if (IS_ENABLED(CONFIG_PWM)) -+ return mvebu_pwm_probe(pdev, mvchip, id); -+ - return 0; - - err_generic_chip: --- -2.7.4 - diff --git a/patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled b/patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled deleted file mode 100644 index e19aa068d..000000000 --- a/patch/kernel/mvebu-default/91-ARM-dts-mvebu-Add-PWM-properties-to-.dtsi-armada-38x.patch.disabled +++ /dev/null @@ -1,62 +0,0 @@ -From e85a492b45f49e374f544bbffe8c975b1dabe87f Mon Sep 17 00:00:00 2001 -From: aprayoga -Date: Sun, 3 Sep 2017 16:08:59 +0800 -Subject: ARM: dts: mvebu: Add PWM properties to .dtsi (armada-38x) - -reference: -https://patchwork.kernel.org/patch/9681397/ ---- - arch/arm/boot/dts/armada-38x.dtsi | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi -index a73cbe2..f87204f 100644 ---- a/arch/arm/boot/dts/armada-38x.dtsi -+++ b/arch/arm/boot/dts/armada-38x.dtsi -@@ -345,31 +345,39 @@ - }; - - gpio0: gpio@18100 { -- compatible = "marvell,orion-gpio"; -- reg = <0x18100 0x40>; -+ compatible = "marvell,armada-370-xp-gpio", -+ "marvell,orion-gpio"; -+ reg = <0x18100 0x40>, <0x181c0 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = , - , - , - ; -+ clocks = <&coreclk 0>; - }; - - gpio1: gpio@18140 { -- compatible = "marvell,orion-gpio"; -- reg = <0x18140 0x40>; -+ compatible = "marvell,armada-370-xp-gpio", -+ "marvell,orion-gpio"; -+ reg = <0x18140 0x40>, <0x181c8 0x08>; -+ reg-names = "gpio", "pwm"; - ngpios = <28>; - gpio-controller; - #gpio-cells = <2>; -+ #pwm-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = , - , - , - ; -+ clocks = <&coreclk 0>; - }; - - system-controller@18200 { --- -2.7.4 - diff --git a/patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch b/patch/kernel/mvebu-default/93-net-phy-marvell-88e1510_fixed_led_act.patch similarity index 100% rename from patch/kernel/mvebu-default/96-net-phy-marvell-88e1510_fixed_led_act.patch rename to patch/kernel/mvebu-default/93-net-phy-marvell-88e1510_fixed_led_act.patch diff --git a/patch/kernel/mvebu-default/93-Enable-ATA-port-LED-trigger.patch b/patch/kernel/mvebu-default/94-01-Enable-ATA-port-LED-trigger.patch similarity index 100% rename from patch/kernel/mvebu-default/93-Enable-ATA-port-LED-trigger.patch rename to patch/kernel/mvebu-default/94-01-Enable-ATA-port-LED-trigger.patch diff --git a/patch/kernel/mvebu-default/92-libata-add-ledtrig-support.patch b/patch/kernel/mvebu-default/94-01-libata-add-ledtrig-support.patch similarity index 100% rename from patch/kernel/mvebu-default/92-libata-add-ledtrig-support.patch rename to patch/kernel/mvebu-default/94-01-libata-add-ledtrig-support.patch diff --git a/patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled b/patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled deleted file mode 100644 index 5180ec9a1..000000000 --- a/patch/kernel/mvebu-default/94-ARM-mvebu-Enable-SENSORS_PWM_FAN.patch.disabled +++ /dev/null @@ -1,35 +0,0 @@ -From facb61a995ceac9b307159f0eb1e8666ce353ef0 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Fri, 14 Apr 2017 17:40:54 +0200 -Subject: ARM: mvebu: Enable SENSORS_PWM_FAN in defconfig - -Now that the GPIO driver also supports PWM operation, enable the PWM -framework and fan driver in mvebu_v7_defconfig. - -Signed-off-by: Andrew Lunn -URL: https://patchwork.ozlabs.org/patch/427297/ -[Ralph Sennhauser: add fan driver to defconfig] -Signed-off-by: Ralph Sennhauser -Tested-by: Andrew Lunn -Acked-by: Linus Walleij -Signed-off-by: Gregory CLEMENT ---- - arch/arm/configs/mvebu_v7_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig -index cf363ab..98cc3da 100644 ---- a/arch/arm/configs/mvebu_v7_defconfig -+++ b/arch/arm/configs/mvebu_v7_defconfig -@@ -132,6 +132,8 @@ CONFIG_DMADEVICES=y - CONFIG_MV_XOR=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_MEMORY=y -+CONFIG_PWM=y -+CONFIG_SENSORS_PWM_FAN=y - CONFIG_EXT4_FS=y - CONFIG_ISO9660_FS=y - CONFIG_JOLIET=y --- -2.7.4 - diff --git a/patch/kernel/mvebu-default/95-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch index b71509555..94d42c984 100644 --- a/patch/kernel/mvebu-default/95-helios4-device-tree.patch +++ b/patch/kernel/mvebu-default/95-helios4-device-tree.patch @@ -8,12 +8,11 @@ Subject: Initial device tree - All 7 LED declared as led-gpio - LED1 (system) default to hearbeat - LED7 (USB) triggered by USB Host activity -- GPIO23 (MPP23) declared as GPIO button - SPI NOR flash declared as MTD - Enable IO expander interrupt - Allocate GPIOs for fans --- - arch/arm/boot/dts/armada-388-helios4.dts | 329 +++++++++++++++++++++ + arch/arm/boot/dts/armada-388-helios4.dts | 333 +++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 arch/arm/boot/dts/armada-388-helios4.dts @@ -22,7 +21,7 @@ new file mode 100644 index 0000000..19a0256 --- /dev/null +++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -0,0 +1,329 @@ +@@ -0,0 +1,333 @@ +/* + * Device Tree file for Helios4 + * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) @@ -143,13 +142,17 @@ index 0000000..19a0256 + }; + + fan1: j10-pwm { -+ compatible = "pwm-fan"; -+ pwms = <&gpio1 9 3800>; ++ compatible = "gpio-fan"; ++ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; ++ gpio-fan,speed-map = < 0 0 ++ 3800 1>; + }; + + fan2: j17-pwm { -+ compatible = "pwm-fan"; -+ pwms = <&gpio1 23 3800>; ++ compatible = "gpio-fan"; ++ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; ++ gpio-fan,speed-map = < 0 0 ++ 3800 1>; + }; + + usb2_phy: usb2-phy { diff --git a/patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch b/patch/kernel/mvebu-next/91-02-Enable-ATA-port-LED-trigger.patch similarity index 100% rename from patch/kernel/mvebu-next/91-02--Enable-ATA-port-LED-trigger.patch rename to patch/kernel/mvebu-next/91-02-Enable-ATA-port-LED-trigger.patch From ead4b8fb4e6a0c2f1a856229a98de72bbac98a37 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Sun, 4 Feb 2018 05:10:57 +0800 Subject: [PATCH 14/20] dts, restore pwm-fan --- .../95-helios4-device-tree.patch | 14 ++++------ ...-helios4-gpio-fan_instead_of_pwm-fan.patch | 26 ------------------- 2 files changed, 5 insertions(+), 35 deletions(-) delete mode 100644 patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch diff --git a/patch/kernel/mvebu-default/95-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch index 94d42c984..cedf27992 100644 --- a/patch/kernel/mvebu-default/95-helios4-device-tree.patch +++ b/patch/kernel/mvebu-default/95-helios4-device-tree.patch @@ -21,7 +21,7 @@ new file mode 100644 index 0000000..19a0256 --- /dev/null +++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -0,0 +1,333 @@ +@@ -0,0 +1,329 @@ +/* + * Device Tree file for Helios4 + * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) @@ -142,17 +142,13 @@ index 0000000..19a0256 + }; + + fan1: j10-pwm { -+ compatible = "gpio-fan"; -+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; -+ gpio-fan,speed-map = < 0 0 -+ 3800 1>; ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 9 3800>; + }; + + fan2: j17-pwm { -+ compatible = "gpio-fan"; -+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ gpio-fan,speed-map = < 0 0 -+ 3800 1>; ++ compatible = "pwm-fan"; ++ pwms = <&gpio1 23 3800>; + }; + + usb2_phy: usb2-phy { diff --git a/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch b/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch deleted file mode 100644 index b72ccb00d..000000000 --- a/patch/kernel/mvebu-default/95-helios4-gpio-fan_instead_of_pwm-fan.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts -index ec7a5ce..1075535 100644 ---- a/arch/arm/boot/dts/armada-388-helios4.dts -+++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -131,13 +131,17 @@ - }; - - fan1: j10-pwm { -- compatible = "pwm-fan"; -- pwms = <&gpio1 9 3800>; -+ compatible = "gpio-fan"; -+ gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; -+ gpio-fan,speed-map = < 0 0 -+ 3800 1>; - }; - - fan2: j17-pwm { -- compatible = "pwm-fan"; -- pwms = <&gpio1 23 3800>; -+ compatible = "gpio-fan"; -+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ gpio-fan,speed-map = < 0 0 -+ 3800 1>; - }; - - usb2_phy: usb2-phy { From ad1b0b712f362913a9483b0282248020e7c00d64 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Sun, 4 Feb 2018 08:32:47 +0800 Subject: [PATCH 15/20] mvebu-default, enable pwm-fan module and hardware pwm in gpi-mvebu --- config/kernel/linux-mvebu-default.config | 14 +- ...io-mvebu-enable_hardware_pwm_support.patch | 523 ++++++++++++++++++ 2 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 patch/kernel/mvebu-default/92-gpio-mvebu-enable_hardware_pwm_support.patch diff --git a/config/kernel/linux-mvebu-default.config b/config/kernel/linux-mvebu-default.config index aaa1d5f0d..8a0830549 100644 --- a/config/kernel/linux-mvebu-default.config +++ b/config/kernel/linux-mvebu-default.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.4.99 Kernel Configuration +# Linux/arm 4.4.110 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -3028,6 +3028,7 @@ CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set +CONFIG_SENSORS_PWM_FAN=m # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHTC1 is not set @@ -3276,6 +3277,7 @@ CONFIG_REGULATOR_GPIO=m # CONFIG_REGULATOR_MAX8973 is not set # CONFIG_REGULATOR_MT6311 is not set # CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PWM is not set # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set @@ -3373,11 +3375,14 @@ CONFIG_LCD_LMS501KF03=m CONFIG_LCD_HX8357=m CONFIG_BACKLIGHT_CLASS_DEVICE=m CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_PWM is not set CONFIG_BACKLIGHT_PM8941_WLED=m CONFIG_BACKLIGHT_ADP8860=m CONFIG_BACKLIGHT_ADP8870=m CONFIG_BACKLIGHT_88PM860X=m +# CONFIG_BACKLIGHT_LM3630A is not set CONFIG_BACKLIGHT_LM3639=m +# CONFIG_BACKLIGHT_LP855X is not set CONFIG_BACKLIGHT_GPIO=m CONFIG_BACKLIGHT_LV5207LP=m CONFIG_BACKLIGHT_BD6107=m @@ -3849,6 +3854,7 @@ CONFIG_LEDS_GPIO=m # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set # CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set @@ -4220,6 +4226,7 @@ CONFIG_COMMON_CLK_SCPI=m # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set CONFIG_MVEBU_CLK_COMMON=y @@ -4528,7 +4535,10 @@ CONFIG_IIO_SYSFS_TRIGGER=m # CONFIG_TSYS02D is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set -# CONFIG_PWM is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARMADA_370_XP_IRQ=y diff --git a/patch/kernel/mvebu-default/92-gpio-mvebu-enable_hardware_pwm_support.patch b/patch/kernel/mvebu-default/92-gpio-mvebu-enable_hardware_pwm_support.patch new file mode 100644 index 000000000..9ebe57360 --- /dev/null +++ b/patch/kernel/mvebu-default/92-gpio-mvebu-enable_hardware_pwm_support.patch @@ -0,0 +1,523 @@ + arch/arm/boot/dts/armada-38x.dtsi | 16 +- + drivers/gpio/gpio-mvebu.c | 369 +++++++++++++++++++++++++++-- + 2 files changed, 367 insertions(+), 18 deletions(-) + +diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi +index e4e1546..5894e45 100644 +--- a/arch/arm/boot/dts/armada-38x.dtsi ++++ b/arch/arm/boot/dts/armada-38x.dtsi +@@ -339,31 +339,39 @@ + }; + + gpio0: gpio@18100 { +- compatible = "marvell,orion-gpio"; +- reg = <0x18100 0x40>; ++ compatible = "marvell,armada-370-gpio", ++ "marvell,orion-gpio"; ++ reg = <0x18100 0x40>, <0x181c0 0x08>; ++ reg-names = "gpio", "pwm"; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; ++ #pwm-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + ; ++ clocks = <&coreclk 0>; + }; + + gpio1: gpio@18140 { +- compatible = "marvell,orion-gpio"; +- reg = <0x18140 0x40>; ++ compatible = "marvell,armada-370-gpio", ++ "marvell,orion-gpio"; ++ reg = <0x18140 0x40>, <0x181c8 0x08>; ++ reg-names = "gpio", "pwm"; + ngpios = <28>; + gpio-controller; + #gpio-cells = <2>; ++ #pwm-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + , + ; ++ clocks = <&coreclk 0>; + }; + + system-controller@18200 { +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index ffea532..9fe65f7 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -42,29 +42,43 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include ++ ++#include "gpiolib.h" + + /* + * GPIO unit register offsets. + */ +-#define GPIO_OUT_OFF 0x0000 +-#define GPIO_IO_CONF_OFF 0x0004 +-#define GPIO_BLINK_EN_OFF 0x0008 +-#define GPIO_IN_POL_OFF 0x000c +-#define GPIO_DATA_IN_OFF 0x0010 +-#define GPIO_EDGE_CAUSE_OFF 0x0014 +-#define GPIO_EDGE_MASK_OFF 0x0018 +-#define GPIO_LEVEL_MASK_OFF 0x001c ++#define GPIO_OUT_OFF 0x0000 ++#define GPIO_IO_CONF_OFF 0x0004 ++#define GPIO_BLINK_EN_OFF 0x0008 ++#define GPIO_IN_POL_OFF 0x000c ++#define GPIO_DATA_IN_OFF 0x0010 ++#define GPIO_EDGE_CAUSE_OFF 0x0014 ++#define GPIO_EDGE_MASK_OFF 0x0018 ++#define GPIO_LEVEL_MASK_OFF 0x001c ++#define GPIO_BLINK_CNT_SELECT_OFF 0x0020 ++ ++/* ++ * PWM register offsets. ++ */ ++#define PWM_BLINK_ON_DURATION_OFF 0x0 ++#define PWM_BLINK_OFF_DURATION_OFF 0x4 ++ + + /* The MV78200 has per-CPU registers for edge mask and level mask */ + #define GPIO_EDGE_MASK_MV78200_OFF(cpu) ((cpu) ? 0x30 : 0x18) + #define GPIO_LEVEL_MASK_MV78200_OFF(cpu) ((cpu) ? 0x34 : 0x1C) + +-/* The Armada XP has per-CPU registers for interrupt cause, interrupt ++/* ++ * The Armada XP has per-CPU registers for interrupt cause, interrupt + * mask and interrupt level mask. Those are relative to the +- * percpu_membase. */ ++ * percpu_membase. ++ */ + #define GPIO_EDGE_CAUSE_ARMADAXP_OFF(cpu) ((cpu) * 0x4) + #define GPIO_EDGE_MASK_ARMADAXP_OFF(cpu) (0x10 + (cpu) * 0x4) + #define GPIO_LEVEL_MASK_ARMADAXP_OFF(cpu) (0x20 + (cpu) * 0x4) +@@ -75,6 +89,41 @@ + + #define MVEBU_MAX_GPIO_PER_BANK 32 + ++enum mvebu_pwm_ctrl { ++ MVEBU_PWM_CTRL_SET_A = 0, ++ MVEBU_PWM_CTRL_SET_B, ++ MVEBU_PWM_CTRL_MAX ++}; ++ ++struct mvebu_pwmchip { ++ void __iomem *membase; ++ unsigned long clk_rate; ++ spinlock_t lock; ++ bool in_use; ++ ++ /* Used to preserve GPIO/PWM registers across suspend/resume */ ++ u32 blink_on_duration; ++ u32 blink_off_duration; ++}; ++ ++struct mvebu_pwm_chip_drv { ++ enum mvebu_pwm_ctrl ctrl; ++ struct gpio_desc *gpiod; ++ bool master; ++}; ++ ++struct mvebu_pwm { ++ struct pwm_chip chip; ++ struct mvebu_gpio_chip *mvchip; ++ struct mvebu_pwmchip controller; ++ enum mvebu_pwm_ctrl default_counter; ++ ++ /* Used to preserve GPIO/PWM registers across suspend/resume */ ++ u32 blink_select; ++}; ++ ++static struct mvebu_pwmchip *mvebu_pwm_list[MVEBU_PWM_CTRL_MAX]; ++ + struct mvebu_gpio_chip { + struct gpio_chip chip; + spinlock_t lock; +@@ -84,6 +133,10 @@ struct mvebu_gpio_chip { + struct irq_domain *domain; + int soc_variant; + ++ /* Used for PWM support */ ++ struct clk *clk; ++ struct mvebu_pwm *mvpwm; ++ + /* Used to preserve GPIO registers across suspend/resume */ + u32 out_reg; + u32 io_conf_reg; +@@ -102,6 +155,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) + return mvchip->membase + GPIO_OUT_OFF; + } + ++static void __iomem *mvebu_gpioreg_blink_select(struct mvebu_gpio_chip *mvchip) ++{ ++ return mvchip->membase + GPIO_BLINK_CNT_SELECT_OFF; ++} ++ + static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) + { + return mvchip->membase + GPIO_BLINK_EN_OFF; +@@ -182,6 +240,20 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) + } + + /* ++ * Functions returning addresses of individual registers for a given ++ * PWM controller. ++ */ ++static void __iomem *mvebu_pwmreg_blink_on_duration(struct mvebu_pwmchip *mvpwm) ++{ ++ return mvpwm->membase + PWM_BLINK_ON_DURATION_OFF; ++} ++ ++static void __iomem *mvebu_pwmreg_blink_off_duration(struct mvebu_pwmchip *mvpwm) ++{ ++ return mvpwm->membase + PWM_BLINK_OFF_DURATION_OFF; ++} ++ ++/* + * Functions implementing the gpio_chip methods + */ + +@@ -489,6 +561,262 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + ++/* ++ * Functions implementing the pwm_chip methods ++ */ ++static struct mvebu_pwm *to_mvebu_pwm(struct pwm_chip *chip) ++{ ++ return container_of(chip, struct mvebu_pwm, chip); ++} ++ ++static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ struct gpio_desc *desc; ++ enum mvebu_pwm_ctrl id; ++ int ret = 0; ++ struct mvebu_pwm_chip_drv *chip_data; ++ u32 u; ++ ++ spin_lock(&mvpwm->controller.lock); ++ ++ mvchip->blink_en_reg = readl_relaxed(mvebu_gpioreg_blink(mvchip)); ++ if (pwm->chip_data || (mvchip->blink_en_reg & BIT(pwm->hwpwm))) ++ return -EBUSY; ++ ++ desc = gpio_to_desc(mvchip->chip.base + pwm->hwpwm); ++ if (!desc) { ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ ret = gpiod_request(desc, "mvebu-pwm"); ++ if (ret) ++ goto out; ++ ++ ret = gpiod_direction_output(desc, 0); ++ if (ret) { ++ gpiod_free(desc); ++ goto out; ++ } ++ ++ chip_data = kzalloc(sizeof(struct mvebu_pwm_chip_drv), GFP_KERNEL); ++ if (!chip_data) { ++ gpiod_free(desc); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ for (id = MVEBU_PWM_CTRL_SET_A;id < MVEBU_PWM_CTRL_MAX; id++) { ++ if (!mvebu_pwm_list[id]->in_use) { ++ chip_data->ctrl = id; ++ chip_data->master = true; ++ mvebu_pwm_list[id]->in_use = true; ++ break; ++ } ++ } ++ ++ if (!chip_data->master) ++ chip_data->ctrl = mvpwm->default_counter; ++ ++ u = readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); ++ if (id) ++ u |= (1 << pwm->hwpwm); ++ else ++ u &= ~(1 << pwm->hwpwm); ++ writel_relaxed(u, mvebu_gpioreg_blink_select(mvchip)); ++ ++ chip_data->gpiod = desc; ++ pwm->chip_data = chip_data; ++ mvpwm->blink_select = u; ++out: ++ spin_unlock(&mvpwm->controller.lock); ++ return ret; ++} ++ ++static void mvebu_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwm->chip_data; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&mvpwm->controller.lock, flags); ++ if (chip_data->master) ++ mvebu_pwm_list[chip_data->ctrl]->in_use = false; ++ ++ gpiod_free(chip_data->gpiod); ++ kfree(chip_data); ++ pwm->chip_data = NULL; ++ spin_unlock_irqrestore(&mvpwm->controller.lock, flags); ++} ++ ++static int mvebu_pwm_config(struct pwm_chip *chip, struct pwm_device *pwmd, ++ int duty_ns, int period_ns) ++{ ++ struct mvebu_pwm_chip_drv *chip_data = (struct mvebu_pwm_chip_drv*) pwmd->chip_data; ++ struct mvebu_pwmchip *controller = mvebu_pwm_list[chip_data->ctrl]; ++ unsigned int on, off; ++ unsigned long long val; ++ unsigned long flags; ++ ++ val = (unsigned long long) controller->clk_rate * duty_ns; ++ do_div(val, NSEC_PER_SEC); ++ if (val > UINT_MAX) ++ return -EINVAL; ++ if (val) ++ on = val; ++ else ++ on = 1; ++ ++ val = (unsigned long long) controller->clk_rate * (period_ns - duty_ns); ++ do_div(val, NSEC_PER_SEC); ++ if (val > UINT_MAX) ++ return -EINVAL; ++ if (val) ++ off = val; ++ else ++ off = 1; ++ ++ spin_lock_irqsave(&controller->lock, flags); ++ writel_relaxed(on, mvebu_pwmreg_blink_on_duration(controller)); ++ writel_relaxed(off, mvebu_pwmreg_blink_off_duration(controller)); ++ spin_unlock_irqrestore(&controller->lock, flags); ++ ++ return 0; ++} ++ ++static int mvebu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ ++ mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 1); ++ ++ return 0; ++} ++ ++static void mvebu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mvebu_pwm *mvpwm = to_mvebu_pwm(chip); ++ struct mvebu_gpio_chip *mvchip = mvpwm->mvchip; ++ ++ mvebu_gpio_blink(&mvchip->chip, pwm->hwpwm, 0); ++} ++ ++static const struct pwm_ops mvebu_pwm_ops = { ++ .request = mvebu_pwm_request, ++ .free = mvebu_pwm_free, ++ .config = mvebu_pwm_config, ++ .enable = mvebu_pwm_enable, ++ .disable = mvebu_pwm_disable, ++ .owner = THIS_MODULE, ++}; ++ ++static void mvebu_pwm_suspend(struct mvebu_gpio_chip *mvchip) ++{ ++ struct mvebu_pwm *mvpwm = mvchip->mvpwm; ++ ++ mvpwm->blink_select = ++ readl_relaxed(mvebu_gpioreg_blink_select(mvchip)); ++ mvpwm->controller.blink_on_duration = ++ readl_relaxed(mvebu_pwmreg_blink_on_duration(&mvpwm->controller)); ++ mvpwm->controller.blink_off_duration = ++ readl_relaxed(mvebu_pwmreg_blink_off_duration(&mvpwm->controller)); ++} ++ ++static void mvebu_pwm_resume(struct mvebu_gpio_chip *mvchip) ++{ ++ struct mvebu_pwm *mvpwm = mvchip->mvpwm; ++ ++ writel_relaxed(mvpwm->blink_select, ++ mvebu_gpioreg_blink_select(mvchip)); ++ writel_relaxed(mvpwm->controller.blink_on_duration, ++ mvebu_pwmreg_blink_on_duration(&mvpwm->controller)); ++ writel_relaxed(mvpwm->controller.blink_off_duration, ++ mvebu_pwmreg_blink_off_duration(&mvpwm->controller)); ++} ++ ++/* ++ * Armada 370/XP has simple PWM support for gpio lines. Other SoCs ++ * don't have this hardware. So if we don't have the necessary ++ * resource, it is not an error. ++ */ ++static int mvebu_pwm_probe(struct platform_device *pdev, ++ struct mvebu_gpio_chip *mvchip, ++ int id) ++{ ++ struct device *dev = &pdev->dev; ++ struct mvebu_pwm *mvpwm; ++ struct resource *res; ++ u32 set; ++ enum mvebu_pwm_ctrl ctrl_set; ++ ++ if (!of_device_is_compatible(mvchip->chip.of_node, ++ "marvell,armada-370-gpio")) ++ return 0; ++ ++ if (IS_ERR(mvchip->clk)) ++ return PTR_ERR(mvchip->clk); ++ ++ /* ++ * There are only two sets of PWM configuration registers for ++ * all the GPIO lines on those SoCs which this driver reserves ++ * for the first two GPIO chips. So if the resource is missing ++ * we can't treat it as an error. ++ */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); ++ if (!res) ++ return 0; ++ ++ /* ++ * Use set A for lines of GPIO chip with id 0, B for GPIO chip ++ * with id 1. Don't allow further GPIO chips to be used for PWM. ++ */ ++ if (id == 0) { ++ set = 0; ++ ctrl_set = MVEBU_PWM_CTRL_SET_A; ++ } else if (id == 1) { ++ set = U32_MAX; ++ ctrl_set = MVEBU_PWM_CTRL_SET_B; ++ } else { ++ return -EINVAL; ++ } ++ writel_relaxed(set, mvebu_gpioreg_blink_select(mvchip)); ++ ++ mvpwm = devm_kzalloc(dev, sizeof(struct mvebu_pwm), GFP_KERNEL); ++ if (!mvpwm) ++ return -ENOMEM; ++ mvchip->mvpwm = mvpwm; ++ mvpwm->mvchip = mvchip; ++ ++ mvpwm->controller.membase = devm_ioremap_resource(dev, res); ++ if (IS_ERR(mvpwm->controller.membase)) ++ return PTR_ERR(mvpwm->controller.membase); ++ ++ mvpwm->controller.clk_rate = clk_get_rate(mvchip->clk); ++ if (!mvpwm->controller.clk_rate) ++ return -EINVAL; ++ ++ mvpwm->chip.dev = dev; ++ mvpwm->chip.ops = &mvebu_pwm_ops; ++ mvpwm->chip.npwm = mvchip->chip.ngpio; ++ ++ /* ++ * There may already be some PWM allocated, so we can't force ++ * mvpwm->chip.base to a fixed point like mvchip->chip.base. ++ * So, we let pwmchip_add() do the numbering and take the next free ++ * region. ++ */ ++ mvpwm->chip.base = -1; ++ ++ spin_lock_init(&mvpwm->controller.lock); ++ mvpwm->default_counter = ctrl_set; ++ mvebu_pwm_list[ctrl_set] = &mvpwm->controller; ++ ++ return pwmchip_add(&mvpwm->chip); ++} ++ + #ifdef CONFIG_DEBUG_FS + #include + +@@ -561,6 +889,10 @@ static const struct of_device_id mvebu_gpio_of_match[] = { + .data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP, + }, + { ++ .compatible = "marvell,armada-370-gpio", ++ .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION, ++ }, ++ { + /* sentinel */ + }, + }; +@@ -607,6 +939,9 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state) + BUG(); + } + ++ if (IS_ENABLED(CONFIG_PWM)) ++ mvebu_pwm_suspend(mvchip); ++ + return 0; + } + +@@ -650,6 +985,9 @@ static int mvebu_gpio_resume(struct platform_device *pdev) + BUG(); + } + ++ if (IS_ENABLED(CONFIG_PWM)) ++ mvebu_pwm_resume(mvchip); ++ + return 0; + } + +@@ -661,7 +999,6 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + struct resource *res; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; +- struct clk *clk; + unsigned int ngpios; + unsigned int gpio_base = -1; + int soc_variant; +@@ -695,10 +1032,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + return id; + } + +- clk = devm_clk_get(&pdev->dev, NULL); ++ mvchip->clk = devm_clk_get(&pdev->dev, NULL); + /* Not all SoCs require a clock.*/ +- if (!IS_ERR(clk)) +- clk_prepare_enable(clk); ++ if (!IS_ERR(mvchip->clk)) ++ clk_prepare_enable(mvchip->clk); + + mvchip->soc_variant = soc_variant; + mvchip->chip.label = dev_name(&pdev->dev); +@@ -835,6 +1172,10 @@ static int mvebu_gpio_probe(struct platform_device *pdev) + goto err_generic_chip; + } + ++ /* Armada 370/XP has simple PWM support for GPIO lines */ ++ if (IS_ENABLED(CONFIG_PWM)) ++ return mvebu_pwm_probe(pdev, mvchip, id); ++ + return 0; + + err_generic_chip: From 50609199173af959f835c242605d8d2086a19651 Mon Sep 17 00:00:00 2001 From: aprayoga Date: Sun, 4 Feb 2018 08:34:31 +0800 Subject: [PATCH 16/20] [helios4] udev rules and pwm fancontrol --- config/sources/mvebu-helios4.inc | 3 ++- packages/bsp/helios4/90-helios4-hwmon.rules | 24 +++++++++++++++++++ .../bsp/helios4/fancontrol_pwm-fan-LK4.4.conf | 10 ++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 packages/bsp/helios4/90-helios4-hwmon.rules create mode 100644 packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf diff --git a/config/sources/mvebu-helios4.inc b/config/sources/mvebu-helios4.inc index e88826109..dae5cd18f 100644 --- a/config/sources/mvebu-helios4.inc +++ b/config/sources/mvebu-helios4.inc @@ -19,9 +19,10 @@ esac family_tweaks_s() { chroot $SDCARD /bin/bash -c "apt-get -y -qq install fancontrol >/dev/null 2>&1" + cp -R $SRC/packages/bsp/helios4/90-helios4-hwmon.rules $SDCARD/etc/udev/rules.d/ case $BRANCH in default) - cp -R $SRC/packages/bsp/helios4/fancontrol_gpio-fan.conf $SDCARD/etc/fancontrol + cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf $SDCARD/etc/fancontrol ;; next) diff --git a/packages/bsp/helios4/90-helios4-hwmon.rules b/packages/bsp/helios4/90-helios4-hwmon.rules new file mode 100755 index 000000000..8214adf81 --- /dev/null +++ b/packages/bsp/helios4/90-helios4-hwmon.rules @@ -0,0 +1,24 @@ +# Helios4 persistent hwmon + +ACTION=="remove", GOTO="helios4_hwmon_end" + +# +KERNELS=="j10-pwm", SUBSYSTEMS=="platform", ENV{_HELIOS4_FAN_}="j10", ENV{_IS_HELIOS4_FAN_}="1", ENV{IS_HELIOS4_HWMON}="1" +KERNELS=="j17-pwm", SUBSYSTEMS=="platform", ENV{_HELIOS4_FAN_}="j17", ENV{_IS_HELIOS4_FAN_}="1", ENV{IS_HELIOS4_HWMON}="1" +KERNELS=="0-004c", SUBSYSTEMS=="i2c", DRIVERS=="lm75", ENV{IS_HELIOS4_HWMON}="1" + +SUBSYSTEM!="hwmon", GOTO="helios4_hwmon_end" + +ENV{HWMON_PATH}="/sys%p" +# +ATTR{name}=="f1072004mdiomii00", ENV{IS_HELIOS4_HWMON}="1", ENV{HELIOS4_SYMLINK}="/dev/thermal-eth" +ATTR{name}=="armada_thermal", ENV{IS_HELIOS4_HWMON}="1", ENV{HELIOS4_SYMLINK}="/dev/thermal-cpu" +# +ENV{IS_HELIOS4_HWMON}=="1", ATTR{name}=="lm75", ENV{HELIOS4_SYMLINK}="/dev/thermal-board" +ENV{_IS_HELIOS4_FAN_}=="1", ENV{HELIOS4_SYMLINK}="/dev/fan-$env{_HELIOS4_FAN_}" + +# +ENV{IS_HELIOS4_HWMON}=="1", RUN+="/bin/ln -sf $env{HWMON_PATH} $env{HELIOS4_SYMLINK}" + +LABEL="helios4_hwmon_end" + diff --git a/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf b/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf new file mode 100644 index 000000000..72392c25f --- /dev/null +++ b/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf @@ -0,0 +1,10 @@ +# Helios4 PWM Fan Control Configuration +# Temp source : lm75 sensor +INTERVAL=10 +DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c +DEVNAME=hwmon0=pwmfan hwmon1=pwmfan hwmon2=lm75 +FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input +MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 +MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 +MINSTART=hwmon0/pwm1=100 hwmon1/pwm1=100 +MINSTOP=hwmon0/pwm1=50 hwmon1/pwm1=50 From 494d6b0376e13420715f434bf077df73eb11d3c4 Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sun, 4 Feb 2018 19:00:39 +0800 Subject: [PATCH 17/20] Helios4 - kernel patch clean-up / consolidation --- .../95-helios4-remove-spi-nor-flash.patch | 21 ------------------- ...ch => 91-libata-add-ledtrig-support.patch} | 0 .../mvebu-next/93-helios4-device-tree.patch | 21 ++----------------- .../93-helios4-remove-spi-nor-flash.patch | 17 --------------- .../93-helios4-remove_sd_uhs_option.patch | 16 -------------- 5 files changed, 2 insertions(+), 73 deletions(-) delete mode 100644 patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch rename patch/kernel/mvebu-next/{91-01-libata-add-ledtrig-support.patch => 91-libata-add-ledtrig-support.patch} (100%) delete mode 100644 patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch delete mode 100644 patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch diff --git a/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch b/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch deleted file mode 100644 index dab0a3481..000000000 --- a/patch/kernel/mvebu-default/95-helios4-remove-spi-nor-flash.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts -index 1075535..2045dc0 100644 ---- a/arch/arm/boot/dts/armada-388-helios4.dts -+++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -244,16 +244,6 @@ - µsom_spi1_cs_pins>; - pinctrl-names = "default"; - status = "okay"; -- -- spi-flash@0 { -- #address-cells = <1>; -- #size-cells = <1>; -- compatible = "w25q32", "jedec,spi-nor"; -- reg = <0>; /* Chip select 0 */ -- spi-max-frequency = <104000000>; -- spi-cpha; -- status = "okay"; -- }; - }; - - sdhci@d8000 { diff --git a/patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch b/patch/kernel/mvebu-next/91-libata-add-ledtrig-support.patch similarity index 100% rename from patch/kernel/mvebu-next/91-01-libata-add-ledtrig-support.patch rename to patch/kernel/mvebu-next/91-libata-add-ledtrig-support.patch diff --git a/patch/kernel/mvebu-next/93-helios4-device-tree.patch b/patch/kernel/mvebu-next/93-helios4-device-tree.patch index ff18c48d8..7d724eebc 100644 --- a/patch/kernel/mvebu-next/93-helios4-device-tree.patch +++ b/patch/kernel/mvebu-next/93-helios4-device-tree.patch @@ -1,7 +1,3 @@ - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/armada-388-helios4.dts | 309 +++++++++++++++++++++ - 2 files changed, 310 insertions(+) - diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4b17f35..c6b6038 100644 --- a/arch/arm/boot/dts/Makefile @@ -14,12 +10,13 @@ index 4b17f35..c6b6038 100644 armada-388-db.dtb \ armada-388-gp.dtb \ armada-388-rd.dtb + diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts new file mode 100644 index 0000000..93d0132 --- /dev/null +++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -0,0 +1,309 @@ +@@ -0,0 +1,295 @@ +/* + * Device Tree file for Helios4 + * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828) @@ -199,11 +196,6 @@ index 0000000..93d0132 + status = "okay"; + vmmc = <®_3p3v>; + wp-inverted; -+ max-frequency = <50000000>; -+ cap-sd-highspeed; -+ sd-uhs-sdr12; -+ sd-uhs-sdr25; -+ sd-uhs-sdr50; + }; + + usb@58000 { @@ -320,12 +312,3 @@ index 0000000..93d0132 + marvell,function = "gpio"; + }; +}; -+ -+&spi1 { -+ status = "okay"; -+ -+ spi-flash@0 { -+ spi-max-frequency = <104000000>; -+ status = "okay"; -+ }; -+}; diff --git a/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch b/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch deleted file mode 100644 index eec08df38..000000000 --- a/patch/kernel/mvebu-next/93-helios4-remove-spi-nor-flash.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts -index 93d0132..47699bd 100644 ---- a/arch/arm/boot/dts/armada-388-helios4.dts -+++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -298,12 +298,3 @@ - marvell,function = "gpio"; - }; - }; -- --&spi1 { -- status = "okay"; -- -- spi-flash@0 { -- spi-max-frequency = <104000000>; -- status = "okay"; -- }; --}; diff --git a/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch b/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch deleted file mode 100644 index 08e364d4a..000000000 --- a/patch/kernel/mvebu-next/93-helios4-remove_sd_uhs_option.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts -index 47699bd..4a5e8fc 100644 ---- a/arch/arm/boot/dts/armada-388-helios4.dts -+++ b/arch/arm/boot/dts/armada-388-helios4.dts -@@ -177,11 +177,6 @@ - status = "okay"; - vmmc = <®_3p3v>; - wp-inverted; -- max-frequency = <50000000>; -- cap-sd-highspeed; -- sd-uhs-sdr12; -- sd-uhs-sdr25; -- sd-uhs-sdr50; - }; - - usb@58000 { From e453a43107ef776ebf41668d96fa749a6583b513 Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Sun, 4 Feb 2018 19:17:33 +0800 Subject: [PATCH 18/20] Helios4 - cleanup fan control setup --- config/sources/mvebu-helios4.inc | 6 +++--- packages/bsp/helios4/fancontrol_gpio-fan.conf | 12 ------------ ....4.conf => fancontrol_pwm-fan-mvebu-default.conf} | 0 ...m-fan.conf => fancontrol_pwm-fan-mvebu-next.conf} | 0 .../mvebu-default/95-helios4-device-tree.patch | 4 ++-- 5 files changed, 5 insertions(+), 17 deletions(-) delete mode 100644 packages/bsp/helios4/fancontrol_gpio-fan.conf rename packages/bsp/helios4/{fancontrol_pwm-fan-LK4.4.conf => fancontrol_pwm-fan-mvebu-default.conf} (100%) rename packages/bsp/helios4/{fancontrol_pwm-fan.conf => fancontrol_pwm-fan-mvebu-next.conf} (100%) diff --git a/config/sources/mvebu-helios4.inc b/config/sources/mvebu-helios4.inc index dae5cd18f..7dad9301f 100644 --- a/config/sources/mvebu-helios4.inc +++ b/config/sources/mvebu-helios4.inc @@ -22,12 +22,12 @@ family_tweaks_s() cp -R $SRC/packages/bsp/helios4/90-helios4-hwmon.rules $SDCARD/etc/udev/rules.d/ case $BRANCH in default) - cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf $SDCARD/etc/fancontrol + cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf $SDCARD/etc/fancontrol ;; next) - cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan.conf $SDCARD/etc/fancontrol - patch $SDCARD/usr/sbin/fancontrol < $SRC/packages/bsp/helios4/fancontrol.patch + cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf $SDCARD/etc/fancontrol + #patch $SDCARD/usr/sbin/fancontrol < $SRC/packages/bsp/helios4/fancontrol.patch ;; esac } diff --git a/packages/bsp/helios4/fancontrol_gpio-fan.conf b/packages/bsp/helios4/fancontrol_gpio-fan.conf deleted file mode 100644 index 556c823c4..000000000 --- a/packages/bsp/helios4/fancontrol_gpio-fan.conf +++ /dev/null @@ -1,12 +0,0 @@ -# Helios4 GPIO Fan Control Configuration -# This is a temporary configuration while relying on gpio-fan driver. -# Only low or full speed is supported. -# Temp source : lm75 sensor -INTERVAL=10 -DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c -DEVNAME=hwmon0=gpio_fan hwmon1=gpio_fan hwmon2=lm75 -FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input -MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 -MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 -MINSTART=hwmon0/pwm1=1 hwmon1/pwm1=1 -MINSTOP=hwmon0/pwm1=0 hwmon1/pwm1=0 diff --git a/packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf similarity index 100% rename from packages/bsp/helios4/fancontrol_pwm-fan-LK4.4.conf rename to packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf diff --git a/packages/bsp/helios4/fancontrol_pwm-fan.conf b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf similarity index 100% rename from packages/bsp/helios4/fancontrol_pwm-fan.conf rename to packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf diff --git a/patch/kernel/mvebu-default/95-helios4-device-tree.patch b/patch/kernel/mvebu-default/95-helios4-device-tree.patch index fd7410067..c36487654 100644 --- a/patch/kernel/mvebu-default/95-helios4-device-tree.patch +++ b/patch/kernel/mvebu-default/95-helios4-device-tree.patch @@ -125,12 +125,12 @@ index 0000000..19a0256 + + fan1: j10-pwm { + compatible = "pwm-fan"; -+ pwms = <&gpio1 9 3800>; ++ pwms = <&gpio1 9 40000>; /* Target freq:25 kHz */ + }; + + fan2: j17-pwm { + compatible = "pwm-fan"; -+ pwms = <&gpio1 23 3800>; ++ pwms = <&gpio1 23 40000>; /* Target freq:25 kHz */ + }; + + usb2_phy: usb2-phy { From 8bc4065287e82c152639686d4867e5d44ffd3c1f Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Mon, 5 Feb 2018 00:55:36 +0800 Subject: [PATCH 19/20] Make fancontrol config use physical device address (mapped via 90-helios4-hwmon.rules) Remove kernel KGDB options --- config/kernel/linux-mvebu-next.config | 7 ------- config/sources/mvebu-helios4.inc | 1 - packages/bsp/helios4/fancontrol.patch | 12 ------------ .../fancontrol_pwm-fan-mvebu-default.conf | 17 +++++++++-------- .../helios4/fancontrol_pwm-fan-mvebu-next.conf | 15 +++++++-------- 5 files changed, 16 insertions(+), 36 deletions(-) delete mode 100644 packages/bsp/helios4/fancontrol.patch diff --git a/config/kernel/linux-mvebu-next.config b/config/kernel/linux-mvebu-next.config index 53b0e8259..cc75f2101 100644 --- a/config/kernel/linux-mvebu-next.config +++ b/config/kernel/linux-mvebu-next.config @@ -4522,13 +4522,6 @@ CONFIG_TEST_HEXDUMP=m # CONFIG_BUG_ON_DATA_CORRUPTION is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y -CONFIG_KGDB=y -CONFIG_KGDB_SERIAL_CONSOLE=y -# CONFIG_KGDB_TESTS is not set -CONFIG_KGDB_KDB=y -CONFIG_KDB_DEFAULT_ENABLE=0x1 -CONFIG_KDB_KEYBOARD=y -CONFIG_KDB_CONTINUE_CATASTROPHIC=0 # CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set # CONFIG_UBSAN is not set CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y diff --git a/config/sources/mvebu-helios4.inc b/config/sources/mvebu-helios4.inc index 7dad9301f..a29de9f7f 100644 --- a/config/sources/mvebu-helios4.inc +++ b/config/sources/mvebu-helios4.inc @@ -27,7 +27,6 @@ family_tweaks_s() next) cp -R $SRC/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf $SDCARD/etc/fancontrol - #patch $SDCARD/usr/sbin/fancontrol < $SRC/packages/bsp/helios4/fancontrol.patch ;; esac } diff --git a/packages/bsp/helios4/fancontrol.patch b/packages/bsp/helios4/fancontrol.patch deleted file mode 100644 index ce9ee7670..000000000 --- a/packages/bsp/helios4/fancontrol.patch +++ /dev/null @@ -1,12 +0,0 @@ -@@ -157,9 +157,9 @@ - - function DevicePath() - { -- if [ -h "$1/device" ] -+ if [ -h "$1" ] - then -- readlink -f "$1/device" | sed -e 's/^\/sys\///' -+ readlink -f "$1" | sed -e 's/^\/sys\///;s/\/hwmon\/.*//' - fi - } - diff --git a/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf index 72392c25f..21677774b 100644 --- a/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf +++ b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-default.conf @@ -1,10 +1,11 @@ # Helios4 PWM Fan Control Configuration -# Temp source : lm75 sensor +# Temp source : /dev/thermal-board INTERVAL=10 -DEVPATH=hwmon0=devices/platform/j10-pwm hwmon1=devices/platform/j17-pwm hwmon2=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c -DEVNAME=hwmon0=pwmfan hwmon1=pwmfan hwmon2=lm75 -FCTEMPS=hwmon0/pwm1=hwmon2/temp1_input hwmon1/pwm1=hwmon2/temp1_input -MINTEMP=hwmon0/pwm1=45 hwmon1/pwm1=45 -MAXTEMP=hwmon0/pwm1=65 hwmon1/pwm1=65 -MINSTART=hwmon0/pwm1=100 hwmon1/pwm1=100 -MINSTOP=hwmon0/pwm1=50 hwmon1/pwm1=50 +FCTEMPS=/dev/fan-j10/pwm1=/dev/thermal-board/temp1_input /dev/fan-j17/pwm1=/dev/thermal-board/temp1_input +MINTEMP=/dev/fan-j10/pwm1=45 /dev/fan-j17/pwm1=45 +MAXTEMP=/dev/fan-j10/pwm1=70 /dev/fan-j17/pwm1=70 +MINSTART=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 +MINSTOP=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 +MINPWM=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 + + diff --git a/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf index 9bd9dc181..2e815954b 100644 --- a/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf +++ b/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf @@ -1,11 +1,10 @@ # Helios4 PWM Fan Control Configuration -# Temp source : armada_thermal sensor +# Temp source : /dev/thermal-cpu INTERVAL=10 -DEVPATH=hwmon1=devices/virtual hwmon2=devices/platform/j10-pwm hwmon3=devices/platform/j17-pwm hwmon4=devices/platform/soc/soc:internal-regs/f1011000.i2c/i2c-0/0-004c -DEVNAME=hwmon1=armada_thermal hwmon2=pwmfan hwmon3=pwmfan hwmon4=lm75 -FCTEMPS=hwmon2/pwm1=hwmon1/temp1_input hwmon3/pwm1=hwmon1/temp1_input -MINTEMP=hwmon2/pwm1=55 hwmon3/pwm1=55 -MAXTEMP=hwmon2/pwm1=95 hwmon3/pwm1=95 -MINSTART=hwmon2/pwm1=100 hwmon3/pwm1=100 -MINSTOP=hwmon2/pwm1=50 hwmon3/pwm1=50 +FCTEMPS=/dev/fan-j10/pwm1=/dev/thermal-cpu/temp1_input /dev/fan-j17/pwm1=/dev/thermal-cpu/temp1_input +MINTEMP=/dev/fan-j10/pwm1=55 /dev/fan-j17/pwm1=55 +MAXTEMP=/dev/fan-j10/pwm1=95 /dev/fan-j17/pwm1=95 +MINSTART=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 +MINSTOP=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 +MINPWM=/dev/fan-j10/pwm1=50 /dev/fan-j17/pwm1=50 From 024e5c01908ea59fe249fecf8a24fbcb72dad496 Mon Sep 17 00:00:00 2001 From: Gauthier Provost Date: Mon, 5 Feb 2018 01:01:57 +0800 Subject: [PATCH 20/20] Revert README.md to match upstream repo and avoid cherry pick PR --- README.md | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3f56a732a..7e56d7d8c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,39 @@ -# Armbian - Helios4 +# Armbian -**This repo is only for developement of Helios4 support in Armbian Build Framework** +Ubuntu and Debian images for ARM based single-board computers +https://www.armbian.com -To get latest Armbian please go to the [Official Armbian Git](https://github.com/armbian/build) +## How to build my own image or kernel? +Supported build environments: +- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) guest inside a [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or other virtualization software, +- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) guest managed by [Vagrant](https://www.vagrantup.com/). This uses Virtualbox (as above) but does so in an easily repeatable way. Please check the [Armbian with Vagrant README](https://docs.armbian.com/Developer-Guide_Using-Vagrant/) for a quick start HOWTO, +- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) inside a [Docker](https://www.docker.com/), [systemd-nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) or other container environment [(example)](https://github.com/igorpecovnik/lib/pull/255#issuecomment-205045273). Building full OS images inside containers may not work, so this option is mostly for the kernel compilation, +- [Ubuntu Xenial 16.04 x64](http://archive.ubuntu.com/ubuntu/dists/xenial-updates/main/installer-amd64/current/images/netboot/mini.iso) running natively on a dedicated PC or a server (**not** recommended unless you build kernel only, for full OS images always use virtualization as outlined above), +- **20GB disk space** or more and **2GB RAM** or more available for the VM, container or native OS, +- superuser rights (configured `sudo` or root access). + +**Execution** + + apt-get -y install git + git clone https://github.com/armbian/build + cd build + ./compile.sh + +Make sure that full path to the build script does not contain spaces. + +You will be prompted with a selection menu for a build option, a board name, a kernel branch and an OS release. Please check the documentation for [advanced options](https://docs.armbian.com/Developer-Guide_Build-Options/) and [additional customization](https://docs.armbian.com/Developer-Guide_User-Configurations/). + +Build process uses caching for the compilation and the debootstrap process, so consecutive runs with similar settings will be much faster. + +## Reporting issues + +Please read [this](https://github.com/igorpecovnik/lib/blob/master/.github/ISSUE_TEMPLATE.md) notice first before opening an issue. + +## More info: + +- [Documentation](https://docs.armbian.com/Developer-Guide_Build-Preparation/) +- [Prebuilt images](https://www.armbian.com/download/) +- [Support forums](https://forum.armbian.com/ "Armbian support forum") +- [Project at Github](https://github.com/igorpecovnik/lib)