Pārlūkot izejas kodu

Snap7 for IOT2050 arm64

Reinhard Russinger 3 gadi atpakaļ
vecāks
revīzija
6481c0727a
100 mainītis faili ar 2 papildinājumiem un 13979 dzēšanām
  1. 0 8
      Config.in
  2. 0 700
      IOT2000/10.1007%2F978-1-4302-6838-3.pdf
  3. BIN
      IOT2000/iot2000_io_module_operating_instructions_enUS_en-US.pdf
  4. BIN
      IOT2000/iot2000_operating_instructions_d_de-DE.pdf
  5. 2 3
      MakeBuildrootEnv.sh
  6. 0 31
      board/PSG/iot2000/genimage.cfg
  7. 0 11
      board/PSG/iot2000/grub.cfg
  8. 0 90
      board/PSG/iot2000/linux-4.4-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch
  9. 0 95
      board/PSG/iot2000/linux-4.4-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch
  10. 0 61
      board/PSG/iot2000/linux-4.4-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch
  11. 0 165
      board/PSG/iot2000/linux-4.4-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch
  12. 0 167
      board/PSG/iot2000/linux-4.4-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch
  13. 0 47
      board/PSG/iot2000/linux-4.4-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch
  14. 0 44
      board/PSG/iot2000/linux-4.4-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch
  15. 0 45
      board/PSG/iot2000/linux-4.4-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch
  16. 0 86
      board/PSG/iot2000/linux-4.4-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch
  17. 0 46
      board/PSG/iot2000/linux-4.4-patches/0010-gpio-sch-Use-devm_gpiochip_add_data-for-gpio-registr.patch
  18. 0 114
      board/PSG/iot2000/linux-4.4-patches/0011-gpio-sch-Fix-Oops-on-module-load-on-Asus-Eee-PC-1201.patch
  19. 0 45
      board/PSG/iot2000/linux-4.4-patches/0012-gpio-sch-Implement-.get_direction.patch
  20. 0 230
      board/PSG/iot2000/linux-4.4-patches/0013-gpio-sch-Add-interrupt-support.patch
  21. 0 44
      board/PSG/iot2000/linux-4.4-patches/0014-iot2000-hack-Work-around-DSDT-mistake.patch
  22. 0 42
      board/PSG/iot2000/linux-4.4-patches/0015-iot2000-hack-Adjust-pca9685-gpio-base-for-legacy-com.patch
  23. 0 99
      board/PSG/iot2000/linux-4.4-patches/0016-iot2000-hack-gpio-pca953x-provide-GPIO-base-based-on.patch
  24. 0 334
      board/PSG/iot2000/linux-4.4-patches/0017-iot2000-hack-gpio-pca953x-add-drive-property.patch
  25. 0 105
      board/PSG/iot2000/linux-4.4-patches/0018-iot2000-hack-pwm-pca-9685-Provide-chip-level-pwm_per.patch
  26. 0 801
      board/PSG/iot2000/linux-4.4-patches/0019-random-replace-non-blocking-pool-with-a-Chacha20-bas.patch
  27. 0 143
      board/PSG/iot2000/linux-4.4-patches/0020-random-make-dev-urandom-scalable-for-silly-userspace.patch
  28. 0 109
      board/PSG/iot2000/linux-4.4-patches/0021-random-add-backtracking-protection-to-the-CRNG.patch
  29. 0 35
      board/PSG/iot2000/linux-4.4-patches/0022-random-remove-stale-maybe_reseed_primary_crng.patch
  30. 0 180
      board/PSG/iot2000/linux-4.4-patches/0023-random-use-chacha20-for-get_random_int-long.patch
  31. 0 147
      board/PSG/iot2000/linux-4.4-patches/0024-random-convert-get_random_int-long-into-get_random_u.patch
  32. 0 148
      board/PSG/iot2000/linux-4.4-patches/0025-random-invalidate-batched-entropy-after-crng-init.patch
  33. 0 87
      board/PSG/iot2000/linux-4.4-patches/0026-random-silence-compiler-warnings-and-fix-race.patch
  34. 0 118
      board/PSG/iot2000/linux-4.4-patches/0027-random-add-wait_for_random_bytes-API.patch
  35. 0 77
      board/PSG/iot2000/linux-4.4-patches/0028-random-fix-crng_ready-test.patch
  36. 0 110
      board/PSG/iot2000/linux-4.4-patches/0029-random-use-a-different-mixing-algorithm-for-add_devi.patch
  37. 0 163
      board/PSG/iot2000/linux-4.4-patches/0030-random-only-read-from-dev-random-after-its-pool-has-.patch
  38. 0 58
      board/PSG/iot2000/linux-4.4-patches/0031-random-fix-soft-lockup-when-trying-to-read-from-an-u.patch
  39. 0 145
      board/PSG/iot2000/linux-4.4-patches/0032-random-try-to-actively-add-entropy-rather-than-passi.patch
  40. 0 68
      board/PSG/iot2000/linux-4.4-patches_orig/0001-stmmac-Add-support-for-SIMATIC-IOT2000-platform.patch
  41. 0 33
      board/PSG/iot2000/linux-4.4-patches_orig/0002-serial-uapi-Add-support-for-bus-termination.patch
  42. 0 103
      board/PSG/iot2000/linux-4.4-patches_orig/0003-serial-8250_pci-Use-symbolic-constants-for-EXAR-s-MP.patch
  43. 0 32
      board/PSG/iot2000/linux-4.4-patches_orig/0004-serial-8250_pci-Fix-EXAR-feature-control-register-co.patch
  44. 0 176
      board/PSG/iot2000/linux-4.4-patches_orig/0005-serial-8250_pci-Add-support-for-IOT2000-platform.patch
  45. 0 152
      board/PSG/iot2000/linux-4.4-patches_orig/0006-serial-8250_pci-Add-support-for-red-user-LED-on-IOT2.patch
  46. 0 67
      board/PSG/iot2000/linux-4.4-patches_orig/0007-spi-pxa2xx-Factor-out-handle_bad_msg.patch
  47. 0 41
      board/PSG/iot2000/linux-4.4-patches_orig/0008-spi-pxa2xx-Prepare-for-edge-triggered-interrupts.patch
  48. 0 39
      board/PSG/iot2000/linux-4.4-patches_orig/0009-spi-pca2xx-pci-Allow-MSI.patch
  49. 0 129
      board/PSG/iot2000/linux-4.4-patches_orig/0010-efi-Move-efi_status_to_err-to-drivers-firmware-efi.patch
  50. 0 431
      board/PSG/iot2000/linux-4.4-patches_orig/0011-efi-Add-capsule-update-support.patch
  51. 0 69
      board/PSG/iot2000/linux-4.4-patches_orig/0012-x86-efi-Force-EFI-reboot-to-process-pending-capsules.patch
  52. 0 425
      board/PSG/iot2000/linux-4.4-patches_orig/0013-efi-Add-misc-char-driver-interface-to-update-EFI-fir.patch
  53. 0 130
      board/PSG/iot2000/linux-4.4-patches_orig/0014-efi-capsule-Make-efi_capsule_pending-lockless.patch
  54. 0 101
      board/PSG/iot2000/linux-4.4-patches_orig/0015-efi-capsule-Move-capsule-to-the-stack-in-efi_capsule.patch
  55. 0 93
      board/PSG/iot2000/linux-4.4-patches_orig/0016-efi-capsule-Allocate-whole-capsule-into-virtual-memo.patch
  56. 0 40
      board/PSG/iot2000/linux-4.4-patches_orig/0017-efi-capsule-Fix-return-code-on-failing-kmap-vmap.patch
  57. 0 70
      board/PSG/iot2000/linux-4.4-patches_orig/0018-efi-capsule-Remove-pr_debug-on-ENOMEM-or-EFAULT.patch
  58. 0 88
      board/PSG/iot2000/linux-4.4-patches_orig/0019-efi-capsule-Clean-up-pr_err-info-messages.patch
  59. 0 34
      board/PSG/iot2000/linux-4.4-patches_orig/0020-efi-capsule-Adjust-return-type-of-efi_capsule_setup_.patch
  60. 0 128
      board/PSG/iot2000/linux-4.4-patches_orig/0021-efi-capsule-loader-Use-a-cached-copy-of-the-capsule-.patch
  61. 0 144
      board/PSG/iot2000/linux-4.4-patches_orig/0022-efi-capsule-loader-Redirect-calls-to-efi_capsule_set.patch
  62. 0 114
      board/PSG/iot2000/linux-4.4-patches_orig/0023-efi-capsule-loader-Use-page-addresses-rather-than-st.patch
  63. 0 202
      board/PSG/iot2000/linux-4.4-patches_orig/0024-efi-capsule-Add-support-for-Quark-security-header.patch
  64. 0 77
      board/PSG/iot2000/linux-4.4-patches_orig/0025-mfd-intel_quark_i2c_gpio-Use-dmi_system_id-table-for.patch
  65. 0 45
      board/PSG/iot2000/linux-4.4-patches_orig/0026-mfd-intel_quark_i2c_gpio-Add-support-for-SIMATIC-IOT.patch
  66. 0 44
      board/PSG/iot2000/linux-4.4-patches_orig/0027-iot2000-hack-Work-around-DSDT-mistake.patch
  67. 0 95
      board/PSG/iot2000/linux-4.4-patches_orig/0028-gpio-pca953x-provide-GPIO-base-based-on-_UID.patch
  68. 0 497
      board/PSG/iot2000/linux-4.4-patches_orig/0029-staging-iio-add-support-for-ADC1x8s102.patch
  69. 0 154
      board/PSG/iot2000/linux-4.4-patches_orig/0030-adc1x8s102-support-ACPI-based-enumeration.patch
  70. 0 373
      board/PSG/iot2000/linux-4.4-patches_orig/0031-gpio-pca953x-add-drive-property.patch
  71. 0 939
      board/PSG/iot2000/linux-4.4-patches_orig/0032-pca9685-PCA9685-PWM-and-GPIO-multi-function-device.patch
  72. 0 36
      board/PSG/iot2000/linux-4.4-patches_orig/0033-spi-pxa2xx-fixed-ACPI-based-enumeration-of-SPI-devic.patch
  73. 0 1218
      board/PSG/iot2000/linux-4.4-patches_orig/0034-acpi-added-a-custom-DSDT-file.patch
  74. 0 90
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch
  75. 0 95
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch
  76. 0 61
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch
  77. 0 165
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch
  78. 0 167
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch
  79. 0 47
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch
  80. 0 44
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch
  81. 0 45
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch
  82. 0 86
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch
  83. 0 46
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0010-gpio-sch-Use-devm_gpiochip_add_data-for-gpio-registr.patch
  84. 0 114
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0011-gpio-sch-Fix-Oops-on-module-load-on-Asus-Eee-PC-1201.patch
  85. 0 45
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0012-gpio-sch-Implement-.get_direction.patch
  86. 0 230
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0013-gpio-sch-Add-interrupt-support.patch
  87. 0 44
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0014-iot2000-hack-Work-around-DSDT-mistake.patch
  88. 0 42
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0015-iot2000-hack-Adjust-pca9685-gpio-base-for-legacy-com.patch
  89. 0 99
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0016-iot2000-hack-gpio-pca953x-provide-GPIO-base-based-on.patch
  90. 0 334
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0017-iot2000-hack-gpio-pca953x-add-drive-property.patch
  91. 0 105
      board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0018-iot2000-hack-pwm-pca-9685-Provide-chip-level-pwm_per.patch
  92. 0 90
      board/PSG/iot2000/linux-4.4-rt-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch
  93. 0 95
      board/PSG/iot2000/linux-4.4-rt-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch
  94. 0 61
      board/PSG/iot2000/linux-4.4-rt-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch
  95. 0 165
      board/PSG/iot2000/linux-4.4-rt-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch
  96. 0 167
      board/PSG/iot2000/linux-4.4-rt-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch
  97. 0 47
      board/PSG/iot2000/linux-4.4-rt-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch
  98. 0 44
      board/PSG/iot2000/linux-4.4-rt-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch
  99. 0 45
      board/PSG/iot2000/linux-4.4-rt-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch
  100. 0 86
      board/PSG/iot2000/linux-4.4-rt-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch

+ 0 - 8
Config.in

@@ -1,10 +1,2 @@
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/wt/Config.in"
 source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/switchserialmode/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/galileo-spi1-spidev/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/galileo-uio-gpio/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/galileogen2-fake/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/adc1x8s102/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/icinga2/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/python-ufw/Config.in"
 source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/Snap7/Config.in"
-source "$BR2_EXTERNAL_PSG_IOT2000_PATH/package/libyasdi/Config.in"

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 700
IOT2000/10.1007%2F978-1-4302-6838-3.pdf


BIN
IOT2000/iot2000_io_module_operating_instructions_enUS_en-US.pdf


BIN
IOT2000/iot2000_operating_instructions_d_de-DE.pdf


+ 2 - 3
MakeBuildrootEnv.sh

@@ -4,8 +4,7 @@ cd ..
 rm -rf buildroot
 git clone git://git.buildroot.net/buildroot
 cd buildroot
-###git checkout 63a20d5dfebe83e2b2bd683dc78ebdf787dff100 -b psgwrk
-git checkout c4d26992560875930866a627cc936da2f938401b -b psgwrk
+git checkout 2021.8.1 -b psgwrk
 #==== Patches
 for i in ../PSG/patches/*.patch
 do
@@ -17,5 +16,5 @@ chmod a+x *.sh
 cp ../PSG/configs/* ./configs
 git add .
 git commit -m "PSG wrk changes and setup"
-make  BR2_EXTERNAL=../PSG iot2000_defconfig
+make  BR2_EXTERNAL=../PSG iot2050_defconfig
 cd $PSGWRKDIR

+ 0 - 31
board/PSG/iot2000/genimage.cfg

@@ -1,31 +0,0 @@
-# Create an image of the efi partition
-image efi-part.vfat {
-	vfat {
-		file startup.nsh {
-			image = "efi-part/startup.nsh"
-		}
-		file EFI {
-			image = "efi-part/EFI"
-		}
-	}
-	size=512K
-}
-
-# Create the sdcard image, pulling in
-#  * the image created by buildroot
-#  * the efi-partition created above
-image sdcard.img {
-	hdimage {
-	}
-
-	partition boot {
-		partition-type = 0xC
-		image = "efi-part.vfat"
-	}
-
-	partition rootfs {
-		partition-type = 0x83
-		image = "rootfs.ext2"
-		size = 1800M
-	}
-}

+ 0 - 11
board/PSG/iot2000/grub.cfg

@@ -1,11 +0,0 @@
-set default="0"
-set timeout="0"
-
-menuentry "PSG iot2000" {
-	# Grub2 supports ext4, load the kernel from the Linux rootfs partition
-	# Set root tells grub to search the 2nd partition for the bzImage
-	set root=(hd0,msdos2)
-
-	# Set Linux to boot from the 2nd partition, SD/MMC support is baked into the kernel
-	linux /boot/bzImage root=/dev/mmcblk0p2 rootwait console=ttyS1,115200n8 earlycon=uart8250,mmio32,0x9000b000,115200n8 reboot=efi,warm apic=debug rw net.ifnames=0 
-}

+ 0 - 90
board/PSG/iot2000/linux-4.4-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch

@@ -1,90 +0,0 @@
-From 9d215622c3277114820de51365109896e0337ab8 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:57 +0200
-Subject: [PATCH 01/32] stmmac: pci: Make stmmac_pci_info structure constant
-
-Commit c5d5287ef0f763e836bf94659b3a6080358373f1 upstream.
-
-By removing the PCI device reference from the structure and passing it
-as parameters to the interested functions, we can make quark_pci_info
-const.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 3491e98bffc5..828d276748e3 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,17 +42,17 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	struct pci_dev *pdev;
--	int (*setup)(struct plat_stmmacenet_data *plat,
--		     struct stmmac_pci_info *info);
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
-+		     const struct stmmac_pci_info *info);
- 	struct stmmac_pci_dmi_data *dmi;
- };
- 
--static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
-+static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
-+				    const struct stmmac_pci_info *info)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(info->pdev->devfn);
-+	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
- 	/*
-@@ -96,17 +96,17 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 	plat->unicast_filter_entries = 1;
- }
- 
--static int quark_default_data(struct plat_stmmacenet_data *plat,
--			      struct stmmac_pci_info *info)
-+static int quark_default_data(struct pci_dev *pdev,
-+			      struct plat_stmmacenet_data *plat,
-+			      const struct stmmac_pci_info *info)
- {
--	struct pci_dev *pdev = info->pdev;
- 	int ret;
- 
- 	/*
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(info);
-+	ret = stmmac_pci_find_phy_addr(pdev, info);
- 	if (ret < 0)
- 		return ret;
- 
-@@ -165,7 +165,7 @@ static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
- 	{}
- };
- 
--static struct stmmac_pci_info quark_pci_info = {
-+static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
- 	.dmi = quark_pci_dmi_data,
- };
-@@ -227,9 +227,8 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 	pci_set_master(pdev);
- 
- 	if (info) {
--		info->pdev = pdev;
- 		if (info->setup) {
--			ret = info->setup(plat, info);
-+			ret = info->setup(pdev, plat, info);
- 			if (ret)
- 				return ret;
- 		}
--- 
-2.16.4
-

+ 0 - 95
board/PSG/iot2000/linux-4.4-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch

@@ -1,95 +0,0 @@
-From 94eff655c67ea28f35715f8864f3412faa2d827e Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:58 +0200
-Subject: [PATCH 02/32] stmmac: pci: Use stmmac_pci_info for all devices
-
-Commit b6a4c8f013ea2dd1ead7ee14b44712189a7bc6c6 upstream.
-
-Make stmmac_default_data compatible with stmmac_pci_info.setup and use
-an info structure for all devices. This allows to make the probing more
-regular.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 36 +++++++++++++++---------
- 1 file changed, 23 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 828d276748e3..a60059032dc6 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -74,7 +74,9 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	return -ENODEV;
- }
- 
--static void stmmac_default_data(struct plat_stmmacenet_data *plat)
-+static int stmmac_default_data(struct pci_dev *pdev,
-+			       struct plat_stmmacenet_data *plat,
-+			       const struct stmmac_pci_info *info)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -94,8 +96,14 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 
- 	/* Set default value for unicast filter entries */
- 	plat->unicast_filter_entries = 1;
-+
-+	return 0;
- }
- 
-+static const struct stmmac_pci_info stmmac_pci_info = {
-+	.setup = stmmac_default_data,
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
- 			      struct plat_stmmacenet_data *plat,
- 			      const struct stmmac_pci_info *info)
-@@ -226,14 +234,9 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	if (info) {
--		if (info->setup) {
--			ret = info->setup(pdev, plat, info);
--			if (ret)
--				return ret;
--		}
--	} else
--		stmmac_default_data(plat);
-+	ret = info->setup(pdev, plat, info);
-+	if (ret)
-+		return ret;
- 
- 	pci_enable_msi(pdev);
- 
-@@ -279,14 +282,21 @@ static int stmmac_pci_resume(struct device *dev)
- 
- static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
- 
--#define STMMAC_VENDOR_ID 0x700
-+/* synthetic ID, no official vendor */
-+#define PCI_VENDOR_ID_STMMAC 0x700
-+
- #define STMMAC_QUARK_ID  0x0937
- #define STMMAC_DEVICE_ID 0x1108
- 
-+#define STMMAC_DEVICE(vendor_id, dev_id, info)	{	\
-+	PCI_VDEVICE(vendor_id, dev_id),			\
-+	.driver_data = (kernel_ulong_t)&info		\
-+	}
-+
- static const struct pci_device_id stmmac_id_table[] = {
--	{PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)},
--	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)},
--	{PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info},
-+	STMMAC_DEVICE(STMMAC, STMMAC_DEVICE_ID, stmmac_pci_info),
-+	STMMAC_DEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_MAC, stmmac_pci_info),
-+	STMMAC_DEVICE(INTEL, STMMAC_QUARK_ID, quark_pci_info),
- 	{}
- };
- 
--- 
-2.16.4
-

+ 0 - 61
board/PSG/iot2000/linux-4.4-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch

@@ -1,61 +0,0 @@
-From 553355e45eac94312df999431b4491bb0dc43122 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:59 +0200
-Subject: [PATCH 03/32] stmmac: pci: Make stmmac_pci_find_phy_addr truly
- generic
-
-Commit c5f657e49c878756f21349f9e4b0f1c9631d5352 upstream.
-
-Move the special case for the early Galileo firmware into
-quark_default_setup. This allows to use stmmac_pci_find_phy_addr for
-non-quark cases.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 20 +++++++++++++-------
- 1 file changed, 13 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index a60059032dc6..19cf9607618a 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -55,12 +55,8 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
--	/*
--	 * Galileo boards with old firmware don't support DMI. We always return
--	 * 1 here, so at least first found MAC controller would be probed.
--	 */
- 	if (!name)
--		return 1;
-+		return -ENODEV;
- 
- 	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
-@@ -115,8 +111,18 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * does not connect to any PHY interface.
- 	 */
- 	ret = stmmac_pci_find_phy_addr(pdev, info);
--	if (ret < 0)
--		return ret;
-+	if (ret < 0) {
-+		/* Return error to the caller on DMI enabled boards. */
-+		if (dmi_get_system_info(DMI_BOARD_NAME))
-+			return ret;
-+
-+		/*
-+		 * Galileo boards with old firmware don't support DMI. We always
-+		 * use 1 here as PHY address, so at least the first found MAC
-+		 * controller would be probed.
-+		 */
-+		ret = 1;
-+	}
- 
- 	plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
- 	plat->phy_addr = ret;
--- 
-2.16.4
-

+ 0 - 165
board/PSG/iot2000/linux-4.4-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch

@@ -1,165 +0,0 @@
-From 95e91552d7a7d0fd28afc42191d8be1c3096d6c2 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:00 +0200
-Subject: [PATCH 04/32] stmmac: pci: Select quark_pci_dmi_data from
- quark_default_data
-
-Commit 7bc519b3ea04026877242328d2fe73cc8e6102bd upsteam.
-
-No need to carry this reference in stmmac_pci_info - the Quark-specific
-setup handler knows that it needs to use the Quark-specific DMI table.
-This also allows to drop the stmmac_pci_info reference from the setup
-handler parameter list.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 83 +++++++++++-------------
- 1 file changed, 39 insertions(+), 44 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 19cf9607618a..9fe6368738ec 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,13 +42,11 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
--		     const struct stmmac_pci_info *info);
--	struct stmmac_pci_dmi_data *dmi;
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    const struct stmmac_pci_info *info)
-+				    struct stmmac_pci_dmi_data *dmi_data)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
-@@ -58,7 +56,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	if (!name)
- 		return -ENODEV;
- 
--	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
-+	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
- 			/* If asset tag is provided, match on it as well. */
- 			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
-@@ -71,8 +69,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- }
- 
- static int stmmac_default_data(struct pci_dev *pdev,
--			       struct plat_stmmacenet_data *plat,
--			       const struct stmmac_pci_info *info)
-+			       struct plat_stmmacenet_data *plat)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -100,9 +97,40 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
-+static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+	{
-+		.name = "Galileo",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "GalileoGen2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-0YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 7,
-+		.phy_addr = 1,
-+	},
-+	{}
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
--			      struct plat_stmmacenet_data *plat,
--			      const struct stmmac_pci_info *info)
-+			      struct plat_stmmacenet_data *plat)
- {
- 	int ret;
- 
-@@ -110,7 +138,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, info);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
-@@ -147,41 +175,8 @@ static int quark_default_data(struct pci_dev *pdev,
- 	return 0;
- }
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
--	{
--		.name = "Galileo",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "GalileoGen2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
--	},
--	{}
--};
--
- static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
--	.dmi = quark_pci_dmi_data,
- };
- 
- /**
-@@ -240,7 +235,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	ret = info->setup(pdev, plat, info);
-+	ret = info->setup(pdev, plat);
- 	if (ret)
- 		return ret;
- 
--- 
-2.16.4
-

+ 0 - 167
board/PSG/iot2000/linux-4.4-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch

@@ -1,167 +0,0 @@
-From d771759e71dfab46de09fc2efcd1282926a775b8 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:01 +0200
-Subject: [PATCH 05/32] stmmac: pci: Use dmi_system_id table for retrieving PHY
- addresses
-
-Commit 8d78b69091845386b6096f3adae98f28b9bf96ed upstream.
-
-Avoids reimplementation of DMI matching in stmmac_pci_find_phy_addr.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 97 ++++++++++++++++--------
- 1 file changed, 64 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 9fe6368738ec..279a1355d75f 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -34,36 +34,39 @@
-  * negative value of the address means that MAC controller is not connected
-  * with PHY.
-  */
--struct stmmac_pci_dmi_data {
--	const char *name;
--	const char *asset_tag;
-+struct stmmac_pci_func_data {
- 	unsigned int func;
- 	int phy_addr;
- };
- 
-+struct stmmac_pci_dmi_data {
-+	const struct stmmac_pci_func_data *func;
-+	size_t nfuncs;
-+};
-+
- struct stmmac_pci_info {
- 	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    struct stmmac_pci_dmi_data *dmi_data)
-+				    const struct dmi_system_id *dmi_list)
- {
--	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
--	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(pdev->devfn);
--	struct stmmac_pci_dmi_data *dmi;
--
--	if (!name)
-+	const struct stmmac_pci_func_data *func_data;
-+	const struct stmmac_pci_dmi_data *dmi_data;
-+	const struct dmi_system_id *dmi_id;
-+	int func = PCI_FUNC(pdev->devfn);
-+	size_t n;
-+
-+	dmi_id = dmi_first_match(dmi_list);
-+	if (!dmi_id)
- 		return -ENODEV;
- 
--	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
--		if (!strcmp(dmi->name, name) && dmi->func == func) {
--			/* If asset tag is provided, match on it as well. */
--			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
--				continue;
--			return dmi->phy_addr;
--		}
--	}
-+	dmi_data = dmi_id->driver_data;
-+	func_data = dmi_data->func;
-+
-+	for (n = 0; n < dmi_data->nfuncs; n++, func_data++)
-+		if (func_data->func == func)
-+			return func_data->phy_addr;
- 
- 	return -ENODEV;
- }
-@@ -97,34 +100,62 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
- 	{
--		.name = "Galileo",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = {
-+	.func = galileo_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(galileo_stmmac_func_data),
-+};
-+
-+static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = {
- 	{
--		.name = "GalileoGen2",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
-+		.func = 7,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = {
-+	.func = iot2040_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data),
-+};
-+
-+static const struct dmi_system_id quark_pci_dmi[] = {
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-0YA2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-1YA2"),
-+		},
-+		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
- 	{}
- };
-@@ -138,7 +169,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
--- 
-2.16.4
-

+ 0 - 47
board/PSG/iot2000/linux-4.4-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch

@@ -1,47 +0,0 @@
-From 81aabe391560f74d9dafc5b139b3b3c2e6de08df Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:08:11 +0200
-Subject: [PATCH 06/32] stmmac: pci: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. The IOT2020 is identified by its unique
-asset tag. Match on it first. If we then match on the board name only,
-we will catch all IOT2040 variants. In the future there will be no other
-devices with the "SIMATIC IOT2000" DMI board name but different
-hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 279a1355d75f..ac733d4d3ed4 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -149,11 +149,15 @@ static const struct dmi_system_id quark_pci_dmi[] = {
- 		},
- 		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
-+	/*
-+	 * There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040.
-+	 * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which
-+	 * has only one pci network device while other asset tags are
-+	 * for IOT2040 which has two.
-+	 */
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
--- 
-2.16.4
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch

@@ -1,44 +0,0 @@
-From 186847dd575416b337ae370b46744a163fcf31fc Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:12:37 +0200
-Subject: [PATCH 07/32] serial: 8250_exar: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-As only the IOT2040 variants have the Exar chip on board, matching on
-their board name is enough. In the future there will be no other devices
-with the "SIMATIC IOT2000" DMI board name but different hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/tty/serial/8250/8250_exar.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
-index be82707d6cb8..3eb3a7674a0f 100644
---- a/drivers/tty/serial/8250/8250_exar.c
-+++ b/drivers/tty/serial/8250/8250_exar.c
-@@ -338,12 +338,15 @@ static const struct exar8250_platform iot2040_platform = {
- 	.register_gpio = iot2040_register_gpio,
- };
- 
-+/*
-+ * For SIMATIC IOT2000, only IOT2040 and its variants have the Exar device,
-+ * IOT2020 doesn't have. Therefore it is sufficient to match on the common
-+ * board name after the device was found.
-+ */
- static const struct dmi_system_id exar_platforms[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_platform,
- 	},
--- 
-2.16.4
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch

@@ -1,45 +0,0 @@
-From f95eb6b146bc6107b082c8d600ac5ae51c05054e Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:05:07 +0200
-Subject: [PATCH 08/32] mfd: intel_quark_i2c_gpio: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. Both are identical regarding the
-intel_quark_i2c_gpio. In the future there will be no other devices with
-the "SIMATIC IOT2000" DMI board name but different hardware. So remove
-the asset tag matching from this driver.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/mfd/intel_quark_i2c_gpio.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
-index 1c09604978d3..ad70a058bea8 100644
---- a/drivers/mfd/intel_quark_i2c_gpio.c
-+++ b/drivers/mfd/intel_quark_i2c_gpio.c
-@@ -76,16 +76,6 @@ static const struct dmi_system_id dmi_platform_info[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-0YA2"),
--		},
--		.driver_data = (void *)400000,
--	},
--	{
--		.matches = {
--			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)400000,
- 	},
--- 
-2.16.4
-

+ 0 - 86
board/PSG/iot2000/linux-4.4-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch

@@ -1,86 +0,0 @@
-From 31273219d4787459eea40094ac811a24cf20eaf6 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Dec 2015 14:21:49 +0100
-Subject: [PATCH 09/32] gpio: sch: use gpiochip data pointer
-
-This makes the driver use the data pointer added to the gpio_chip
-to store a pointer to the state container instead of relying on
-container_of().
-
-Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index b72906f5b999..23907fc080a3 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -41,8 +41,6 @@ struct sch_gpio {
- 	unsigned short resume_base;
- };
- 
--#define to_sch_gpio(gc)	container_of(gc, struct sch_gpio, chip)
--
- static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
- 				unsigned reg)
- {
-@@ -65,7 +63,7 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
- 
- static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -80,7 +78,7 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 			     int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -97,7 +95,7 @@ static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 
- static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
-@@ -112,7 +110,7 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- 
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GLV, val);
-@@ -122,7 +120,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 				  int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
-@@ -217,7 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return gpiochip_add(&sch->chip);
-+	return gpiochip_add_data(&sch->chip, sch);
- }
- 
- static int sch_gpio_remove(struct platform_device *pdev)
--- 
-2.16.4
-

+ 0 - 46
board/PSG/iot2000/linux-4.4-patches/0010-gpio-sch-Use-devm_gpiochip_add_data-for-gpio-registr.patch

@@ -1,46 +0,0 @@
-From 01837820d1cc75845d0c771f24eea5fe3d4ae109 Mon Sep 17 00:00:00 2001
-From: Laxman Dewangan <ldewangan@nvidia.com>
-Date: Mon, 22 Feb 2016 17:43:28 +0530
-Subject: [PATCH 10/32] gpio: sch: Use devm_gpiochip_add_data() for gpio
- registration
-
-Use devm_gpiochip_add_data() for GPIO registration and remove the
-need of driver callback .remove.
-
-Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
----
- drivers/gpio/gpio-sch.c | 11 +----------
- 1 file changed, 1 insertion(+), 10 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 23907fc080a3..bbf9b2a34da8 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -215,15 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return gpiochip_add_data(&sch->chip, sch);
--}
--
--static int sch_gpio_remove(struct platform_device *pdev)
--{
--	struct sch_gpio *sch = platform_get_drvdata(pdev);
--
--	gpiochip_remove(&sch->chip);
--	return 0;
-+	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
- }
- 
- static struct platform_driver sch_gpio_driver = {
-@@ -231,7 +223,6 @@ static struct platform_driver sch_gpio_driver = {
- 		.name = "sch_gpio",
- 	},
- 	.probe		= sch_gpio_probe,
--	.remove		= sch_gpio_remove,
- };
- 
- module_platform_driver(sch_gpio_driver);
--- 
-2.16.4
-

+ 0 - 114
board/PSG/iot2000/linux-4.4-patches/0011-gpio-sch-Fix-Oops-on-module-load-on-Asus-Eee-PC-1201.patch

@@ -1,114 +0,0 @@
-From 3ecc35879dfd4a4df2ae418892743446fe05f3a0 Mon Sep 17 00:00:00 2001
-From: Colin Pitrat <colin.pitrat@gmail.com>
-Date: Sat, 18 Jun 2016 19:05:04 +0100
-Subject: [PATCH 11/32] gpio: sch: Fix Oops on module load on Asus Eee PC 1201
-
-This fixes the issue descirbe in bug 117531
-(https://bugzilla.kernel.org/show_bug.cgi?id=117531).
-It's a regression introduced in linux 4.5 that causes a Oops at load of
-gpio_sch and prevents powering off the computer.
-
-The issue is that sch_gpio_reg_set is called in sch_gpio_probe before
-gpio_chip data is initialized with the pointer to the sch_gpio struct. As
-sch_gpio_reg_set calls gpiochip_get_data, it returns NULL which causes
-the Oops.
-
-The patch follows Mika's advice (https://lkml.org/lkml/2016/5/9/61) and
-consists in modifying sch_gpio_reg_get and sch_gpio_reg_set to take a
-sch_gpio struct directly instead of a gpio_chip, which avoids the call to
-gpiochip_get_data.
-
-Thanks Mika for your patience with me :-)
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Colin Pitrat <colin.pitrat@gmail.com>
-Acked-by: Alexandre Courbot <acourbot@nvidia.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 21 ++++++++++-----------
- 1 file changed, 10 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index bbf9b2a34da8..5f72b177fc80 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -61,9 +61,8 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
- 	return gpio % 8;
- }
- 
--static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
-+static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned gpio, unsigned reg)
- {
--	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -75,10 +74,9 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- 	return reg_val;
- }
- 
--static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
-+static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
- 			     int val)
- {
--	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -98,14 +96,15 @@ static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
-+	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
- 	spin_unlock(&sch->lock);
- 	return 0;
- }
- 
- static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- {
--	return sch_gpio_reg_get(gc, gpio_num, GLV);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	return sch_gpio_reg_get(sch, gpio_num, GLV);
- }
- 
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
-@@ -113,7 +112,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GLV, val);
-+	sch_gpio_reg_set(sch, gpio_num, GLV, val);
- 	spin_unlock(&sch->lock);
- }
- 
-@@ -123,7 +122,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
-+	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
- 	spin_unlock(&sch->lock);
- 
- 	/*
-@@ -182,13 +181,13 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 		 * GPIO7 is configured by the CMC as SLPIOVR
- 		 * Enable GPIO[9:8] core powered gpios explicitly
- 		 */
--		sch_gpio_reg_set(&sch->chip, 8, GEN, 1);
--		sch_gpio_reg_set(&sch->chip, 9, GEN, 1);
-+		sch_gpio_reg_set(sch, 8, GEN, 1);
-+		sch_gpio_reg_set(sch, 9, GEN, 1);
- 		/*
- 		 * SUS_GPIO[2:0] enabled by default
- 		 * Enable SUS_GPIO3 resume powered gpio explicitly
- 		 */
--		sch_gpio_reg_set(&sch->chip, 13, GEN, 1);
-+		sch_gpio_reg_set(sch, 13, GEN, 1);
- 		break;
- 
- 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
--- 
-2.16.4
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-patches/0012-gpio-sch-Implement-.get_direction.patch

@@ -1,45 +0,0 @@
-From 8c5cc2a98dcbcbd4208c62e5709d3669405072f7 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 27 Jun 2018 10:39:31 +0200
-Subject: [PATCH 12/32] gpio: sch: Implement .get_direction()
-
-It's pretty simple to implement the .get_direction() for this
-chip, so let's just do it.
-
-Cc: Denis Turischev <denis.turischev@compulab.co.il>
-Cc: Daniel Krueger <daniel.krueger@systec-electronic.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 5f72b177fc80..6715828c3940 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -138,6 +138,13 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 	return 0;
- }
- 
-+static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned gpio_num)
-+{
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
-+
-+	return sch_gpio_reg_get(sch, gpio_num, GIO);
-+}
-+
- static struct gpio_chip sch_gpio_chip = {
- 	.label			= "sch_gpio",
- 	.owner			= THIS_MODULE,
-@@ -145,6 +152,7 @@ static struct gpio_chip sch_gpio_chip = {
- 	.get			= sch_gpio_get,
- 	.direction_output	= sch_gpio_direction_out,
- 	.set			= sch_gpio_set,
-+	.get_direction		= sch_gpio_get_direction,
- };
- 
- static int sch_gpio_probe(struct platform_device *pdev)
--- 
-2.16.4
-

+ 0 - 230
board/PSG/iot2000/linux-4.4-patches/0013-gpio-sch-Add-interrupt-support.patch

@@ -1,230 +0,0 @@
-From d046375f1bc2a63d945bad8c4026ce1a6eabd838 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Wed, 17 Apr 2019 22:26:22 +0200
-Subject: [PATCH 13/32] gpio: sch: Add interrupt support
-
-Validated on the Quark platform, this adds interrupt support on rising
-and/or falling edges.
-
-Backported from upstream, skipping clean roll-back or errors due to some
-missing devm_* services.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-sch.c | 140 +++++++++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 133 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 6715828c3940..1d1dadebc8c1 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -32,6 +32,10 @@
- #define GEN	0x00
- #define GIO	0x04
- #define GLV	0x08
-+#define GTPE	0x0c
-+#define GTNE	0x10
-+#define GGPE	0x14
-+#define GTS	0x1c
- 
- struct sch_gpio {
- 	struct gpio_chip chip;
-@@ -39,6 +43,7 @@ struct sch_gpio {
- 	unsigned short iobase;
- 	unsigned short core_base;
- 	unsigned short resume_base;
-+	int irq_base;
- };
- 
- static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
-@@ -94,10 +99,11 @@ static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
- static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- 	return 0;
- }
- 
-@@ -110,20 +116,22 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GLV, val);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- }
- 
- static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 				  int val)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- 
- 	/*
- 	 * according to the datasheet, writing to the level register has no
-@@ -145,6 +153,12 @@ static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned gpio_num)
- 	return sch_gpio_reg_get(sch, gpio_num, GIO);
- }
- 
-+static int sch_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset)
-+{
-+	struct sch_gpio *sch = gpiochip_get_data(gpio);
-+	return sch->irq_base + offset;
-+}
-+
- static struct gpio_chip sch_gpio_chip = {
- 	.label			= "sch_gpio",
- 	.owner			= THIS_MODULE,
-@@ -153,12 +167,96 @@ static struct gpio_chip sch_gpio_chip = {
- 	.direction_output	= sch_gpio_direction_out,
- 	.set			= sch_gpio_set,
- 	.get_direction		= sch_gpio_get_direction,
-+	.to_irq			= sch_gpio_to_irq,
- };
- 
-+static u32 sch_sci_handler(void *context)
-+{
-+	struct sch_gpio *sch = context;
-+	unsigned long core_status, resume_status;
-+	unsigned int resume_gpios, offset;
-+
-+	core_status = inl(sch->iobase + GTS);
-+	resume_status = inl(sch->iobase + GTS + 0x20);
-+
-+	if (core_status == 0 && resume_status == 0)
-+		return ACPI_INTERRUPT_NOT_HANDLED;
-+
-+	for_each_set_bit(offset, &core_status, sch->resume_base)
-+		generic_handle_irq(sch->irq_base + offset);
-+
-+	resume_gpios = sch->chip.ngpio - sch->resume_base;
-+	for_each_set_bit(offset, &resume_status, resume_gpios)
-+		generic_handle_irq(sch->irq_base + sch->resume_base + offset);
-+
-+	outl(core_status, sch->iobase + GTS);
-+	outl(resume_status, sch->iobase + GTS + 0x20);
-+
-+	return ACPI_INTERRUPT_HANDLED;
-+}
-+
-+static int sch_irq_type(struct irq_data *d, unsigned int type)
-+{
-+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-+	struct sch_gpio *sch = gc->private;
-+	unsigned int gpio_num = d->irq - sch->irq_base;
-+	unsigned long flags;
-+	int rising = 0;
-+	int falling = 0;
-+
-+	switch (type & IRQ_TYPE_SENSE_MASK) {
-+	case IRQ_TYPE_EDGE_RISING:
-+		rising = 1;
-+		break;
-+	case IRQ_TYPE_EDGE_FALLING:
-+		falling = 1;
-+		break;
-+	case IRQ_TYPE_EDGE_BOTH:
-+		rising = 1;
-+		falling = 1;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	spin_lock_irqsave(&sch->lock, flags);
-+	sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
-+	sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
-+	spin_unlock_irqrestore(&sch->lock, flags);
-+
-+	return 0;
-+}
-+
-+static void sch_irq_set_enable(struct irq_data *d, int val)
-+{
-+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-+	struct sch_gpio *sch = gc->private;
-+	unsigned int gpio_num = d->irq - sch->irq_base;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&sch->lock, flags);
-+	sch_gpio_reg_set(sch, gpio_num, GGPE, val);
-+	spin_unlock_irqrestore(&sch->lock, flags);
-+}
-+
-+static void sch_irq_mask(struct irq_data *d)
-+{
-+	sch_irq_set_enable(d, 0);
-+}
-+
-+static void sch_irq_unmask(struct irq_data *d)
-+{
-+	sch_irq_set_enable(d, 1);
-+}
-+
- static int sch_gpio_probe(struct platform_device *pdev)
- {
-+	struct irq_chip_generic *gc;
-+	struct irq_chip_type *ct;
- 	struct sch_gpio *sch;
- 	struct resource *res;
-+	acpi_status status;
-+	int irq_base, ret;
- 
- 	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
- 	if (!sch)
-@@ -222,7 +320,35 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
-+	ret = devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
-+	if (ret)
-+		return ret;
-+
-+	irq_base = irq_alloc_descs(-1, 0, sch->chip.ngpio, NUMA_NO_NODE);
-+	if (irq_base < 0)
-+		return irq_base;
-+	sch->irq_base = irq_base;
-+
-+	gc = irq_alloc_generic_chip("sch_gpio", 1, irq_base,
-+				    NULL, handle_simple_irq);
-+	if (!gc)
-+		return -ENOMEM;
-+
-+	gc->private = sch;
-+	ct = gc->chip_types;
-+
-+	ct->chip.irq_mask = sch_irq_mask;
-+	ct->chip.irq_unmask = sch_irq_unmask;
-+	ct->chip.irq_set_type = sch_irq_type;
-+
-+	irq_setup_generic_chip(gc, IRQ_MSK(sch->chip.ngpio),
-+			       0, IRQ_NOREQUEST | IRQ_NOPROBE, 0);
-+
-+	status = acpi_install_sci_handler(sch_sci_handler, sch);
-+	if (ACPI_FAILURE(status))
-+		return -EINVAL;
-+
-+	return 0;
- }
- 
- static struct platform_driver sch_gpio_driver = {
--- 
-2.16.4
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-patches/0014-iot2000-hack-Work-around-DSDT-mistake.patch

@@ -1,44 +0,0 @@
-From 63e4ba1816a80a258e4c7a846b3bd389b9a04e32 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 25 May 2017 11:09:42 +0200
-Subject: [PATCH 14/32] iot2000-hack: Work around DSDT mistake
-
-Until we have a new firmware revision, fix up the incorrect GPIO
-interrupt pin in software.
-
-Nothing for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpiolib-acpi.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
-index 16a7b6816744..304855b3ecb8 100644
---- a/drivers/gpio/gpiolib-acpi.c
-+++ b/drivers/gpio/gpiolib-acpi.c
-@@ -10,6 +10,7 @@
-  * published by the Free Software Foundation.
-  */
- 
-+#include <linux/dmi.h>
- #include <linux/errno.h>
- #include <linux/gpio.h>
- #include <linux/gpio/consumer.h>
-@@ -408,6 +409,13 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
- 		if (pin_index >= agpio->pin_table_length)
- 			return 1;
- 
-+		if (!strcmp(dmi_get_system_info(DMI_BOARD_NAME),
-+			    "SIMATIC IOT2000") &&
-+		    !strcmp(agpio->resource_source.string_ptr,
-+			    "\\_SB.PCI0.GIP0.GPO") &&
-+		    agpio->pin_table[pin_index] == 9)
-+			agpio->pin_table[pin_index] = 1;
-+
- 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
- 					      agpio->pin_table[pin_index]);
- 		lookup->info.gpioint =
--- 
-2.16.4
-

+ 0 - 42
board/PSG/iot2000/linux-4.4-patches/0015-iot2000-hack-Adjust-pca9685-gpio-base-for-legacy-com.patch

@@ -1,42 +0,0 @@
-From e679338fe980d8722246366906bf71971fa2f538 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 25 May 2017 13:05:12 +0200
-Subject: [PATCH 15/32] iot2000-hack: Adjust pca9685-gpio base for legacy
- compatibility
-
-mraa and the Arduino runtime expect this.
-
-Not for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/pwm/pwm-pca9685.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
-index d2b92e940e38..611b9263a896 100644
---- a/drivers/pwm/pwm-pca9685.c
-+++ b/drivers/pwm/pwm-pca9685.c
-@@ -19,6 +19,7 @@
-  * this program.  If not, see <http://www.gnu.org/licenses/>.
-  */
- 
-+#include <linux/dmi.h>
- #include <linux/acpi.h>
- #include <linux/gpio/driver.h>
- #include <linux/i2c.h>
-@@ -222,7 +223,10 @@ static int pca9685_pwm_gpio_probe(struct pca9685 *pca)
- 	pca->gpio.direction_output = pca9685_pwm_gpio_direction_output;
- 	pca->gpio.get = pca9685_pwm_gpio_get;
- 	pca->gpio.set = pca9685_pwm_gpio_set;
--	pca->gpio.base = -1;
-+	if (!strcmp(dmi_get_system_info(DMI_BOARD_NAME), "SIMATIC IOT2000"))
-+		pca->gpio.base = 64;
-+	else
-+		pca->gpio.base = -1;
- 	pca->gpio.ngpio = PCA9685_MAXCHAN;
- 	pca->gpio.can_sleep = true;
- 
--- 
-2.16.4
-

+ 0 - 99
board/PSG/iot2000/linux-4.4-patches/0016-iot2000-hack-gpio-pca953x-provide-GPIO-base-based-on.patch

@@ -1,99 +0,0 @@
-From b4513d4a15616321e240c93436e8ffd58aa931ed Mon Sep 17 00:00:00 2001
-From: Yong Li <sdliyong@gmail.com>
-Date: Thu, 31 Mar 2016 15:33:08 +0800
-Subject: [PATCH 16/32] iot2000-hack: gpio: pca953x: provide GPIO base based on
- _UID
-
-Custom kernel for Intel Galileo Gen2 provides and moreover libmraa relies on
-the continuous GPIO space. To do such we have to configure GPIO base per each
-GPIO expander. The only value we can use is the ACPI _UID.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-
-Upstream-status: Inappropriate, custom code for legacy userspace
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Yong Li <sdliyong@gmail.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-pca953x.c | 44 +++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 37 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index b45ba6be69ef..8b467c0db1cb 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -82,12 +82,6 @@ static const struct i2c_device_id pca953x_id[] = {
- };
- MODULE_DEVICE_TABLE(i2c, pca953x_id);
- 
--static const struct acpi_device_id pca953x_acpi_ids[] = {
--	{ "INT3491", 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
--	{ }
--};
--MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
--
- #define MAX_BANK 5
- #define BANK_SZ 8
- 
-@@ -119,6 +113,35 @@ static inline struct pca953x_chip *to_pca(struct gpio_chip *gc)
- 	return container_of(gc, struct pca953x_chip, gpio_chip);
- }
- 
-+struct pca953x_info {
-+	kernel_ulong_t driver_data;
-+	void (*setup)(struct pca953x_chip *chip);
-+};
-+
-+static void pca953x_setup_int3491(struct pca953x_chip *chip)
-+{
-+	struct acpi_device *adev = ACPI_COMPANION(&chip->client->dev);
-+	unsigned int uid;
-+
-+	if (kstrtouint(acpi_device_uid(adev), 0, &uid) || !uid--)
-+		return;
-+
-+	chip->gpio_start = 8 /* sch_gpio */ +
-+			   8 /* gpio-dwapb */ +
-+			  16 /* pca9535 */ * uid;
-+}
-+
-+static const struct pca953x_info pca953x_info_int3491 = {
-+	.driver_data = 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL,
-+	.setup = pca953x_setup_int3491,
-+};
-+
-+static const struct acpi_device_id pca953x_acpi_ids[] = {
-+	{ "INT3491",  (kernel_ulong_t)&pca953x_info_int3491 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
-+
- static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
- 				int off)
- {
-@@ -731,12 +754,19 @@ static int pca953x_probe(struct i2c_client *client,
- 		chip->driver_data = id->driver_data;
- 	} else {
- 		const struct acpi_device_id *id;
-+		const struct pca953x_info *info;
- 
- 		id = acpi_match_device(pca953x_acpi_ids, &client->dev);
- 		if (!id)
- 			return -ENODEV;
- 
--		chip->driver_data = id->driver_data;
-+		info = (struct pca953x_info *)id->driver_data;
-+		if (!info)
-+			return -ENODEV;
-+
-+		chip->driver_data = info->driver_data;
-+		if (info->setup)
-+			info->setup(chip);
- 	}
- 
- 	chip->chip_type = PCA_CHIP_TYPE(chip->driver_data);
--- 
-2.16.4
-

+ 0 - 334
board/PSG/iot2000/linux-4.4-patches/0017-iot2000-hack-gpio-pca953x-add-drive-property.patch

@@ -1,334 +0,0 @@
-From 7190fa3b9d76d0d554dab7c0a220a2be3e866560 Mon Sep 17 00:00:00 2001
-From: Yong Li <sdliyong@gmail.com>
-Date: Thu, 31 Mar 2016 15:33:09 +0800
-Subject: [PATCH 17/32] iot2000-hack: gpio-pca953x: add "drive" property
-
-Galileo gen 2 has support for setting GPIO modes. Expose these
-properties through the GPIO sysfs interface. This approach is bit hacky,
-since it changes the interface semantics.
-
-The original patch was by Josef Ahmad <josef.ahmad@linux.intel.com> and
-made on top of kernel 3.8.
-
-Not for upstream.
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Jussi Laako <jussi.laako@linux.intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Yong Li <sdliyong@gmail.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-pca953x.c   | 42 +++++++++++++++++++++++
- drivers/gpio/gpiolib-sysfs.c  | 78 +++++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib.c        | 17 ++++++++++
- drivers/gpio/gpiolib.h        |  4 +++
- include/asm-generic/gpio.h    |  5 +++
- include/linux/gpio.h          | 10 ++++++
- include/linux/gpio/consumer.h | 11 ++++++
- include/linux/gpio/driver.h   |  2 ++
- 8 files changed, 169 insertions(+)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index 8b467c0db1cb..ca1f6f4d6f59 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -40,6 +40,8 @@
- #define PCA957X_INTS		7
- 
- #define PCAL953X_IN_LATCH	34
-+#define PCAL953X_PUPD_EN	35
-+#define PCAL953X_PUPD_SEL	36
- #define PCAL953X_INT_MASK	37
- #define PCAL953X_INT_STAT	38
- 
-@@ -380,6 +382,43 @@ exit:
- 	mutex_unlock(&chip->i2c_lock);
- }
- 
-+static int pca953x_gpio_set_drive(struct gpio_chip *gc,
-+				 unsigned off, unsigned mode)
-+{
-+	struct pca953x_chip *chip;
-+	int ret = 0;
-+	int val;
-+
-+	chip = container_of(gc, struct pca953x_chip, gpio_chip);
-+
-+	if (!(chip->driver_data & PCA_PCAL))
-+		return -EINVAL;
-+
-+	mutex_lock(&chip->i2c_lock);
-+
-+	switch (mode) {
-+	case GPIOF_DRIVE_PULLUP:
-+		ret = pca953x_write_single(chip, PCAL953X_PUPD_EN, 1, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, 1, off);
-+		break;
-+	case GPIOF_DRIVE_PULLDOWN:
-+		ret = pca953x_write_single(chip, PCAL953X_PUPD_EN, 1, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, 0, off);
-+		break;
-+	case GPIOF_DRIVE_STRONG:
-+	case GPIOF_DRIVE_HIZ:
-+		ret = pca953x_read_single(chip, PCAL953X_PUPD_EN, &val, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_EN, 0, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, val, off);
-+		break;
-+	default:
-+		ret = -EINVAL;
-+	}
-+
-+	mutex_unlock(&chip->i2c_lock);
-+	return ret;
-+}
-+
- static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- {
- 	struct gpio_chip *gc;
-@@ -398,6 +437,9 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- 	gc->dev = &chip->client->dev;
- 	gc->owner = THIS_MODULE;
- 	gc->names = chip->names;
-+
-+	if (chip->driver_data & PCA_PCAL)
-+		gc->set_drive = pca953x_gpio_set_drive;
- }
- 
- #ifdef CONFIG_GPIO_PCA953X_IRQ
-diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
-index b57ed8e55ab5..72a8647146fa 100644
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -7,6 +7,7 @@
- #include <linux/interrupt.h>
- #include <linux/kdev_t.h>
- #include <linux/slab.h>
-+#include <linux/gpio.h>
- 
- #include "gpiolib.h"
- 
-@@ -350,6 +351,82 @@ static ssize_t active_low_store(struct device *dev,
- }
- static DEVICE_ATTR_RW(active_low);
- 
-+
-+static ssize_t gpio_drive_show(struct device *dev,
-+		struct device_attribute *attr, char *buf)
-+{
-+	const struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
-+		status = -EIO;
-+	} else {
-+		if (test_bit(FLAG_PULLUP, &desc->flags))
-+			status = sprintf(buf, "pullup\n");
-+		else if (test_bit(FLAG_PULLDOWN, &desc->flags))
-+			status = sprintf(buf, "pulldown\n");
-+		else if (test_bit(FLAG_STRONG, &desc->flags))
-+			status = sprintf(buf, "strong\n");
-+		else if (test_bit(FLAG_HIZ, &desc->flags))
-+			status = sprintf(buf, "hiz\n");
-+		else
-+			status = -EINVAL;
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status;
-+}
-+
-+static ssize_t gpio_drive_store(struct device *dev,
-+		struct device_attribute *attr, const char *buf, size_t size)
-+{
-+	struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags))
-+		status = -EIO;
-+	else {
-+		clear_bit(FLAG_PULLUP, &desc->flags);
-+		clear_bit(FLAG_PULLDOWN, &desc->flags);
-+		clear_bit(FLAG_STRONG, &desc->flags);
-+		clear_bit(FLAG_HIZ, &desc->flags);
-+		if (sysfs_streq(buf, "pullup")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLUP);
-+			if (!status) {
-+				set_bit(FLAG_PULLUP, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "pulldown")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLDOWN);
-+			if (!status) {
-+				set_bit(FLAG_PULLDOWN, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "strong")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_STRONG);
-+			if (!status) {
-+				set_bit(FLAG_STRONG, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "hiz")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_HIZ);
-+			if (!status) {
-+				set_bit(FLAG_HIZ, &desc->flags);
-+			}
-+		} else {
-+			status = -EINVAL;
-+		}
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status ? : size;
-+}
-+
-+static DEVICE_ATTR(drive, 0644,
-+		gpio_drive_show, gpio_drive_store);
-+
-+
- static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
- 			       int n)
- {
-@@ -377,6 +454,7 @@ static struct attribute *gpio_attrs[] = {
- 	&dev_attr_edge.attr,
- 	&dev_attr_value.attr,
- 	&dev_attr_active_low.attr,
-+	&dev_attr_drive.attr,
- 	NULL,
- };
- 
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index d72218fcaeeb..66d4e4a59035 100644
---- a/drivers/gpio/gpiolib.c
-+++ b/drivers/gpio/gpiolib.c
-@@ -1376,6 +1376,23 @@ int gpiod_is_active_low(const struct gpio_desc *desc)
- }
- EXPORT_SYMBOL_GPL(gpiod_is_active_low);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode)
-+{
-+	struct gpio_chip	*chip;
-+
-+	chip = desc->chip;
-+	if (!chip || !chip->set || !chip->set_drive)
-+		goto fail;
-+
-+	might_sleep_if(chip->can_sleep);
-+
-+	return chip->set_drive(chip, gpio_chip_hwgpio(desc), mode);
-+
-+fail:
-+	return -EINVAL;
-+}
-+EXPORT_SYMBOL_GPL(gpiod_set_drive);
-+
- /* I/O calls are only valid after configuration completed; the relevant
-  * "is this a valid GPIO" error checks should already have been done.
-  *
-diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
-index 07541c5670e6..cfa7406b10fd 100644
---- a/drivers/gpio/gpiolib.h
-+++ b/drivers/gpio/gpiolib.h
-@@ -96,6 +96,10 @@ struct gpio_desc {
- #define FLAG_OPEN_SOURCE 8	/* Gpio is open source type */
- #define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
- #define FLAG_IS_HOGGED	11	/* GPIO is hogged */
-+#define FLAG_PULLUP	12	/* Gpio drive is resistive pullup */
-+#define FLAG_PULLDOWN	13	/* Gpio drive is resistive pulldown */
-+#define FLAG_STRONG	14	/* Gpio drive is strong (fast output) */
-+#define FLAG_HIZ	15	/* Gpio drive is Hi-Z (input) */
- 
- 	/* Connection label */
- 	const char		*label;
-diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
-index 40ec1433f05d..519e8d458878 100644
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -76,6 +76,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return gpiod_set_debounce(gpio_to_desc(gpio), debounce);
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return gpiod_set_drive(gpio_to_desc(gpio), mode);
-+}
-+
- static inline int gpio_get_value_cansleep(unsigned gpio)
- {
- 	return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio));
-diff --git a/include/linux/gpio.h b/include/linux/gpio.h
-index 11555bd821b7..1e8ab82f2787 100644
---- a/include/linux/gpio.h
-+++ b/include/linux/gpio.h
-@@ -30,6 +30,11 @@
- #define GPIOF_EXPORT_DIR_FIXED	(GPIOF_EXPORT)
- #define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE)
- 
-+#define GPIOF_DRIVE_PULLUP	(1 << 7)
-+#define GPIOF_DRIVE_PULLDOWN	(1 << 8)
-+#define GPIOF_DRIVE_STRONG	(1 << 9)
-+#define GPIOF_DRIVE_HIZ		(1 << 10)
-+
- /**
-  * struct gpio - a structure describing a GPIO with configuration
-  * @gpio:	the GPIO number
-@@ -148,6 +153,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return -ENOSYS;
-+}
-+
- static inline int gpio_get_value(unsigned gpio)
- {
- 	/* GPIO can never have been requested or set as {in,out}put */
-diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
-index fb0fde686cb1..17f5f187699b 100644
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -122,6 +122,8 @@ void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
- 
- int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode);
-+
- int gpiod_is_active_low(const struct gpio_desc *desc);
- int gpiod_cansleep(const struct gpio_desc *desc);
- 
-@@ -376,6 +378,15 @@ static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+
-+static inline int gpiod_set_drive(unsigned gpio, unsigned mode)
-+{
-+	/* GPIO can never have been requested */
-+	WARN_ON(1);
-+	return -ENOSYS;
-+}
-+
-+
- static inline int gpiod_is_active_low(const struct gpio_desc *desc)
- {
- 	/* GPIO can never have been requested */
-diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
-index c0fc8effdba9..b73af28ac7d8 100644
---- a/include/linux/gpio/driver.h
-+++ b/include/linux/gpio/driver.h
-@@ -116,6 +116,8 @@ struct gpio_chip {
- 	int			(*set_debounce)(struct gpio_chip *chip,
- 						unsigned offset,
- 						unsigned debounce);
-+	int			(*set_drive)(struct gpio_chip *chip,
-+						unsigned offset, unsigned mode);
- 
- 	int			(*to_irq)(struct gpio_chip *chip,
- 						unsigned offset);
--- 
-2.16.4
-

+ 0 - 105
board/PSG/iot2000/linux-4.4-patches/0018-iot2000-hack-pwm-pca-9685-Provide-chip-level-pwm_per.patch

@@ -1,105 +0,0 @@
-From 0bdd0c91036a0c6a1cb74eebc3a95e08faf9e7b8 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 17 Nov 2017 20:25:54 +0100
-Subject: [PATCH 18/32] iot2000-hack: pwm: pca-9685: Provide chip-level
- pwm_period attribute
-
-Arduino runtime relies on this path to program the PWM period, rather
-than doing this via the upstream kernel API which is per channel.
-
-Another one not for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/pwm/pwm-pca9685.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
-
-diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
-index 611b9263a896..ce765f903714 100644
---- a/drivers/pwm/pwm-pca9685.c
-+++ b/drivers/pwm/pwm-pca9685.c
-@@ -444,6 +444,54 @@ static const struct pwm_ops pca9685_pwm_ops = {
- 	.owner = THIS_MODULE,
- };
- 
-+static ssize_t pwm_period_show(struct device *parent,
-+			       struct device_attribute *attr,
-+			       char *buf)
-+{
-+	struct pwm_chip *chip = dev_get_drvdata(parent);
-+
-+	return sprintf(buf, "%u\n", to_pca(chip)->period_ns);
-+}
-+
-+static ssize_t pwm_period_store(struct device *parent,
-+				struct device_attribute *attr,
-+				const char *buf, size_t size)
-+{
-+	struct pwm_chip *chip = dev_get_drvdata(parent);
-+	struct pca9685 *pca = to_pca(chip);
-+	int old_period_ns = pca->period_ns;
-+	unsigned long long duty_scale, new_duty_ns;
-+	unsigned int val, channel;
-+	struct pwm_device *pwm;
-+	int ret;
-+
-+	ret = kstrtouint(buf, 0, &val);
-+	if (ret)
-+		return ret;
-+
-+	for (channel = 0; channel < PCA9685_MAXCHAN; channel++) {
-+		pwm = &chip->pwms[channel];
-+
-+		if (pca9685_pwm_is_gpio(pca, pwm))
-+			continue;
-+
-+		/* Scale the rise time to maintain duty cycle */
-+		duty_scale = val;
-+		duty_scale *= 1000000;
-+		do_div(duty_scale, old_period_ns);
-+		new_duty_ns = duty_scale * pwm_get_duty_cycle(pwm);
-+		do_div(new_duty_ns, 1000000);
-+		/* Update the duty_cycle */
-+		ret = pwm_config(pwm, (int)new_duty_ns, val);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return size;
-+}
-+
-+static DEVICE_ATTR_RW(pwm_period);
-+
- static const struct regmap_config pca9685_regmap_i2c_config = {
- 	.reg_bits = 8,
- 	.val_bits = 8,
-@@ -504,8 +552,17 @@ static int pca9685_pwm_probe(struct i2c_client *client,
- 	if (ret < 0)
- 		return ret;
- 
-+	ret = sysfs_create_file(&pca->chip.dev->kobj,
-+				&dev_attr_pwm_period.attr);
-+	if (ret < 0) {
-+		pwmchip_remove(&pca->chip);
-+		return ret;
-+	}
-+
- 	ret = pca9685_pwm_gpio_probe(pca);
- 	if (ret < 0) {
-+		sysfs_remove_file(&pca->chip.dev->kobj,
-+				  &dev_attr_pwm_period.attr);
- 		pwmchip_remove(&pca->chip);
- 		return ret;
- 	}
-@@ -526,6 +583,8 @@ static int pca9685_pwm_remove(struct i2c_client *client)
- 	struct pca9685 *pca = i2c_get_clientdata(client);
- 	int ret;
- 
-+	sysfs_remove_file(&pca->chip.dev->kobj, &dev_attr_pwm_period.attr);
-+
- 	ret = pwmchip_remove(&pca->chip);
- 	if (ret)
- 		return ret;
--- 
-2.16.4
-

+ 0 - 801
board/PSG/iot2000/linux-4.4-patches/0019-random-replace-non-blocking-pool-with-a-Chacha20-bas.patch

@@ -1,801 +0,0 @@
-From af72f4e73aa5a951d998e88260154082c5ffd340 Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Sun, 12 Jun 2016 18:13:36 -0400
-Subject: [PATCH 19/32] random: replace non-blocking pool with a Chacha20-based
- CRNG
-
-The CRNG is faster, and we don't pretend to track entropy usage in the
-CRNG any more.
-
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- crypto/chacha20_generic.c |  61 --------
- drivers/char/random.c     | 378 +++++++++++++++++++++++++++++++++-------------
- include/crypto/chacha20.h |   1 +
- lib/Makefile              |   2 +-
- lib/chacha20.c            |  79 ++++++++++
- 5 files changed, 357 insertions(+), 164 deletions(-)
- create mode 100644 lib/chacha20.c
-
-diff --git a/crypto/chacha20_generic.c b/crypto/chacha20_generic.c
-index da9c89968223..1cab83146e33 100644
---- a/crypto/chacha20_generic.c
-+++ b/crypto/chacha20_generic.c
-@@ -15,72 +15,11 @@
- #include <linux/module.h>
- #include <crypto/chacha20.h>
- 
--static inline u32 rotl32(u32 v, u8 n)
--{
--	return (v << n) | (v >> (sizeof(v) * 8 - n));
--}
--
- static inline u32 le32_to_cpuvp(const void *p)
- {
- 	return le32_to_cpup(p);
- }
- 
--static void chacha20_block(u32 *state, void *stream)
--{
--	u32 x[16], *out = stream;
--	int i;
--
--	for (i = 0; i < ARRAY_SIZE(x); i++)
--		x[i] = state[i];
--
--	for (i = 0; i < 20; i += 2) {
--		x[0]  += x[4];    x[12] = rotl32(x[12] ^ x[0],  16);
--		x[1]  += x[5];    x[13] = rotl32(x[13] ^ x[1],  16);
--		x[2]  += x[6];    x[14] = rotl32(x[14] ^ x[2],  16);
--		x[3]  += x[7];    x[15] = rotl32(x[15] ^ x[3],  16);
--
--		x[8]  += x[12];   x[4]  = rotl32(x[4]  ^ x[8],  12);
--		x[9]  += x[13];   x[5]  = rotl32(x[5]  ^ x[9],  12);
--		x[10] += x[14];   x[6]  = rotl32(x[6]  ^ x[10], 12);
--		x[11] += x[15];   x[7]  = rotl32(x[7]  ^ x[11], 12);
--
--		x[0]  += x[4];    x[12] = rotl32(x[12] ^ x[0],   8);
--		x[1]  += x[5];    x[13] = rotl32(x[13] ^ x[1],   8);
--		x[2]  += x[6];    x[14] = rotl32(x[14] ^ x[2],   8);
--		x[3]  += x[7];    x[15] = rotl32(x[15] ^ x[3],   8);
--
--		x[8]  += x[12];   x[4]  = rotl32(x[4]  ^ x[8],   7);
--		x[9]  += x[13];   x[5]  = rotl32(x[5]  ^ x[9],   7);
--		x[10] += x[14];   x[6]  = rotl32(x[6]  ^ x[10],  7);
--		x[11] += x[15];   x[7]  = rotl32(x[7]  ^ x[11],  7);
--
--		x[0]  += x[5];    x[15] = rotl32(x[15] ^ x[0],  16);
--		x[1]  += x[6];    x[12] = rotl32(x[12] ^ x[1],  16);
--		x[2]  += x[7];    x[13] = rotl32(x[13] ^ x[2],  16);
--		x[3]  += x[4];    x[14] = rotl32(x[14] ^ x[3],  16);
--
--		x[10] += x[15];   x[5]  = rotl32(x[5]  ^ x[10], 12);
--		x[11] += x[12];   x[6]  = rotl32(x[6]  ^ x[11], 12);
--		x[8]  += x[13];   x[7]  = rotl32(x[7]  ^ x[8],  12);
--		x[9]  += x[14];   x[4]  = rotl32(x[4]  ^ x[9],  12);
--
--		x[0]  += x[5];    x[15] = rotl32(x[15] ^ x[0],   8);
--		x[1]  += x[6];    x[12] = rotl32(x[12] ^ x[1],   8);
--		x[2]  += x[7];    x[13] = rotl32(x[13] ^ x[2],   8);
--		x[3]  += x[4];    x[14] = rotl32(x[14] ^ x[3],   8);
--
--		x[10] += x[15];   x[5]  = rotl32(x[5]  ^ x[10],  7);
--		x[11] += x[12];   x[6]  = rotl32(x[6]  ^ x[11],  7);
--		x[8]  += x[13];   x[7]  = rotl32(x[7]  ^ x[8],   7);
--		x[9]  += x[14];   x[4]  = rotl32(x[4]  ^ x[9],   7);
--	}
--
--	for (i = 0; i < ARRAY_SIZE(x); i++)
--		out[i] = cpu_to_le32(x[i] + state[i]);
--
--	state[12]++;
--}
--
- static void chacha20_docrypt(u32 *state, u8 *dst, const u8 *src,
- 			     unsigned int bytes)
- {
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 2916d08ee30e..6d2abeae9434 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -260,6 +260,7 @@
- #include <linux/irq.h>
- #include <linux/syscalls.h>
- #include <linux/completion.h>
-+#include <crypto/chacha20.h>
- 
- #include <asm/processor.h>
- #include <asm/uaccess.h>
-@@ -412,6 +413,31 @@ static struct fasync_struct *fasync;
- static DEFINE_SPINLOCK(random_ready_list_lock);
- static LIST_HEAD(random_ready_list);
- 
-+struct crng_state {
-+	__u32		state[16];
-+	unsigned long	init_time;
-+	spinlock_t	lock;
-+};
-+
-+struct crng_state primary_crng = {
-+	.lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock),
-+};
-+
-+/*
-+ * crng_init =  0 --> Uninitialized
-+ *		1 --> Initialized
-+ *		2 --> Initialized from input_pool
-+ *
-+ * crng_init is protected by primary_crng->lock, and only increases
-+ * its value (from 0->1->2).
-+ */
-+static int crng_init = 0;
-+#define crng_ready() (likely(crng_init > 0))
-+static int crng_init_cnt = 0;
-+#define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
-+static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]);
-+static void process_random_ready_list(void);
-+
- /**********************************************************************
-  *
-  * OS independent entropy store.   Here are the functions which handle
-@@ -441,10 +467,15 @@ struct entropy_store {
- 	__u8 last_data[EXTRACT_SIZE];
- };
- 
-+static ssize_t extract_entropy(struct entropy_store *r, void *buf,
-+			       size_t nbytes, int min, int rsvd);
-+static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
-+				size_t nbytes, int fips);
-+
-+static void crng_reseed(struct crng_state *crng, struct entropy_store *r);
- static void push_to_pool(struct work_struct *work);
- static __u32 input_pool_data[INPUT_POOL_WORDS];
- static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
--static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
- 
- static struct entropy_store input_pool = {
- 	.poolinfo = &poolinfo_table[0],
-@@ -465,16 +496,6 @@ static struct entropy_store blocking_pool = {
- 					push_to_pool),
- };
- 
--static struct entropy_store nonblocking_pool = {
--	.poolinfo = &poolinfo_table[1],
--	.name = "nonblocking",
--	.pull = &input_pool,
--	.lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock),
--	.pool = nonblocking_pool_data,
--	.push_work = __WORK_INITIALIZER(nonblocking_pool.push_work,
--					push_to_pool),
--};
--
- static __u32 const twist_table[8] = {
- 	0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
- 	0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
-@@ -677,12 +698,6 @@ retry:
- 	if (!r->initialized && r->entropy_total > 128) {
- 		r->initialized = 1;
- 		r->entropy_total = 0;
--		if (r == &nonblocking_pool) {
--			prandom_reseed_late();
--			process_random_ready_list();
--			wake_up_all(&urandom_init_wait);
--			pr_notice("random: %s pool is initialized\n", r->name);
--		}
- 	}
- 
- 	trace_credit_entropy_bits(r->name, nbits,
-@@ -692,30 +707,27 @@ retry:
- 	if (r == &input_pool) {
- 		int entropy_bits = entropy_count >> ENTROPY_SHIFT;
- 
-+		if (crng_init < 2 && entropy_bits >= 128) {
-+			crng_reseed(&primary_crng, r);
-+			entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
-+		}
-+
- 		/* should we wake readers? */
- 		if (entropy_bits >= random_read_wakeup_bits) {
- 			wake_up_interruptible(&random_read_wait);
- 			kill_fasync(&fasync, SIGIO, POLL_IN);
- 		}
- 		/* If the input pool is getting full, send some
--		 * entropy to the two output pools, flipping back and
--		 * forth between them, until the output pools are 75%
--		 * full.
-+		 * entropy to the blocking pool until it is 75% full.
- 		 */
- 		if (entropy_bits > random_write_wakeup_bits &&
- 		    r->initialized &&
- 		    r->entropy_total >= 2*random_read_wakeup_bits) {
--			static struct entropy_store *last = &blocking_pool;
- 			struct entropy_store *other = &blocking_pool;
- 
--			if (last == &blocking_pool)
--				other = &nonblocking_pool;
- 			if (other->entropy_count <=
--			    3 * other->poolinfo->poolfracbits / 4)
--				last = other;
--			if (last->entropy_count <=
--			    3 * last->poolinfo->poolfracbits / 4) {
--				schedule_work(&last->push_work);
-+			    3 * other->poolinfo->poolfracbits / 4) {
-+				schedule_work(&other->push_work);
- 				r->entropy_total = 0;
- 			}
- 		}
-@@ -736,6 +748,152 @@ static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
- 	return 0;
- }
- 
-+/*********************************************************************
-+ *
-+ * CRNG using CHACHA20
-+ *
-+ *********************************************************************/
-+
-+#define CRNG_RESEED_INTERVAL (300*HZ)
-+
-+static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
-+
-+static void crng_initialize(struct crng_state *crng)
-+{
-+	int		i;
-+	unsigned long	rv;
-+
-+	memcpy(&crng->state[0], "expand 32-byte k", 16);
-+	if (crng == &primary_crng)
-+		_extract_entropy(&input_pool, &crng->state[4],
-+				 sizeof(__u32) * 12, 0);
-+	else
-+		get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
-+	for (i = 4; i < 16; i++) {
-+		if (!arch_get_random_seed_long(&rv) &&
-+		    !arch_get_random_long(&rv))
-+			rv = random_get_entropy();
-+		crng->state[i] ^= rv;
-+	}
-+	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
-+}
-+
-+static int crng_fast_load(const char *cp, size_t len)
-+{
-+	unsigned long flags;
-+	char *p;
-+
-+	if (!spin_trylock_irqsave(&primary_crng.lock, flags))
-+		return 0;
-+	if (crng_ready()) {
-+		spin_unlock_irqrestore(&primary_crng.lock, flags);
-+		return 0;
-+	}
-+	p = (unsigned char *) &primary_crng.state[4];
-+	while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) {
-+		p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp;
-+		cp++; crng_init_cnt++; len--;
-+	}
-+	if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
-+		crng_init = 1;
-+		wake_up_interruptible(&crng_init_wait);
-+		pr_notice("random: fast init done\n");
-+	}
-+	spin_unlock_irqrestore(&primary_crng.lock, flags);
-+	return 1;
-+}
-+
-+static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
-+{
-+	unsigned long	flags;
-+	int		i, num;
-+	union {
-+		__u8	block[CHACHA20_BLOCK_SIZE];
-+		__u32	key[8];
-+	} buf;
-+
-+	if (r) {
-+		num = extract_entropy(r, &buf, 32, 16, 0);
-+		if (num == 0)
-+			return;
-+	} else
-+		extract_crng(buf.block);
-+	spin_lock_irqsave(&primary_crng.lock, flags);
-+	for (i = 0; i < 8; i++) {
-+		unsigned long	rv;
-+		if (!arch_get_random_seed_long(&rv) &&
-+		    !arch_get_random_long(&rv))
-+			rv = random_get_entropy();
-+		crng->state[i+4] ^= buf.key[i] ^ rv;
-+	}
-+	memzero_explicit(&buf, sizeof(buf));
-+	crng->init_time = jiffies;
-+	if (crng == &primary_crng && crng_init < 2) {
-+		crng_init = 2;
-+		process_random_ready_list();
-+		wake_up_interruptible(&crng_init_wait);
-+		pr_notice("random: crng init done\n");
-+	}
-+	spin_unlock_irqrestore(&primary_crng.lock, flags);
-+}
-+
-+static inline void crng_wait_ready(void)
-+{
-+	wait_event_interruptible(crng_init_wait, crng_ready());
-+}
-+
-+static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
-+{
-+	unsigned long v, flags;
-+	struct crng_state *crng = &primary_crng;
-+
-+	if (crng_init > 1 &&
-+	    time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
-+		crng_reseed(crng, &input_pool);
-+	spin_lock_irqsave(&crng->lock, flags);
-+	if (arch_get_random_long(&v))
-+		crng->state[14] ^= v;
-+	chacha20_block(&crng->state[0], out);
-+	if (crng->state[12] == 0)
-+		crng->state[13]++;
-+	spin_unlock_irqrestore(&crng->lock, flags);
-+}
-+
-+static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
-+{
-+	ssize_t ret = 0, i;
-+	__u8 tmp[CHACHA20_BLOCK_SIZE];
-+	int large_request = (nbytes > 256);
-+
-+	while (nbytes) {
-+		if (large_request && need_resched()) {
-+			if (signal_pending(current)) {
-+				if (ret == 0)
-+					ret = -ERESTARTSYS;
-+				break;
-+			}
-+			schedule();
-+		}
-+
-+		extract_crng(tmp);
-+		i = min_t(int, nbytes, CHACHA20_BLOCK_SIZE);
-+		if (copy_to_user(buf, tmp, i)) {
-+			ret = -EFAULT;
-+			break;
-+		}
-+
-+		nbytes -= i;
-+		buf += i;
-+		ret += i;
-+	}
-+
-+	/* Wipe data just written to memory */
-+	memzero_explicit(tmp, sizeof(tmp));
-+
-+	return ret;
-+}
-+
-+
- /*********************************************************************
-  *
-  * Entropy input management
-@@ -752,12 +910,12 @@ struct timer_rand_state {
- #define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, };
- 
- /*
-- * Add device- or boot-specific data to the input and nonblocking
-- * pools to help initialize them to unique values.
-+ * Add device- or boot-specific data to the input pool to help
-+ * initialize it.
-  *
-- * None of this adds any entropy, it is meant to avoid the
-- * problem of the nonblocking pool having similar initial state
-- * across largely identical devices.
-+ * None of this adds any entropy; it is meant to avoid the problem of
-+ * the entropy pool having similar initial state across largely
-+ * identical devices.
-  */
- void add_device_randomness(const void *buf, unsigned int size)
- {
-@@ -769,11 +927,6 @@ void add_device_randomness(const void *buf, unsigned int size)
- 	_mix_pool_bytes(&input_pool, buf, size);
- 	_mix_pool_bytes(&input_pool, &time, sizeof(time));
- 	spin_unlock_irqrestore(&input_pool.lock, flags);
--
--	spin_lock_irqsave(&nonblocking_pool.lock, flags);
--	_mix_pool_bytes(&nonblocking_pool, buf, size);
--	_mix_pool_bytes(&nonblocking_pool, &time, sizeof(time));
--	spin_unlock_irqrestore(&nonblocking_pool.lock, flags);
- }
- EXPORT_SYMBOL(add_device_randomness);
- 
-@@ -804,7 +957,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
- 	sample.jiffies = jiffies;
- 	sample.cycles = random_get_entropy();
- 	sample.num = num;
--	r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
-+	r = &input_pool;
- 	mix_pool_bytes(r, &sample, sizeof(sample));
- 
- 	/*
-@@ -924,11 +1077,21 @@ void add_interrupt_randomness(int irq, int irq_flags)
- 	fast_mix(fast_pool);
- 	add_interrupt_bench(cycles);
- 
-+	if (!crng_ready()) {
-+		if ((fast_pool->count >= 64) &&
-+		    crng_fast_load((char *) fast_pool->pool,
-+				   sizeof(fast_pool->pool))) {
-+			fast_pool->count = 0;
-+			fast_pool->last = now;
-+		}
-+		return;
-+	}
-+
- 	if ((fast_pool->count < 64) &&
- 	    !time_after(now, fast_pool->last + HZ))
- 		return;
- 
--	r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
-+	r = &input_pool;
- 	if (!spin_trylock(&r->lock))
- 		return;
- 
-@@ -972,9 +1135,6 @@ EXPORT_SYMBOL_GPL(add_disk_randomness);
-  *
-  *********************************************************************/
- 
--static ssize_t extract_entropy(struct entropy_store *r, void *buf,
--			       size_t nbytes, int min, int rsvd);
--
- /*
-  * This utility inline function is responsible for transferring entropy
-  * from the primary pool to the secondary extraction pool. We make
-@@ -1149,6 +1309,36 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
- 	memzero_explicit(&hash, sizeof(hash));
- }
- 
-+static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
-+				size_t nbytes, int fips)
-+{
-+	ssize_t ret = 0, i;
-+	__u8 tmp[EXTRACT_SIZE];
-+	unsigned long flags;
-+
-+	while (nbytes) {
-+		extract_buf(r, tmp);
-+
-+		if (fips) {
-+			spin_lock_irqsave(&r->lock, flags);
-+			if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
-+				panic("Hardware RNG duplicated output!\n");
-+			memcpy(r->last_data, tmp, EXTRACT_SIZE);
-+			spin_unlock_irqrestore(&r->lock, flags);
-+		}
-+		i = min_t(int, nbytes, EXTRACT_SIZE);
-+		memcpy(buf, tmp, i);
-+		nbytes -= i;
-+		buf += i;
-+		ret += i;
-+	}
-+
-+	/* Wipe data just returned from memory */
-+	memzero_explicit(tmp, sizeof(tmp));
-+
-+	return ret;
-+}
-+
- /*
-  * This function extracts randomness from the "entropy pool", and
-  * returns it in a buffer.
-@@ -1161,7 +1351,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
- static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- 				 size_t nbytes, int min, int reserved)
- {
--	ssize_t ret = 0, i;
- 	__u8 tmp[EXTRACT_SIZE];
- 	unsigned long flags;
- 
-@@ -1185,27 +1374,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- 	xfer_secondary_pool(r, nbytes);
- 	nbytes = account(r, nbytes, min, reserved);
- 
--	while (nbytes) {
--		extract_buf(r, tmp);
--
--		if (fips_enabled) {
--			spin_lock_irqsave(&r->lock, flags);
--			if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
--				panic("Hardware RNG duplicated output!\n");
--			memcpy(r->last_data, tmp, EXTRACT_SIZE);
--			spin_unlock_irqrestore(&r->lock, flags);
--		}
--		i = min_t(int, nbytes, EXTRACT_SIZE);
--		memcpy(buf, tmp, i);
--		nbytes -= i;
--		buf += i;
--		ret += i;
--	}
--
--	/* Wipe data just returned from memory */
--	memzero_explicit(tmp, sizeof(tmp));
--
--	return ret;
-+	return _extract_entropy(r, buf, nbytes, fips_enabled);
- }
- 
- /*
-@@ -1260,15 +1429,26 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
-  */
- void get_random_bytes(void *buf, int nbytes)
- {
-+	__u8 tmp[CHACHA20_BLOCK_SIZE];
-+
- #if DEBUG_RANDOM_BOOT > 0
--	if (unlikely(nonblocking_pool.initialized == 0))
-+	if (!crng_ready())
- 		printk(KERN_NOTICE "random: %pF get_random_bytes called "
--		       "with %d bits of entropy available\n",
--		       (void *) _RET_IP_,
--		       nonblocking_pool.entropy_total);
-+		       "with crng_init = %d\n", (void *) _RET_IP_, crng_init);
- #endif
- 	trace_get_random_bytes(nbytes, _RET_IP_);
--	extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
-+
-+	while (nbytes >= CHACHA20_BLOCK_SIZE) {
-+		extract_crng(buf);
-+		buf += CHACHA20_BLOCK_SIZE;
-+		nbytes -= CHACHA20_BLOCK_SIZE;
-+	}
-+
-+	if (nbytes > 0) {
-+		extract_crng(tmp);
-+		memcpy(buf, tmp, nbytes);
-+		memzero_explicit(tmp, nbytes);
-+	}
- }
- EXPORT_SYMBOL(get_random_bytes);
- 
-@@ -1286,7 +1466,7 @@ int add_random_ready_callback(struct random_ready_callback *rdy)
- 	unsigned long flags;
- 	int err = -EALREADY;
- 
--	if (likely(nonblocking_pool.initialized))
-+	if (crng_ready())
- 		return err;
- 
- 	owner = rdy->owner;
-@@ -1294,7 +1474,7 @@ int add_random_ready_callback(struct random_ready_callback *rdy)
- 		return -ENOENT;
- 
- 	spin_lock_irqsave(&random_ready_list_lock, flags);
--	if (nonblocking_pool.initialized)
-+	if (crng_ready())
- 		goto out;
- 
- 	owner = NULL;
-@@ -1358,7 +1538,7 @@ void get_random_bytes_arch(void *buf, int nbytes)
- 	}
- 
- 	if (nbytes)
--		extract_entropy(&nonblocking_pool, p, nbytes, 0, 0);
-+		get_random_bytes(p, nbytes);
- }
- EXPORT_SYMBOL(get_random_bytes_arch);
- 
-@@ -1403,7 +1583,7 @@ static int rand_initialize(void)
- {
- 	init_std_data(&input_pool);
- 	init_std_data(&blocking_pool);
--	init_std_data(&nonblocking_pool);
-+	crng_initialize(&primary_crng);
- 	return 0;
- }
- early_initcall(rand_initialize);
-@@ -1465,22 +1645,22 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
- static ssize_t
- urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
- {
-+	unsigned long flags;
- 	static int maxwarn = 10;
- 	int ret;
- 
--	if (unlikely(nonblocking_pool.initialized == 0) &&
--	    maxwarn > 0) {
-+	if (!crng_ready() && maxwarn > 0) {
- 		maxwarn--;
- 		printk(KERN_NOTICE "random: %s: uninitialized urandom read "
--		       "(%zd bytes read, %d bits of entropy available)\n",
--		       current->comm, nbytes, nonblocking_pool.entropy_total);
-+		       "(%zd bytes read)\n",
-+		       current->comm, nbytes);
-+		spin_lock_irqsave(&primary_crng.lock, flags);
-+		crng_init_cnt = 0;
-+		spin_unlock_irqrestore(&primary_crng.lock, flags);
- 	}
--
- 	nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
--	ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
--
--	trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool),
--			   ENTROPY_BITS(&input_pool));
-+	ret = extract_crng_user(buf, nbytes);
-+	trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool));
- 	return ret;
- }
- 
-@@ -1534,10 +1714,7 @@ static ssize_t random_write(struct file *file, const char __user *buffer,
- {
- 	size_t ret;
- 
--	ret = write_pool(&blocking_pool, buffer, count);
--	if (ret)
--		return ret;
--	ret = write_pool(&nonblocking_pool, buffer, count);
-+	ret = write_pool(&input_pool, buffer, count);
- 	if (ret)
- 		return ret;
- 
-@@ -1586,7 +1763,6 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
- 		if (!capable(CAP_SYS_ADMIN))
- 			return -EPERM;
- 		input_pool.entropy_count = 0;
--		nonblocking_pool.entropy_count = 0;
- 		blocking_pool.entropy_count = 0;
- 		return 0;
- 	default:
-@@ -1628,11 +1804,10 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
- 	if (flags & GRND_RANDOM)
- 		return _random_read(flags & GRND_NONBLOCK, buf, count);
- 
--	if (unlikely(nonblocking_pool.initialized == 0)) {
-+	if (!crng_ready()) {
- 		if (flags & GRND_NONBLOCK)
- 			return -EAGAIN;
--		wait_event_interruptible(urandom_init_wait,
--					 nonblocking_pool.initialized);
-+		crng_wait_ready();
- 		if (signal_pending(current))
- 			return -ERESTARTSYS;
- 	}
-@@ -1888,18 +2063,17 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
- {
- 	struct entropy_store *poolp = &input_pool;
- 
--	if (unlikely(nonblocking_pool.initialized == 0))
--		poolp = &nonblocking_pool;
--	else {
--		/* Suspend writing if we're above the trickle
--		 * threshold.  We'll be woken up again once below
--		 * random_write_wakeup_thresh, or when the calling
--		 * thread is about to terminate.
--		 */
--		wait_event_interruptible(random_write_wait,
--					 kthread_should_stop() ||
--			ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
-+	if (!crng_ready()) {
-+		crng_fast_load(buffer, count);
-+		return;
- 	}
-+
-+	/* Suspend writing if we're above the trickle threshold.
-+	 * We'll be woken up again once below random_write_wakeup_thresh,
-+	 * or when the calling thread is about to terminate.
-+	 */
-+	wait_event_interruptible(random_write_wait, kthread_should_stop() ||
-+			ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
- 	mix_pool_bytes(poolp, buffer, count);
- 	credit_entropy_bits(poolp, entropy);
- }
-diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h
-index 274bbaeeed0f..20d20f681a72 100644
---- a/include/crypto/chacha20.h
-+++ b/include/crypto/chacha20.h
-@@ -16,6 +16,7 @@ struct chacha20_ctx {
- 	u32 key[8];
- };
- 
-+void chacha20_block(u32 *state, void *stream);
- void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv);
- int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key,
- 			   unsigned int keysize);
-diff --git a/lib/Makefile b/lib/Makefile
-index 34a7460c7005..c9ab674107ef 100644
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -10,7 +10,7 @@ endif
- lib-y := ctype.o string.o vsprintf.o cmdline.o \
- 	 rbtree.o radix-tree.o dump_stack.o timerqueue.o\
- 	 idr.o int_sqrt.o extable.o \
--	 sha1.o md5.o irq_regs.o argv_split.o \
-+	 sha1.o chacha20.o md5.o irq_regs.o argv_split.o \
- 	 proportions.o flex_proportions.o ratelimit.o show_mem.o \
- 	 is_single_threaded.o plist.o decompress.o kobject_uevent.o \
- 	 earlycpio.o seq_buf.o siphash.o nmi_backtrace.o
-diff --git a/lib/chacha20.c b/lib/chacha20.c
-new file mode 100644
-index 000000000000..250ceed9ec9a
---- /dev/null
-+++ b/lib/chacha20.c
-@@ -0,0 +1,79 @@
-+/*
-+ * ChaCha20 256-bit cipher algorithm, RFC7539
-+ *
-+ * Copyright (C) 2015 Martin Willi
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/export.h>
-+#include <linux/bitops.h>
-+#include <linux/cryptohash.h>
-+#include <asm/unaligned.h>
-+#include <crypto/chacha20.h>
-+
-+static inline u32 rotl32(u32 v, u8 n)
-+{
-+	return (v << n) | (v >> (sizeof(v) * 8 - n));
-+}
-+
-+extern void chacha20_block(u32 *state, void *stream)
-+{
-+	u32 x[16], *out = stream;
-+	int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(x); i++)
-+		x[i] = state[i];
-+
-+	for (i = 0; i < 20; i += 2) {
-+		x[0]  += x[4];    x[12] = rotl32(x[12] ^ x[0],  16);
-+		x[1]  += x[5];    x[13] = rotl32(x[13] ^ x[1],  16);
-+		x[2]  += x[6];    x[14] = rotl32(x[14] ^ x[2],  16);
-+		x[3]  += x[7];    x[15] = rotl32(x[15] ^ x[3],  16);
-+
-+		x[8]  += x[12];   x[4]  = rotl32(x[4]  ^ x[8],  12);
-+		x[9]  += x[13];   x[5]  = rotl32(x[5]  ^ x[9],  12);
-+		x[10] += x[14];   x[6]  = rotl32(x[6]  ^ x[10], 12);
-+		x[11] += x[15];   x[7]  = rotl32(x[7]  ^ x[11], 12);
-+
-+		x[0]  += x[4];    x[12] = rotl32(x[12] ^ x[0],   8);
-+		x[1]  += x[5];    x[13] = rotl32(x[13] ^ x[1],   8);
-+		x[2]  += x[6];    x[14] = rotl32(x[14] ^ x[2],   8);
-+		x[3]  += x[7];    x[15] = rotl32(x[15] ^ x[3],   8);
-+
-+		x[8]  += x[12];   x[4]  = rotl32(x[4]  ^ x[8],   7);
-+		x[9]  += x[13];   x[5]  = rotl32(x[5]  ^ x[9],   7);
-+		x[10] += x[14];   x[6]  = rotl32(x[6]  ^ x[10],  7);
-+		x[11] += x[15];   x[7]  = rotl32(x[7]  ^ x[11],  7);
-+
-+		x[0]  += x[5];    x[15] = rotl32(x[15] ^ x[0],  16);
-+		x[1]  += x[6];    x[12] = rotl32(x[12] ^ x[1],  16);
-+		x[2]  += x[7];    x[13] = rotl32(x[13] ^ x[2],  16);
-+		x[3]  += x[4];    x[14] = rotl32(x[14] ^ x[3],  16);
-+
-+		x[10] += x[15];   x[5]  = rotl32(x[5]  ^ x[10], 12);
-+		x[11] += x[12];   x[6]  = rotl32(x[6]  ^ x[11], 12);
-+		x[8]  += x[13];   x[7]  = rotl32(x[7]  ^ x[8],  12);
-+		x[9]  += x[14];   x[4]  = rotl32(x[4]  ^ x[9],  12);
-+
-+		x[0]  += x[5];    x[15] = rotl32(x[15] ^ x[0],   8);
-+		x[1]  += x[6];    x[12] = rotl32(x[12] ^ x[1],   8);
-+		x[2]  += x[7];    x[13] = rotl32(x[13] ^ x[2],   8);
-+		x[3]  += x[4];    x[14] = rotl32(x[14] ^ x[3],   8);
-+
-+		x[10] += x[15];   x[5]  = rotl32(x[5]  ^ x[10],  7);
-+		x[11] += x[12];   x[6]  = rotl32(x[6]  ^ x[11],  7);
-+		x[8]  += x[13];   x[7]  = rotl32(x[7]  ^ x[8],   7);
-+		x[9]  += x[14];   x[4]  = rotl32(x[4]  ^ x[9],   7);
-+	}
-+
-+	for (i = 0; i < ARRAY_SIZE(x); i++)
-+		out[i] = cpu_to_le32(x[i] + state[i]);
-+
-+	state[12]++;
-+}
-+EXPORT_SYMBOL(chacha20_block);
--- 
-2.16.4
-

+ 0 - 143
board/PSG/iot2000/linux-4.4-patches/0020-random-make-dev-urandom-scalable-for-silly-userspace.patch

@@ -1,143 +0,0 @@
-From 90e62ff12f7205a70151ab1f45c437674a4fb81b Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Mon, 2 May 2016 02:04:41 -0400
-Subject: [PATCH 20/32] random: make /dev/urandom scalable for silly userspace
- programs
-
-On a system with a 4 socket (NUMA) system where a large number of
-application threads were all trying to read from /dev/urandom, this
-can result in the system spending 80% of its time contending on the
-global urandom spinlock.  The application should have used its own
-PRNG, but let's try to help it from running, lemming-like, straight
-over the locking cliff.
-
-Reported-by: Andi Kleen <ak@linux.intel.com>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 58 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 6d2abeae9434..79b049e644f3 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -435,6 +435,8 @@ static int crng_init = 0;
- #define crng_ready() (likely(crng_init > 0))
- static int crng_init_cnt = 0;
- #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
-+static void _extract_crng(struct crng_state *crng,
-+			  __u8 out[CHACHA20_BLOCK_SIZE]);
- static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]);
- static void process_random_ready_list(void);
- 
-@@ -758,6 +760,16 @@ static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
- 
- static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
- 
-+#ifdef CONFIG_NUMA
-+/*
-+ * Hack to deal with crazy userspace progams when they are all trying
-+ * to access /dev/urandom in parallel.  The programs are almost
-+ * certainly doing something terribly wrong, but we'll work around
-+ * their brain damage.
-+ */
-+static struct crng_state **crng_node_pool __read_mostly;
-+#endif
-+
- static void crng_initialize(struct crng_state *crng)
- {
- 	int		i;
-@@ -817,7 +829,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 		if (num == 0)
- 			return;
- 	} else
--		extract_crng(buf.block);
-+		_extract_crng(&primary_crng, buf.block);
- 	spin_lock_irqsave(&primary_crng.lock, flags);
- 	for (i = 0; i < 8; i++) {
- 		unsigned long	rv;
-@@ -837,19 +849,26 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 	spin_unlock_irqrestore(&primary_crng.lock, flags);
- }
- 
-+static inline void maybe_reseed_primary_crng(void)
-+{
-+	if (crng_init > 2 &&
-+	    time_after(jiffies, primary_crng.init_time + CRNG_RESEED_INTERVAL))
-+		crng_reseed(&primary_crng, &input_pool);
-+}
-+
- static inline void crng_wait_ready(void)
- {
- 	wait_event_interruptible(crng_init_wait, crng_ready());
- }
- 
--static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
-+static void _extract_crng(struct crng_state *crng,
-+			  __u8 out[CHACHA20_BLOCK_SIZE])
- {
- 	unsigned long v, flags;
--	struct crng_state *crng = &primary_crng;
- 
- 	if (crng_init > 1 &&
- 	    time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
--		crng_reseed(crng, &input_pool);
-+		crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
- 	spin_lock_irqsave(&crng->lock, flags);
- 	if (arch_get_random_long(&v))
- 		crng->state[14] ^= v;
-@@ -859,6 +878,19 @@ static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
- 	spin_unlock_irqrestore(&crng->lock, flags);
- }
- 
-+static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
-+{
-+	struct crng_state *crng = NULL;
-+
-+#ifdef CONFIG_NUMA
-+	if (crng_node_pool)
-+		crng = crng_node_pool[numa_node_id()];
-+	if (crng == NULL)
-+#endif
-+		crng = &primary_crng;
-+	_extract_crng(crng, out);
-+}
-+
- static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
- {
- 	ssize_t ret = 0, i;
-@@ -1581,9 +1613,31 @@ static void init_std_data(struct entropy_store *r)
-  */
- static int rand_initialize(void)
- {
-+#ifdef CONFIG_NUMA
-+	int i;
-+	int num_nodes = num_possible_nodes();
-+	struct crng_state *crng;
-+	struct crng_state **pool;
-+#endif
-+
- 	init_std_data(&input_pool);
- 	init_std_data(&blocking_pool);
- 	crng_initialize(&primary_crng);
-+
-+#ifdef CONFIG_NUMA
-+	pool = kmalloc(num_nodes * sizeof(void *),
-+		       GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO);
-+	for (i=0; i < num_nodes; i++) {
-+		crng = kmalloc_node(sizeof(struct crng_state),
-+				    GFP_KERNEL | __GFP_NOFAIL, i);
-+		spin_lock_init(&crng->lock);
-+		crng_initialize(crng);
-+		pool[i] = crng;
-+
-+	}
-+	mb();
-+	crng_node_pool = pool;
-+#endif
- 	return 0;
- }
- early_initcall(rand_initialize);
--- 
-2.16.4
-

+ 0 - 109
board/PSG/iot2000/linux-4.4-patches/0021-random-add-backtracking-protection-to-the-CRNG.patch

@@ -1,109 +0,0 @@
-From a6d1adf3fed33218b5059d41128ab2b8b429d08c Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Wed, 4 May 2016 13:29:18 -0400
-Subject: [PATCH 21/32] random: add backtracking protection to the CRNG
-
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 49 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 79b049e644f3..a1214c0fbaf3 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -437,7 +437,8 @@ static int crng_init_cnt = 0;
- #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
- static void _extract_crng(struct crng_state *crng,
- 			  __u8 out[CHACHA20_BLOCK_SIZE]);
--static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE]);
-+static void _crng_backtrack_protect(struct crng_state *crng,
-+				    __u8 tmp[CHACHA20_BLOCK_SIZE], int used);
- static void process_random_ready_list(void);
- 
- /**********************************************************************
-@@ -828,8 +829,11 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 		num = extract_entropy(r, &buf, 32, 16, 0);
- 		if (num == 0)
- 			return;
--	} else
-+	} else {
- 		_extract_crng(&primary_crng, buf.block);
-+		_crng_backtrack_protect(&primary_crng, buf.block,
-+					CHACHA20_KEY_SIZE);
-+	}
- 	spin_lock_irqsave(&primary_crng.lock, flags);
- 	for (i = 0; i < 8; i++) {
- 		unsigned long	rv;
-@@ -891,9 +895,46 @@ static void extract_crng(__u8 out[CHACHA20_BLOCK_SIZE])
- 	_extract_crng(crng, out);
- }
- 
-+/*
-+ * Use the leftover bytes from the CRNG block output (if there is
-+ * enough) to mutate the CRNG key to provide backtracking protection.
-+ */
-+static void _crng_backtrack_protect(struct crng_state *crng,
-+				    __u8 tmp[CHACHA20_BLOCK_SIZE], int used)
-+{
-+	unsigned long	flags;
-+	__u32		*s, *d;
-+	int		i;
-+
-+	used = round_up(used, sizeof(__u32));
-+	if (used + CHACHA20_KEY_SIZE > CHACHA20_BLOCK_SIZE) {
-+		extract_crng(tmp);
-+		used = 0;
-+	}
-+	spin_lock_irqsave(&crng->lock, flags);
-+	s = (__u32 *) &tmp[used];
-+	d = &crng->state[4];
-+	for (i=0; i < 8; i++)
-+		*d++ ^= *s++;
-+	spin_unlock_irqrestore(&crng->lock, flags);
-+}
-+
-+static void crng_backtrack_protect(__u8 tmp[CHACHA20_BLOCK_SIZE], int used)
-+{
-+	struct crng_state *crng = NULL;
-+
-+#ifdef CONFIG_NUMA
-+	if (crng_node_pool)
-+		crng = crng_node_pool[numa_node_id()];
-+	if (crng == NULL)
-+#endif
-+		crng = &primary_crng;
-+	_crng_backtrack_protect(crng, tmp, used);
-+}
-+
- static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
- {
--	ssize_t ret = 0, i;
-+	ssize_t ret = 0, i = CHACHA20_BLOCK_SIZE;
- 	__u8 tmp[CHACHA20_BLOCK_SIZE];
- 	int large_request = (nbytes > 256);
- 
-@@ -918,6 +959,7 @@ static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
- 		buf += i;
- 		ret += i;
- 	}
-+	crng_backtrack_protect(tmp, i);
- 
- 	/* Wipe data just written to memory */
- 	memzero_explicit(tmp, sizeof(tmp));
-@@ -1479,8 +1521,10 @@ void get_random_bytes(void *buf, int nbytes)
- 	if (nbytes > 0) {
- 		extract_crng(tmp);
- 		memcpy(buf, tmp, nbytes);
--		memzero_explicit(tmp, nbytes);
--	}
-+		crng_backtrack_protect(tmp, nbytes);
-+	} else
-+		crng_backtrack_protect(tmp, CHACHA20_BLOCK_SIZE);
-+	memzero_explicit(tmp, sizeof(tmp));
- }
- EXPORT_SYMBOL(get_random_bytes);
- 
--- 
-2.16.4
-

+ 0 - 35
board/PSG/iot2000/linux-4.4-patches/0022-random-remove-stale-maybe_reseed_primary_crng.patch

@@ -1,35 +0,0 @@
-From 1eadc614c3546b2cef698c337c95034253c99771 Mon Sep 17 00:00:00 2001
-From: Stephan Mueller <stephan.mueller@atsec.com>
-Date: Thu, 15 Dec 2016 12:42:33 +0100
-Subject: [PATCH 22/32] random: remove stale maybe_reseed_primary_crng
-
-The function maybe_reseed_primary_crng is not used anywhere and thus can
-be removed.
-
-Signed-off-by: Stephan Mueller <smueller@chronox.de>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c | 7 -------
- 1 file changed, 7 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index a1214c0fbaf3..a6a6a357ddae 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -853,13 +853,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 	spin_unlock_irqrestore(&primary_crng.lock, flags);
- }
- 
--static inline void maybe_reseed_primary_crng(void)
--{
--	if (crng_init > 2 &&
--	    time_after(jiffies, primary_crng.init_time + CRNG_RESEED_INTERVAL))
--		crng_reseed(&primary_crng, &input_pool);
--}
--
- static inline void crng_wait_ready(void)
- {
- 	wait_event_interruptible(crng_init_wait, crng_ready());
--- 
-2.16.4
-

+ 0 - 180
board/PSG/iot2000/linux-4.4-patches/0023-random-use-chacha20-for-get_random_int-long.patch

@@ -1,180 +0,0 @@
-From b2a4ee8c97a7102789f81e428ce13d14a2ac1954 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Fri, 6 Jan 2017 19:32:01 +0100
-Subject: [PATCH 23/32] random: use chacha20 for get_random_int/long
-
-Now that our crng uses chacha20, we can rely on its speedy
-characteristics for replacing MD5, while simultaneously achieving a
-higher security guarantee. Before the idea was to use these functions if
-you wanted random integers that aren't stupidly insecure but aren't
-necessarily secure either, a vague gray zone, that hopefully was "good
-enough" for its users. With chacha20, we can strengthen this claim,
-since either we're using an rdrand-like instruction, or we're using the
-same crng as /dev/urandom. And it's faster than what was before.
-
-We could have chosen to replace this with a SipHash-derived function,
-which might be slightly faster, but at the cost of having yet another
-RNG construction in the kernel. By moving to chacha20, we have a single
-RNG to analyze and verify, and we also already get good performance
-improvements on all platforms.
-
-Implementation-wise, rather than use a generic buffer for both
-get_random_int/long and memcpy based on the size needs, we use a
-specific buffer for 32-bit reads and for 64-bit reads. This way, we're
-guaranteed to always have aligned accesses on all platforms. While
-slightly more verbose in C, the assembly this generates is a lot
-simpler than otherwise.
-
-Finally, on 32-bit platforms where longs and ints are the same size,
-we simply alias get_random_int to get_random_long.
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Suggested-by: Theodore Ts'o <tytso@mit.edu>
-Cc: Theodore Ts'o <tytso@mit.edu>
-Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
-Cc: Andy Lutomirski <luto@amacapital.net>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c  | 84 ++++++++++++++++++++++++++------------------------
- include/linux/random.h |  1 -
- init/main.c            |  1 -
- 3 files changed, 43 insertions(+), 43 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index a6a6a357ddae..a10ff9c50cea 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -2068,63 +2068,65 @@ struct ctl_table random_table[] = {
- };
- #endif 	/* CONFIG_SYSCTL */
- 
--static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
--
--int random_int_secret_init(void)
--{
--	get_random_bytes(random_int_secret, sizeof(random_int_secret));
--	return 0;
--}
--
--static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash)
--		__aligned(sizeof(unsigned long));
-+struct batched_entropy {
-+	union {
-+		unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)];
-+		unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)];
-+	};
-+	unsigned int position;
-+};
- 
- /*
-- * Get a random word for internal kernel use only. Similar to urandom but
-- * with the goal of minimal entropy pool depletion. As a result, the random
-- * value is not cryptographically secure but for several uses the cost of
-- * depleting entropy is too high
-+ * Get a random word for internal kernel use only. The quality of the random
-+ * number is either as good as RDRAND or as good as /dev/urandom, with the
-+ * goal of being quite fast and not depleting entropy.
-  */
--unsigned int get_random_int(void)
-+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long);
-+unsigned long get_random_long(void)
- {
--	__u32 *hash;
--	unsigned int ret;
-+	unsigned long ret;
-+	struct batched_entropy *batch;
- 
--	if (arch_get_random_int(&ret))
-+	if (arch_get_random_long(&ret))
- 		return ret;
- 
--	hash = get_cpu_var(get_random_int_hash);
--
--	hash[0] += current->pid + jiffies + random_get_entropy();
--	md5_transform(hash, random_int_secret);
--	ret = hash[0];
--	put_cpu_var(get_random_int_hash);
--
-+	batch = &get_cpu_var(batched_entropy_long);
-+	if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) {
-+		extract_crng((u8 *)batch->entropy_long);
-+		batch->position = 0;
-+	}
-+	ret = batch->entropy_long[batch->position++];
-+	put_cpu_var(batched_entropy_long);
- 	return ret;
- }
--EXPORT_SYMBOL(get_random_int);
-+EXPORT_SYMBOL(get_random_long);
- 
--/*
-- * Same as get_random_int(), but returns unsigned long.
-- */
--unsigned long get_random_long(void)
-+#if BITS_PER_LONG == 32
-+unsigned int get_random_int(void)
- {
--	__u32 *hash;
--	unsigned long ret;
-+	return get_random_long();
-+}
-+#else
-+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int);
-+unsigned int get_random_int(void)
-+{
-+	unsigned int ret;
-+	struct batched_entropy *batch;
- 
--	if (arch_get_random_long(&ret))
-+	if (arch_get_random_int(&ret))
- 		return ret;
- 
--	hash = get_cpu_var(get_random_int_hash);
--
--	hash[0] += current->pid + jiffies + random_get_entropy();
--	md5_transform(hash, random_int_secret);
--	ret = *(unsigned long *)hash;
--	put_cpu_var(get_random_int_hash);
--
-+	batch = &get_cpu_var(batched_entropy_int);
-+	if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) {
-+		extract_crng((u8 *)batch->entropy_int);
-+		batch->position = 0;
-+	}
-+	ret = batch->entropy_int[batch->position++];
-+	put_cpu_var(batched_entropy_int);
- 	return ret;
- }
--EXPORT_SYMBOL(get_random_long);
-+#endif
-+EXPORT_SYMBOL(get_random_int);
- 
- /*
-  * randomize_range() returns a start address such that
-diff --git a/include/linux/random.h b/include/linux/random.h
-index 9c29122037f9..3e874bcdf8b8 100644
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -27,7 +27,6 @@ extern int add_random_ready_callback(struct random_ready_callback *rdy);
- extern void del_random_ready_callback(struct random_ready_callback *rdy);
- extern void get_random_bytes_arch(void *buf, int nbytes);
- void generate_random_uuid(unsigned char uuid_out[16]);
--extern int random_int_secret_init(void);
- 
- #ifndef MODULE
- extern const struct file_operations random_fops, urandom_fops;
-diff --git a/init/main.c b/init/main.c
-index e88c8cdef6a7..406cddf01de8 100644
---- a/init/main.c
-+++ b/init/main.c
-@@ -885,7 +885,6 @@ static void __init do_basic_setup(void)
- 	do_ctors();
- 	usermodehelper_enable();
- 	do_initcalls();
--	random_int_secret_init();
- }
- 
- static void __init do_pre_smp_initcalls(void)
--- 
-2.16.4
-

+ 0 - 147
board/PSG/iot2000/linux-4.4-patches/0024-random-convert-get_random_int-long-into-get_random_u.patch

@@ -1,147 +0,0 @@
-From 74f881a90ad219b51f59cc3ea700b3dd9decc2a3 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Sun, 22 Jan 2017 16:34:08 +0100
-Subject: [PATCH 24/32] random: convert get_random_int/long into
- get_random_u32/u64
-
-Many times, when a user wants a random number, he wants a random number
-of a guaranteed size. So, thinking of get_random_int and get_random_long
-in terms of get_random_u32 and get_random_u64 makes it much easier to
-achieve this. It also makes the code simpler.
-
-On 32-bit platforms, get_random_int and get_random_long are both aliased
-to get_random_u32. On 64-bit platforms, int->u32 and long->u64.
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c  | 55 +++++++++++++++++++++++++-------------------------
- include/linux/random.h | 17 ++++++++++++++--
- 2 files changed, 42 insertions(+), 30 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index a10ff9c50cea..d79a631a2b5e 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -2070,8 +2070,8 @@ struct ctl_table random_table[] = {
- 
- struct batched_entropy {
- 	union {
--		unsigned long entropy_long[CHACHA20_BLOCK_SIZE / sizeof(unsigned long)];
--		unsigned int entropy_int[CHACHA20_BLOCK_SIZE / sizeof(unsigned int)];
-+		u64 entropy_u64[CHACHA20_BLOCK_SIZE / sizeof(u64)];
-+		u32 entropy_u32[CHACHA20_BLOCK_SIZE / sizeof(u32)];
- 	};
- 	unsigned int position;
- };
-@@ -2081,52 +2081,51 @@ struct batched_entropy {
-  * number is either as good as RDRAND or as good as /dev/urandom, with the
-  * goal of being quite fast and not depleting entropy.
-  */
--static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_long);
--unsigned long get_random_long(void)
-+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
-+u64 get_random_u64(void)
- {
--	unsigned long ret;
-+	u64 ret;
- 	struct batched_entropy *batch;
- 
--	if (arch_get_random_long(&ret))
-+#if BITS_PER_LONG == 64
-+	if (arch_get_random_long((unsigned long *)&ret))
- 		return ret;
-+#else
-+	if (arch_get_random_long((unsigned long *)&ret) &&
-+	    arch_get_random_long((unsigned long *)&ret + 1))
-+	    return ret;
-+#endif
- 
--	batch = &get_cpu_var(batched_entropy_long);
--	if (batch->position % ARRAY_SIZE(batch->entropy_long) == 0) {
--		extract_crng((u8 *)batch->entropy_long);
-+	batch = &get_cpu_var(batched_entropy_u64);
-+	if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
-+		extract_crng((u8 *)batch->entropy_u64);
- 		batch->position = 0;
- 	}
--	ret = batch->entropy_long[batch->position++];
--	put_cpu_var(batched_entropy_long);
-+	ret = batch->entropy_u64[batch->position++];
-+	put_cpu_var(batched_entropy_u64);
- 	return ret;
- }
--EXPORT_SYMBOL(get_random_long);
-+EXPORT_SYMBOL(get_random_u64);
- 
--#if BITS_PER_LONG == 32
--unsigned int get_random_int(void)
--{
--	return get_random_long();
--}
--#else
--static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_int);
--unsigned int get_random_int(void)
-+static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
-+u32 get_random_u32(void)
- {
--	unsigned int ret;
-+	u32 ret;
- 	struct batched_entropy *batch;
- 
- 	if (arch_get_random_int(&ret))
- 		return ret;
- 
--	batch = &get_cpu_var(batched_entropy_int);
--	if (batch->position % ARRAY_SIZE(batch->entropy_int) == 0) {
--		extract_crng((u8 *)batch->entropy_int);
-+	batch = &get_cpu_var(batched_entropy_u32);
-+	if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
-+		extract_crng((u8 *)batch->entropy_u32);
- 		batch->position = 0;
- 	}
--	ret = batch->entropy_int[batch->position++];
--	put_cpu_var(batched_entropy_int);
-+	ret = batch->entropy_u32[batch->position++];
-+	put_cpu_var(batched_entropy_u32);
- 	return ret;
- }
--#endif
--EXPORT_SYMBOL(get_random_int);
-+EXPORT_SYMBOL(get_random_u32);
- 
- /*
-  * randomize_range() returns a start address such that
-diff --git a/include/linux/random.h b/include/linux/random.h
-index 3e874bcdf8b8..39f125ba80bb 100644
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -32,8 +32,21 @@ void generate_random_uuid(unsigned char uuid_out[16]);
- extern const struct file_operations random_fops, urandom_fops;
- #endif
- 
--unsigned int get_random_int(void);
--unsigned long get_random_long(void);
-+u32 get_random_u32(void);
-+u64 get_random_u64(void);
-+static inline unsigned int get_random_int(void)
-+{
-+	return get_random_u32();
-+}
-+static inline unsigned long get_random_long(void)
-+{
-+#if BITS_PER_LONG == 64
-+	return get_random_u64();
-+#else
-+	return get_random_u32();
-+#endif
-+}
-+
- unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
- 
- u32 prandom_u32(void);
--- 
-2.16.4
-

+ 0 - 148
board/PSG/iot2000/linux-4.4-patches/0025-random-invalidate-batched-entropy-after-crng-init.patch

@@ -1,148 +0,0 @@
-From a4829bebf0be947a5ec2880b15ec77d5178d6a17 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Wed, 7 Jun 2017 19:45:31 -0400
-Subject: [PATCH 25/32] random: invalidate batched entropy after crng init
-
-It's possible that get_random_{u32,u64} is used before the crng has
-initialized, in which case, its output might not be cryptographically
-secure. For this problem, directly, this patch set is introducing the
-*_wait variety of functions, but even with that, there's a subtle issue:
-what happens to our batched entropy that was generated before
-initialization. Prior to this commit, it'd stick around, supplying bad
-numbers. After this commit, we force the entropy to be re-extracted
-after each phase of the crng has initialized.
-
-In order to avoid a race condition with the position counter, we
-introduce a simple rwlock for this invalidation. Since it's only during
-this awkward transition period, after things are all set up, we stop
-using it, so that it doesn't have an impact on performance.
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Cc: stable@vger.kernel.org  # v4.11+
----
- drivers/char/random.c | 37 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index d79a631a2b5e..6c571ee0d6c4 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -1,6 +1,9 @@
- /*
-  * random.c -- A strong random number generator
-  *
-+ * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All
-+ * Rights Reserved.
-+ *
-  * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
-  *
-  * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
-@@ -771,6 +774,8 @@ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
- static struct crng_state **crng_node_pool __read_mostly;
- #endif
- 
-+static void invalidate_batched_entropy(void);
-+
- static void crng_initialize(struct crng_state *crng)
- {
- 	int		i;
-@@ -808,6 +813,7 @@ static int crng_fast_load(const char *cp, size_t len)
- 		cp++; crng_init_cnt++; len--;
- 	}
- 	if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
-+		invalidate_batched_entropy();
- 		crng_init = 1;
- 		wake_up_interruptible(&crng_init_wait);
- 		pr_notice("random: fast init done\n");
-@@ -845,6 +851,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 	memzero_explicit(&buf, sizeof(buf));
- 	crng->init_time = jiffies;
- 	if (crng == &primary_crng && crng_init < 2) {
-+		invalidate_batched_entropy();
- 		crng_init = 2;
- 		process_random_ready_list();
- 		wake_up_interruptible(&crng_init_wait);
-@@ -2075,6 +2082,7 @@ struct batched_entropy {
- 	};
- 	unsigned int position;
- };
-+static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_reset_lock);
- 
- /*
-  * Get a random word for internal kernel use only. The quality of the random
-@@ -2085,6 +2093,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
- u64 get_random_u64(void)
- {
- 	u64 ret;
-+	bool use_lock = crng_init < 2;
-+	unsigned long flags;
- 	struct batched_entropy *batch;
- 
- #if BITS_PER_LONG == 64
-@@ -2097,11 +2107,15 @@ u64 get_random_u64(void)
- #endif
- 
- 	batch = &get_cpu_var(batched_entropy_u64);
-+	if (use_lock)
-+		read_lock_irqsave(&batched_entropy_reset_lock, flags);
- 	if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) {
- 		extract_crng((u8 *)batch->entropy_u64);
- 		batch->position = 0;
- 	}
- 	ret = batch->entropy_u64[batch->position++];
-+	if (use_lock)
-+		read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
- 	put_cpu_var(batched_entropy_u64);
- 	return ret;
- }
-@@ -2111,22 +2125,45 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
- u32 get_random_u32(void)
- {
- 	u32 ret;
-+	bool use_lock = crng_init < 2;
-+	unsigned long flags;
- 	struct batched_entropy *batch;
- 
- 	if (arch_get_random_int(&ret))
- 		return ret;
- 
- 	batch = &get_cpu_var(batched_entropy_u32);
-+	if (use_lock)
-+		read_lock_irqsave(&batched_entropy_reset_lock, flags);
- 	if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) {
- 		extract_crng((u8 *)batch->entropy_u32);
- 		batch->position = 0;
- 	}
- 	ret = batch->entropy_u32[batch->position++];
-+	if (use_lock)
-+		read_unlock_irqrestore(&batched_entropy_reset_lock, flags);
- 	put_cpu_var(batched_entropy_u32);
- 	return ret;
- }
- EXPORT_SYMBOL(get_random_u32);
- 
-+/* It's important to invalidate all potential batched entropy that might
-+ * be stored before the crng is initialized, which we can do lazily by
-+ * simply resetting the counter to zero so that it's re-extracted on the
-+ * next usage. */
-+static void invalidate_batched_entropy(void)
-+{
-+	int cpu;
-+	unsigned long flags;
-+
-+	write_lock_irqsave(&batched_entropy_reset_lock, flags);
-+	for_each_possible_cpu (cpu) {
-+		per_cpu_ptr(&batched_entropy_u32, cpu)->position = 0;
-+		per_cpu_ptr(&batched_entropy_u64, cpu)->position = 0;
-+	}
-+	write_unlock_irqrestore(&batched_entropy_reset_lock, flags);
-+}
-+
- /*
-  * randomize_range() returns a start address such that
-  *
--- 
-2.16.4
-

+ 0 - 87
board/PSG/iot2000/linux-4.4-patches/0026-random-silence-compiler-warnings-and-fix-race.patch

@@ -1,87 +0,0 @@
-From 45cf6623ee8462c12e9a971620ea01fdae7b0114 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Thu, 15 Jun 2017 00:45:26 +0200
-Subject: [PATCH 26/32] random: silence compiler warnings and fix race
-
-Odd versions of gcc for the sh4 architecture will actually warn about
-flags being used while uninitialized, so we set them to zero. Non crazy
-gccs will optimize that out again, so it doesn't make a difference.
-
-Next, over aggressive gccs could inline the expression that defines
-use_lock, which could then introduce a race resulting in a lock
-imbalance. By using READ_ONCE, we prevent that fate. Finally, we make
-that assignment const, so that gcc can still optimize a nice amount.
-
-Finally, we fix a potential deadlock between primary_crng.lock and
-batched_entropy_reset_lock, where they could be called in opposite
-order. Moving the call to invalidate_batched_entropy to outside the lock
-rectifies this issue.
-
-Fixes: b169c13de473a85b3c859bb36216a4cb5f00a54a
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Cc: stable@vger.kernel.org
----
- drivers/char/random.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 6c571ee0d6c4..194cdb02d458 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -812,13 +812,13 @@ static int crng_fast_load(const char *cp, size_t len)
- 		p[crng_init_cnt % CHACHA20_KEY_SIZE] ^= *cp;
- 		cp++; crng_init_cnt++; len--;
- 	}
-+	spin_unlock_irqrestore(&primary_crng.lock, flags);
- 	if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) {
- 		invalidate_batched_entropy();
- 		crng_init = 1;
- 		wake_up_interruptible(&crng_init_wait);
- 		pr_notice("random: fast init done\n");
- 	}
--	spin_unlock_irqrestore(&primary_crng.lock, flags);
- 	return 1;
- }
- 
-@@ -850,6 +850,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 	}
- 	memzero_explicit(&buf, sizeof(buf));
- 	crng->init_time = jiffies;
-+	spin_unlock_irqrestore(&primary_crng.lock, flags);
- 	if (crng == &primary_crng && crng_init < 2) {
- 		invalidate_batched_entropy();
- 		crng_init = 2;
-@@ -857,7 +858,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 		wake_up_interruptible(&crng_init_wait);
- 		pr_notice("random: crng init done\n");
- 	}
--	spin_unlock_irqrestore(&primary_crng.lock, flags);
- }
- 
- static inline void crng_wait_ready(void)
-@@ -2093,8 +2093,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
- u64 get_random_u64(void)
- {
- 	u64 ret;
--	bool use_lock = crng_init < 2;
--	unsigned long flags;
-+	bool use_lock = READ_ONCE(crng_init) < 2;
-+	unsigned long flags = 0;
- 	struct batched_entropy *batch;
- 
- #if BITS_PER_LONG == 64
-@@ -2125,8 +2125,8 @@ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32);
- u32 get_random_u32(void)
- {
- 	u32 ret;
--	bool use_lock = crng_init < 2;
--	unsigned long flags;
-+	bool use_lock = READ_ONCE(crng_init) < 2;
-+	unsigned long flags = 0;
- 	struct batched_entropy *batch;
- 
- 	if (arch_get_random_int(&ret))
--- 
-2.16.4
-

+ 0 - 118
board/PSG/iot2000/linux-4.4-patches/0027-random-add-wait_for_random_bytes-API.patch

@@ -1,118 +0,0 @@
-From bab97a70fbb2f35de923e07d1e2377ad43b024af Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Wed, 7 Jun 2017 19:58:56 -0400
-Subject: [PATCH 27/32] random: add wait_for_random_bytes() API
-
-This enables users of get_random_{bytes,u32,u64,int,long} to wait until
-the pool is ready before using this function, in case they actually want
-to have reliable randomness.
-
-Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c  | 41 +++++++++++++++++++++++++++++++----------
- include/linux/random.h |  1 +
- 2 files changed, 32 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 194cdb02d458..198ae9df9d9e 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -860,11 +860,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- 	}
- }
- 
--static inline void crng_wait_ready(void)
--{
--	wait_event_interruptible(crng_init_wait, crng_ready());
--}
--
- static void _extract_crng(struct crng_state *crng,
- 			  __u8 out[CHACHA20_BLOCK_SIZE])
- {
-@@ -1499,7 +1494,10 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
-  * number of good random numbers, suitable for key generation, seeding
-  * TCP sequence numbers, etc.  It does not rely on the hardware random
-  * number generator.  For random bytes direct from the hardware RNG
-- * (when available), use get_random_bytes_arch().
-+ * (when available), use get_random_bytes_arch(). In order to ensure
-+ * that the randomness provided by this function is okay, the function
-+ * wait_for_random_bytes() should be called and return 0 at least once
-+ * at any point prior.
-  */
- void get_random_bytes(void *buf, int nbytes)
- {
-@@ -1528,6 +1526,24 @@ void get_random_bytes(void *buf, int nbytes)
- }
- EXPORT_SYMBOL(get_random_bytes);
- 
-+/*
-+ * Wait for the urandom pool to be seeded and thus guaranteed to supply
-+ * cryptographically secure random numbers. This applies to: the /dev/urandom
-+ * device, the get_random_bytes function, and the get_random_{u32,u64,int,long}
-+ * family of functions. Using any of these functions without first calling
-+ * this function forfeits the guarantee of security.
-+ *
-+ * Returns: 0 if the urandom pool has been seeded.
-+ *          -ERESTARTSYS if the function was interrupted by a signal.
-+ */
-+int wait_for_random_bytes(void)
-+{
-+	if (likely(crng_ready()))
-+		return 0;
-+	return wait_event_interruptible(crng_init_wait, crng_ready());
-+}
-+EXPORT_SYMBOL(wait_for_random_bytes);
-+
- /*
-  * Add a callback function that will be invoked when the nonblocking
-  * pool is initialised.
-@@ -1893,6 +1909,8 @@ const struct file_operations urandom_fops = {
- SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
- 		unsigned int, flags)
- {
-+	int ret;
-+
- 	if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
- 		return -EINVAL;
- 
-@@ -1905,9 +1923,9 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
- 	if (!crng_ready()) {
- 		if (flags & GRND_NONBLOCK)
- 			return -EAGAIN;
--		crng_wait_ready();
--		if (signal_pending(current))
--			return -ERESTARTSYS;
-+		ret = wait_for_random_bytes();
-+		if (unlikely(ret))
-+			return ret;
- 	}
- 	return urandom_read(NULL, buf, count, NULL);
- }
-@@ -2087,7 +2105,10 @@ static rwlock_t batched_entropy_reset_lock = __RW_LOCK_UNLOCKED(batched_entropy_
- /*
-  * Get a random word for internal kernel use only. The quality of the random
-  * number is either as good as RDRAND or as good as /dev/urandom, with the
-- * goal of being quite fast and not depleting entropy.
-+ * goal of being quite fast and not depleting entropy. In order to ensure
-+ * that the randomness provided by this function is okay, the function
-+ * wait_for_random_bytes() should be called and return 0 at least once
-+ * at any point prior.
-  */
- static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64);
- u64 get_random_u64(void)
-diff --git a/include/linux/random.h b/include/linux/random.h
-index 39f125ba80bb..b282d7adcacc 100644
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -23,6 +23,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
- extern void add_interrupt_randomness(int irq, int irq_flags);
- 
- extern void get_random_bytes(void *buf, int nbytes);
-+extern int wait_for_random_bytes(void);
- extern int add_random_ready_callback(struct random_ready_callback *rdy);
- extern void del_random_ready_callback(struct random_ready_callback *rdy);
- extern void get_random_bytes_arch(void *buf, int nbytes);
--- 
-2.16.4
-

+ 0 - 77
board/PSG/iot2000/linux-4.4-patches/0028-random-fix-crng_ready-test.patch

@@ -1,77 +0,0 @@
-From 24cef0dbc155391db6e2eceba26cba476e54dd15 Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Wed, 11 Apr 2018 13:27:52 -0400
-Subject: [PATCH 28/32] random: fix crng_ready() test
-
-The crng_init variable has three states:
-
-0: The CRNG is not initialized at all
-1: The CRNG has a small amount of entropy, hopefully good enough for
-   early-boot, non-cryptographical use cases
-2: The CRNG is fully initialized and we are sure it is safe for
-   cryptographic use cases.
-
-The crng_ready() function should only return true once we are in the
-last state.  This addresses CVE-2018-1108.
-
-Reported-by: Jann Horn <jannh@google.com>
-Fixes: e192be9d9a30 ("random: replace non-blocking pool...")
-Cc: stable@kernel.org # 4.8+
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Reviewed-by: Jann Horn <jannh@google.com>
----
- drivers/char/random.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 198ae9df9d9e..747b7d6d4f44 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -435,7 +435,7 @@ struct crng_state primary_crng = {
-  * its value (from 0->1->2).
-  */
- static int crng_init = 0;
--#define crng_ready() (likely(crng_init > 0))
-+#define crng_ready() (likely(crng_init > 1))
- static int crng_init_cnt = 0;
- #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
- static void _extract_crng(struct crng_state *crng,
-@@ -803,7 +803,7 @@ static int crng_fast_load(const char *cp, size_t len)
- 
- 	if (!spin_trylock_irqsave(&primary_crng.lock, flags))
- 		return 0;
--	if (crng_ready()) {
-+	if (crng_init != 0) {
- 		spin_unlock_irqrestore(&primary_crng.lock, flags);
- 		return 0;
- 	}
-@@ -865,7 +865,7 @@ static void _extract_crng(struct crng_state *crng,
- {
- 	unsigned long v, flags;
- 
--	if (crng_init > 1 &&
-+	if (crng_ready() &&
- 	    time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
- 		crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
- 	spin_lock_irqsave(&crng->lock, flags);
-@@ -1146,7 +1146,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
- 	fast_mix(fast_pool);
- 	add_interrupt_bench(cycles);
- 
--	if (!crng_ready()) {
-+	if (unlikely(crng_init == 0)) {
- 		if ((fast_pool->count >= 64) &&
- 		    crng_fast_load((char *) fast_pool->pool,
- 				   sizeof(fast_pool->pool))) {
-@@ -2213,7 +2213,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
- {
- 	struct entropy_store *poolp = &input_pool;
- 
--	if (!crng_ready()) {
-+	if (unlikely(crng_init == 0)) {
- 		crng_fast_load(buffer, count);
- 		return;
- 	}
--- 
-2.16.4
-

+ 0 - 110
board/PSG/iot2000/linux-4.4-patches/0029-random-use-a-different-mixing-algorithm-for-add_devi.patch

@@ -1,110 +0,0 @@
-From 0e756274490a989fc8a368d0072b20019a5bd53d Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Wed, 11 Apr 2018 14:58:27 -0400
-Subject: [PATCH 29/32] random: use a different mixing algorithm for
- add_device_randomness()
-
-add_device_randomness() use of crng_fast_load() was highly
-problematic.  Some callers of add_device_randomness() can pass in a
-large amount of static information.  This would immediately promote
-the crng_init state from 0 to 1, without really doing much to
-initialize the primary_crng's internal state with something even
-vaguely unpredictable.
-
-Since we don't have the speed constraints of add_interrupt_randomness(),
-we can do a better job mixing in the what unpredictability a device
-driver or architecture maintainer might see fit to give us, and do it
-in a way which does not bump the crng_init_cnt variable.
-
-Also, since add_device_randomness() doesn't bump any entropy
-accounting in crng_init state 0, mix the device randomness into the
-input_pool entropy pool as well.  This is related to CVE-2018-1108.
-
-Reported-by: Jann Horn <jannh@google.com>
-Fixes: ee7998c50c26 ("random: do not ignore early device randomness")
-Cc: stable@kernel.org # 4.13+
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 52 insertions(+)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 747b7d6d4f44..ca9127abad52 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -796,6 +796,10 @@ static void crng_initialize(struct crng_state *crng)
- 	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
- }
- 
-+/*
-+ * crng_fast_load() can be called by code in the interrupt service
-+ * path.  So we can't afford to dilly-dally.
-+ */
- static int crng_fast_load(const char *cp, size_t len)
- {
- 	unsigned long flags;
-@@ -822,6 +826,51 @@ static int crng_fast_load(const char *cp, size_t len)
- 	return 1;
- }
- 
-+/*
-+ * crng_slow_load() is called by add_device_randomness, which has two
-+ * attributes.  (1) We can't trust the buffer passed to it is
-+ * guaranteed to be unpredictable (so it might not have any entropy at
-+ * all), and (2) it doesn't have the performance constraints of
-+ * crng_fast_load().
-+ *
-+ * So we do something more comprehensive which is guaranteed to touch
-+ * all of the primary_crng's state, and which uses a LFSR with a
-+ * period of 255 as part of the mixing algorithm.  Finally, we do
-+ * *not* advance crng_init_cnt since buffer we may get may be something
-+ * like a fixed DMI table (for example), which might very well be
-+ * unique to the machine, but is otherwise unvarying.
-+ */
-+static int crng_slow_load(const char *cp, size_t len)
-+{
-+	unsigned long		flags;
-+	static unsigned char	lfsr = 1;
-+	unsigned char		tmp;
-+	unsigned		i, max = CHACHA20_KEY_SIZE;
-+	const char *		src_buf = cp;
-+	char *			dest_buf = (char *) &primary_crng.state[4];
-+
-+	if (!spin_trylock_irqsave(&primary_crng.lock, flags))
-+		return 0;
-+	if (crng_init != 0) {
-+		spin_unlock_irqrestore(&primary_crng.lock, flags);
-+		return 0;
-+	}
-+	if (len > max)
-+		max = len;
-+
-+	for (i = 0; i < max ; i++) {
-+		tmp = lfsr;
-+		lfsr >>= 1;
-+		if (tmp & 1)
-+			lfsr ^= 0xE1;
-+		tmp = dest_buf[i % CHACHA20_KEY_SIZE];
-+		dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
-+		lfsr += (tmp << 3) | (tmp >> 5);
-+	}
-+	spin_unlock_irqrestore(&primary_crng.lock, flags);
-+	return 1;
-+}
-+
- static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
- {
- 	unsigned long	flags;
-@@ -991,6 +1040,9 @@ void add_device_randomness(const void *buf, unsigned int size)
- 	unsigned long time = random_get_entropy() ^ jiffies;
- 	unsigned long flags;
- 
-+	if (!crng_ready() && size)
-+		crng_slow_load(buf, size);
-+
- 	trace_add_device_randomness(size, _RET_IP_);
- 	spin_lock_irqsave(&input_pool.lock, flags);
- 	_mix_pool_bytes(&input_pool, buf, size);
--- 
-2.16.4
-

+ 0 - 163
board/PSG/iot2000/linux-4.4-patches/0030-random-only-read-from-dev-random-after-its-pool-has-.patch

@@ -1,163 +0,0 @@
-From 6cb95e11da746d51f1defd91d5904f90c15fb743 Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Wed, 20 Feb 2019 16:06:38 -0500
-Subject: [PATCH 30/32] random: only read from /dev/random after its pool has
- received 128 bits
-
-Immediately after boot, we allow reads from /dev/random before its
-entropy pool has been fully initialized.  Fix this so that we don't
-allow this until the blocking pool has received 128 bits.
-
-We do this by repurposing the initialized flag in the entropy pool
-struct, and use the initialized flag in the blocking pool to indicate
-whether it is safe to pull from the blocking pool.
-
-To do this, we needed to rework when we decide to push entropy from the
-input pool to the blocking pool, since the initialized flag for the
-input pool was used for this purpose.  To simplify things, we no
-longer use the initialized flag for that purpose, nor do we use the
-entropy_total field any more.
-
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c         | 44 +++++++++++++++++++++----------------------
- include/trace/events/random.h | 13 +++++--------
- 2 files changed, 27 insertions(+), 30 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index ca9127abad52..f37a90896821 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -466,7 +466,6 @@ struct entropy_store {
- 	unsigned short add_ptr;
- 	unsigned short input_rotate;
- 	int entropy_count;
--	int entropy_total;
- 	unsigned int initialized:1;
- 	unsigned int limit:1;
- 	unsigned int last_data_init:1;
-@@ -642,7 +641,7 @@ static void process_random_ready_list(void)
-  */
- static void credit_entropy_bits(struct entropy_store *r, int nbits)
- {
--	int entropy_count, orig;
-+	int entropy_count, orig, has_initialized = 0;
- 	const int pool_size = r->poolinfo->poolfracbits;
- 	int nfrac = nbits << ENTROPY_SHIFT;
- 
-@@ -697,23 +696,25 @@ retry:
- 		entropy_count = 0;
- 	} else if (entropy_count > pool_size)
- 		entropy_count = pool_size;
-+	if ((r == &blocking_pool) && !r->initialized &&
-+	    (entropy_count >> ENTROPY_SHIFT) > 128)
-+		has_initialized = 1;
- 	if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
- 		goto retry;
- 
--	r->entropy_total += nbits;
--	if (!r->initialized && r->entropy_total > 128) {
-+	if (has_initialized)
- 		r->initialized = 1;
--		r->entropy_total = 0;
--	}
- 
- 	trace_credit_entropy_bits(r->name, nbits,
--				  entropy_count >> ENTROPY_SHIFT,
--				  r->entropy_total, _RET_IP_);
-+				  entropy_count >> ENTROPY_SHIFT, _RET_IP_);
- 
- 	if (r == &input_pool) {
- 		int entropy_bits = entropy_count >> ENTROPY_SHIFT;
-+		struct entropy_store *other = &blocking_pool;
- 
--		if (crng_init < 2 && entropy_bits >= 128) {
-+		if (crng_init < 2) {
-+			if (entropy_bits < 128)
-+				return;
- 			crng_reseed(&primary_crng, r);
- 			entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
- 		}
-@@ -723,20 +724,14 @@ retry:
- 			wake_up_interruptible(&random_read_wait);
- 			kill_fasync(&fasync, SIGIO, POLL_IN);
- 		}
--		/* If the input pool is getting full, send some
--		 * entropy to the blocking pool until it is 75% full.
-+		/* If the input pool is getting full, and the blocking
-+		 * pool has room, send some entropy to the blocking
-+		 * pool.
- 		 */
--		if (entropy_bits > random_write_wakeup_bits &&
--		    r->initialized &&
--		    r->entropy_total >= 2*random_read_wakeup_bits) {
--			struct entropy_store *other = &blocking_pool;
--
--			if (other->entropy_count <=
--			    3 * other->poolinfo->poolfracbits / 4) {
--				schedule_work(&other->push_work);
--				r->entropy_total = 0;
--			}
--		}
-+		if (!work_pending(&other->push_work) &&
-+		    (ENTROPY_BITS(r) > 6 * r->poolinfo->poolbytes) &&
-+		    (ENTROPY_BITS(other) <= 6 * other->poolinfo->poolbytes))
-+			schedule_work(&other->push_work);
- 	}
- }
- 
-@@ -1510,6 +1505,11 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
- 	int large_request = (nbytes > 256);
- 
- 	trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
-+	if (!r->initialized && r->pull) {
-+		xfer_secondary_pool(r, ENTROPY_BITS(r->pull)/8);
-+		if (!r->initialized)
-+			return 0;
-+	}
- 	xfer_secondary_pool(r, nbytes);
- 	nbytes = account(r, nbytes, 0, 0);
- 
-diff --git a/include/trace/events/random.h b/include/trace/events/random.h
-index 4684de344c5d..d5323630be90 100644
---- a/include/trace/events/random.h
-+++ b/include/trace/events/random.h
-@@ -61,15 +61,14 @@ DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
- 
- TRACE_EVENT(credit_entropy_bits,
- 	TP_PROTO(const char *pool_name, int bits, int entropy_count,
--		 int entropy_total, unsigned long IP),
-+		 unsigned long IP),
- 
--	TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
-+	TP_ARGS(pool_name, bits, entropy_count, IP),
- 
- 	TP_STRUCT__entry(
- 		__field( const char *,	pool_name		)
- 		__field(	  int,	bits			)
- 		__field(	  int,	entropy_count		)
--		__field(	  int,	entropy_total		)
- 		__field(unsigned long,	IP			)
- 	),
- 
-@@ -77,14 +76,12 @@ TRACE_EVENT(credit_entropy_bits,
- 		__entry->pool_name	= pool_name;
- 		__entry->bits		= bits;
- 		__entry->entropy_count	= entropy_count;
--		__entry->entropy_total	= entropy_total;
- 		__entry->IP		= IP;
- 	),
- 
--	TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
--		  "caller %pS", __entry->pool_name, __entry->bits,
--		  __entry->entropy_count, __entry->entropy_total,
--		  (void *)__entry->IP)
-+	TP_printk("%s pool: bits %d entropy_count %d caller %pS",
-+		  __entry->pool_name, __entry->bits,
-+		  __entry->entropy_count, (void *)__entry->IP)
- );
- 
- TRACE_EVENT(push_to_pool,
--- 
-2.16.4
-

+ 0 - 58
board/PSG/iot2000/linux-4.4-patches/0031-random-fix-soft-lockup-when-trying-to-read-from-an-u.patch

@@ -1,58 +0,0 @@
-From 4fe896ddf122abf98234154db65773db70f0b8a1 Mon Sep 17 00:00:00 2001
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Wed, 22 May 2019 12:02:16 -0400
-Subject: [PATCH 31/32] random: fix soft lockup when trying to read from an
- uninitialized blocking pool
-
-Fixes: eb9d1bf079bb: "random: only read from /dev/random after its pool has received 128 bits"
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
----
- drivers/char/random.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index f37a90896821..29755924aa45 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -702,8 +702,11 @@ retry:
- 	if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
- 		goto retry;
- 
--	if (has_initialized)
-+	if (has_initialized) {
- 		r->initialized = 1;
-+		wake_up_interruptible(&random_read_wait);
-+		kill_fasync(&fasync, SIGIO, POLL_IN);
-+	}
- 
- 	trace_credit_entropy_bits(r->name, nbits,
- 				  entropy_count >> ENTROPY_SHIFT, _RET_IP_);
-@@ -719,6 +722,13 @@ retry:
- 			entropy_bits = r->entropy_count >> ENTROPY_SHIFT;
- 		}
- 
-+		/* initialize the blocking pool if necessary */
-+		if (entropy_bits >= random_read_wakeup_bits &&
-+		    !other->initialized) {
-+			schedule_work(&other->push_work);
-+			return;
-+		}
-+
- 		/* should we wake readers? */
- 		if (entropy_bits >= random_read_wakeup_bits) {
- 			wake_up_interruptible(&random_read_wait);
-@@ -1795,8 +1805,8 @@ _random_read(int nonblock, char __user *buf, size_t nbytes)
- 			return -EAGAIN;
- 
- 		wait_event_interruptible(random_read_wait,
--			ENTROPY_BITS(&input_pool) >=
--			random_read_wakeup_bits);
-+		    blocking_pool.initialized &&
-+		    (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits));
- 		if (signal_pending(current))
- 			return -ERESTARTSYS;
- 	}
--- 
-2.16.4
-

+ 0 - 145
board/PSG/iot2000/linux-4.4-patches/0032-random-try-to-actively-add-entropy-rather-than-passi.patch

@@ -1,145 +0,0 @@
-From eb0b7b33a7bb77cd54cc4627044a77f1ee002139 Mon Sep 17 00:00:00 2001
-From: Linus Torvalds <torvalds@linux-foundation.org>
-Date: Sat, 28 Sep 2019 16:53:52 -0700
-Subject: [PATCH 32/32] random: try to actively add entropy rather than
- passively wait for it
-
-For 5.3 we had to revert a nice ext4 IO pattern improvement, because it
-caused a bootup regression due to lack of entropy at bootup together
-with arguably broken user space that was asking for secure random
-numbers when it really didn't need to.
-
-See commit 72dbcf721566 (Revert "ext4: make __ext4_get_inode_loc plug").
-
-This aims to solve the issue by actively generating entropy noise using
-the CPU cycle counter when waiting for the random number generator to
-initialize.  This only works when you have a high-frequency time stamp
-counter available, but that's the case on all modern x86 CPU's, and on
-most other modern CPU's too.
-
-What we do is to generate jitter entropy from the CPU cycle counter
-under a somewhat complex load: calling the scheduler while also
-guaranteeing a certain amount of timing noise by also triggering a
-timer.
-
-I'm sure we can tweak this, and that people will want to look at other
-alternatives, but there's been a number of papers written on jitter
-entropy, and this should really be fairly conservative by crediting one
-bit of entropy for every timer-induced jump in the cycle counter.  Not
-because the timer itself would be all that unpredictable, but because
-the interaction between the timer and the loop is going to be.
-
-Even if (and perhaps particularly if) the timer actually happens on
-another CPU, the cacheline interaction between the loop that reads the
-cycle counter and the timer itself firing is going to add perturbations
-to the cycle counter values that get mixed into the entropy pool.
-
-As Thomas pointed out, with a modern out-of-order CPU, even quite simple
-loops show a fair amount of hard-to-predict timing variability even in
-the absense of external interrupts.  But this tries to take that further
-by actually having a fairly complex interaction.
-
-This is not going to solve the entropy issue for architectures that have
-no CPU cycle counter, but it's not clear how (and if) that is solvable,
-and the hardware in question is largely starting to be irrelevant.  And
-by doing this we can at least avoid some of the even more contentious
-approaches (like making the entropy waiting time out in order to avoid
-the possibly unbounded waiting).
-
-Cc: Ahmed Darwish <darwish.07@gmail.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Theodore Ts'o <tytso@mit.edu>
-Cc: Nicholas Mc Guire <hofrat@opentech.at>
-Cc: Andy Lutomirski <luto@kernel.org>
-Cc: Kees Cook <keescook@chromium.org>
-Cc: Willy Tarreau <w@1wt.eu>
-Cc: Alexander E. Patrakov <patrakov@gmail.com>
-Cc: Lennart Poettering <mzxreary@0pointer.de>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
----
- drivers/char/random.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 61 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 29755924aa45..8bded70230de 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -1588,6 +1588,56 @@ void get_random_bytes(void *buf, int nbytes)
- }
- EXPORT_SYMBOL(get_random_bytes);
- 
-+
-+/*
-+ * Each time the timer fires, we expect that we got an unpredictable
-+ * jump in the cycle counter. Even if the timer is running on another
-+ * CPU, the timer activity will be touching the stack of the CPU that is
-+ * generating entropy..
-+ *
-+ * Note that we don't re-arm the timer in the timer itself - we are
-+ * happy to be scheduled away, since that just makes the load more
-+ * complex, but we do not want the timer to keep ticking unless the
-+ * entropy loop is running.
-+ *
-+ * So the re-arming always happens in the entropy loop itself.
-+ */
-+static void entropy_timer(unsigned long unused)
-+{
-+	credit_entropy_bits(&input_pool, 1);
-+}
-+
-+/*
-+ * If we have an actual cycle counter, see if we can
-+ * generate enough entropy with timing noise
-+ */
-+static void try_to_generate_entropy(void)
-+{
-+	struct {
-+		unsigned long now;
-+		struct timer_list timer;
-+	} stack;
-+
-+	stack.now = random_get_entropy();
-+
-+	/* Slow counter - or none. Don't even bother */
-+	if (stack.now == random_get_entropy())
-+		return;
-+
-+	setup_timer_on_stack(&stack.timer, entropy_timer, 0);
-+	while (!crng_ready()) {
-+		if (!timer_pending(&stack.timer))
-+			mod_timer(&stack.timer, jiffies+1);
-+		mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
-+		schedule();
-+		stack.now = random_get_entropy();
-+	}
-+
-+	del_timer_sync(&stack.timer);
-+	destroy_timer_on_stack(&stack.timer);
-+	mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
-+}
-+
- /*
-  * Wait for the urandom pool to be seeded and thus guaranteed to supply
-  * cryptographically secure random numbers. This applies to: the /dev/urandom
-@@ -1602,7 +1652,17 @@ int wait_for_random_bytes(void)
- {
- 	if (likely(crng_ready()))
- 		return 0;
--	return wait_event_interruptible(crng_init_wait, crng_ready());
-+
-+	do {
-+		int ret;
-+		ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
-+		if (ret)
-+			return ret > 0 ? 0 : ret;
-+
-+		try_to_generate_entropy();
-+	} while (!crng_ready());
-+
-+	return 0;
- }
- EXPORT_SYMBOL(wait_for_random_bytes);
- 
--- 
-2.16.4
-

+ 0 - 68
board/PSG/iot2000/linux-4.4-patches_orig/0001-stmmac-Add-support-for-SIMATIC-IOT2000-platform.patch

@@ -1,68 +0,0 @@
-From 702a99a0434380b1b7ce1b9045a71fbc30b436bb Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Wed, 6 Jul 2016 15:27:20 +0100
-Subject: [PATCH 01/27] stmmac: Add support for SIMATIC IOT2000 platform
-
-The IOT2000 is industrial controller platform, derived from the Intel
-Galileo Gen2 board. The variant IOT2020 comes with one LAN port, the
-IOT2040 has two of them. They can be told apart based on the board asset
-tag in the DMI table.
-
-Based on patch by Sascha Weisenberger.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 16 +++++++++++++++-
- 1 file changed, 15 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index d71a721ea61c..4801a46d0f07 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -36,6 +36,7 @@
-  */
- struct stmmac_pci_dmi_data {
- 	const char *name;
-+	const char *asset_tag;
- 	unsigned int func;
- 	int phy_addr;
- };
-@@ -50,6 +51,7 @@ struct stmmac_pci_info {
- static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
-+	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
- 	unsigned int func = PCI_FUNC(info->pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
-@@ -61,7 +63,8 @@ static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
- 		return 1;
- 
- 	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
--		if (!strcmp(dmi->name, name) && dmi->func == func)
-+		if (dmi->func == func && !strcmp(dmi->name, name) &&
-+		    (!dmi->asset_tag || !strcmp(dmi->asset_tag, asset_tag)))
- 			return dmi->phy_addr;
- 	}
- 
-@@ -138,6 +141,17 @@ static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 7,
-+		.phy_addr = 1,
-+	},
- 	{}
- };
- 
--- 
-2.12.0
-

+ 0 - 33
board/PSG/iot2000/linux-4.4-patches_orig/0002-serial-uapi-Add-support-for-bus-termination.patch

@@ -1,33 +0,0 @@
-From 78c076f026667f9a94592c54339b21af5ae09201 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Tue, 26 Jul 2016 20:31:09 +0200
-Subject: [PATCH 02/27] serial: uapi: Add support for bus termination
-
-The Siemens IOT2000 comes with a RS485 interface that allows to enable
-or disable bus termination via software. Add a bit to the flags field of
-serial_rs485 that applications can set in order to request this feature
-from the hardware. This seems generic enough to add it for everyone.
-Existing driver will simply ignore it when set.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- include/uapi/linux/serial.h | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
-index 25331f9faa76..7934e3247b45 100644
---- a/include/uapi/linux/serial.h
-+++ b/include/uapi/linux/serial.h
-@@ -121,6 +121,9 @@ struct serial_rs485 {
- #define SER_RS485_RTS_AFTER_SEND	(1 << 2)	/* Logical level for
- 							   RTS pin after sent*/
- #define SER_RS485_RX_DURING_TX		(1 << 4)
-+#define SER_RS485_TERMINATE_BUS		(1 << 5)	/* Enable bus
-+							   termination
-+							   (if supported) */
- 	__u32	delay_rts_before_send;	/* Delay before send (milliseconds) */
- 	__u32	delay_rts_after_send;	/* Delay after send (milliseconds) */
- 	__u32	padding[5];		/* Memory is cheap, new structs
--- 
-2.12.0
-

+ 0 - 103
board/PSG/iot2000/linux-4.4-patches_orig/0003-serial-8250_pci-Use-symbolic-constants-for-EXAR-s-MP.patch

@@ -1,103 +0,0 @@
-From 0b78ae582a7991832e13f01e25991a6287b5cd47 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Tue, 26 Jul 2016 21:00:59 +0200
-Subject: [PATCH 03/27] serial: 8250_pci: Use symbolic constants for EXAR's
- MPIO registers
-
-Commit b6fce7382d72274336aeafe6e44da755a371ed32 upstream.
-
-Less magic that only requires comments.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/tty/serial/8250/8250_pci.c | 55 +++++++++++++++++++++++---------------
- 1 file changed, 34 insertions(+), 21 deletions(-)
-
-diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
-index 83ff1724ec79..4df43fae4234 100644
---- a/drivers/tty/serial/8250/8250_pci.c
-+++ b/drivers/tty/serial/8250/8250_pci.c
-@@ -1755,6 +1755,19 @@ static int pci_eg20t_init(struct pci_dev *dev)
- #define PCI_DEVICE_ID_EXAR_XR17V4358	0x4358
- #define PCI_DEVICE_ID_EXAR_XR17V8358	0x8358
- 
-+#define UART_EXAR_MPIOINT_7_0	0x8f	/* MPIOINT[7:0] */
-+#define UART_EXAR_MPIOLVL_7_0	0x90	/* MPIOLVL[7:0] */
-+#define UART_EXAR_MPIO3T_7_0	0x91	/* MPIO3T[7:0] */
-+#define UART_EXAR_MPIOINV_7_0	0x92	/* MPIOINV[7:0] */
-+#define UART_EXAR_MPIOSEL_7_0	0x93	/* MPIOSEL[7:0] */
-+#define UART_EXAR_MPIOOD_7_0	0x94	/* MPIOOD[7:0] */
-+#define UART_EXAR_MPIOINT_15_8	0x95	/* MPIOINT[15:8] */
-+#define UART_EXAR_MPIOLVL_15_8	0x96	/* MPIOLVL[15:8] */
-+#define UART_EXAR_MPIO3T_15_8	0x97	/* MPIO3T[15:8] */
-+#define UART_EXAR_MPIOINV_15_8	0x98	/* MPIOINV[15:8] */
-+#define UART_EXAR_MPIOSEL_15_8	0x99	/* MPIOSEL[15:8] */
-+#define UART_EXAR_MPIOOD_15_8	0x9a	/* MPIOOD[15:8] */
-+
- static int
- pci_xr17c154_setup(struct serial_private *priv,
- 		  const struct pciserial_board *board,
-@@ -1797,18 +1810,18 @@ pci_xr17v35x_setup(struct serial_private *priv,
- 	 * Setup Multipurpose Input/Output pins.
- 	 */
- 	if (idx == 0) {
--		writeb(0x00, p + 0x8f); /*MPIOINT[7:0]*/
--		writeb(0x00, p + 0x90); /*MPIOLVL[7:0]*/
--		writeb(0x00, p + 0x91); /*MPIO3T[7:0]*/
--		writeb(0x00, p + 0x92); /*MPIOINV[7:0]*/
--		writeb(0x00, p + 0x93); /*MPIOSEL[7:0]*/
--		writeb(0x00, p + 0x94); /*MPIOOD[7:0]*/
--		writeb(0x00, p + 0x95); /*MPIOINT[15:8]*/
--		writeb(0x00, p + 0x96); /*MPIOLVL[15:8]*/
--		writeb(0x00, p + 0x97); /*MPIO3T[15:8]*/
--		writeb(0x00, p + 0x98); /*MPIOINV[15:8]*/
--		writeb(0x00, p + 0x99); /*MPIOSEL[15:8]*/
--		writeb(0x00, p + 0x9a); /*MPIOOD[15:8]*/
-+		writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
-+		writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
-+		writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
-+		writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
-+		writeb(0x00, p + UART_EXAR_MPIOSEL_15_8);
-+		writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
- 	}
- 	writeb(0x00, p + UART_EXAR_8XMODE);
- 	writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
-@@ -1844,20 +1857,20 @@ pci_fastcom335_setup(struct serial_private *priv,
- 		switch (priv->dev->device) {
- 		case PCI_DEVICE_ID_COMMTECH_4222PCI335:
- 		case PCI_DEVICE_ID_COMMTECH_4224PCI335:
--			writeb(0x78, p + 0x90); /* MPIOLVL[7:0] */
--			writeb(0x00, p + 0x92); /* MPIOINV[7:0] */
--			writeb(0x00, p + 0x93); /* MPIOSEL[7:0] */
-+			writeb(0x78, p + UART_EXAR_MPIOLVL_7_0);
-+			writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
-+			writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
- 			break;
- 		case PCI_DEVICE_ID_COMMTECH_2324PCI335:
- 		case PCI_DEVICE_ID_COMMTECH_2328PCI335:
--			writeb(0x00, p + 0x90); /* MPIOLVL[7:0] */
--			writeb(0xc0, p + 0x92); /* MPIOINV[7:0] */
--			writeb(0xc0, p + 0x93); /* MPIOSEL[7:0] */
-+			writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
-+			writeb(0xc0, p + UART_EXAR_MPIOINV_7_0);
-+			writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0);
- 			break;
- 		}
--		writeb(0x00, p + 0x8f); /* MPIOINT[7:0] */
--		writeb(0x00, p + 0x91); /* MPIO3T[7:0] */
--		writeb(0x00, p + 0x94); /* MPIOOD[7:0] */
-+		writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
-+		writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
- 	}
- 	writeb(0x00, p + UART_EXAR_8XMODE);
- 	writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
--- 
-2.12.0
-

+ 0 - 32
board/PSG/iot2000/linux-4.4-patches_orig/0004-serial-8250_pci-Fix-EXAR-feature-control-register-co.patch

@@ -1,32 +0,0 @@
-From 2ace954358c4da794a73156bc701c3ecb0b33f19 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Tue, 26 Jul 2016 21:24:32 +0200
-Subject: [PATCH 04/27] serial: 8250_pci: Fix EXAR feature control register
- constants
-
-According to the XR17V352 manual, bit 4 is IrDA control and bit 5 for
-485. Fortunately, no driver used them so far.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- include/uapi/linux/serial_reg.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
-index 1e5ac4e776da..cdb9f97a63c7 100644
---- a/include/uapi/linux/serial_reg.h
-+++ b/include/uapi/linux/serial_reg.h
-@@ -366,8 +366,8 @@
- #define UART_EXAR_DVID		0x8d	/* Device identification */
- 
- #define UART_EXAR_FCTR		0x08	/* Feature Control Register */
--#define UART_FCTR_EXAR_IRDA	0x08	/* IrDa data encode select */
--#define UART_FCTR_EXAR_485	0x10	/* Auto 485 half duplex dir ctl */
-+#define UART_FCTR_EXAR_IRDA	0x10	/* IrDa data encode select */
-+#define UART_FCTR_EXAR_485	0x20	/* Auto 485 half duplex dir ctl */
- #define UART_FCTR_EXAR_TRGA	0x00	/* FIFO trigger table A */
- #define UART_FCTR_EXAR_TRGB	0x60	/* FIFO trigger table B */
- #define UART_FCTR_EXAR_TRGC	0x80	/* FIFO trigger table C */
--- 
-2.12.0
-

+ 0 - 176
board/PSG/iot2000/linux-4.4-patches_orig/0005-serial-8250_pci-Add-support-for-IOT2000-platform.patch

@@ -1,176 +0,0 @@
-From fcc7fd22dca592b95941a0c3440c07b232a3ce4b Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Wed, 27 Jul 2016 16:32:20 +0200
-Subject: [PATCH 05/27] serial: 8250_pci: Add support for IOT2000 platform
-
-This implements the setup of RS232 and the switch-over to RS485 or RS422
-for the Siemens IOT2000 platform. That uses an EXAR XR17V352 with
-external logic to switch between the different modes. The external logic
-is controlled via MPIO pins of the EXAR controller.
-
-As the XR17V352 used on the IOT2000 is not equipped with an external
-EEPROM, it cannot present itself as IOT2000-variant via subvendor/
-subdevice IDs. Thus, we have to check via DMI for the target platform.
-
-Co-developed with Sascha Weisenberger.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Signed-off-by: Sascha Weisenberger <sascha.weisenberger@siemens.com>
----
- drivers/tty/serial/8250/8250_pci.c | 96 ++++++++++++++++++++++++++++++++++++--
- include/uapi/linux/serial_reg.h    |  2 +
- 2 files changed, 95 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
-index 4df43fae4234..1a918f924313 100644
---- a/drivers/tty/serial/8250/8250_pci.c
-+++ b/drivers/tty/serial/8250/8250_pci.c
-@@ -22,6 +22,7 @@
- #include <linux/8250_pci.h>
- #include <linux/bitops.h>
- #include <linux/rational.h>
-+#include <linux/dmi.h>
- 
- #include <asm/byteorder.h>
- #include <asm/io.h>
-@@ -1786,11 +1787,92 @@ xr17v35x_has_slave(struct serial_private *priv)
- 	        (dev_id == PCI_DEVICE_ID_EXAR_XR17V8358));
- }
- 
-+/*
-+ * IOT2000 MPIO wiring semantics:
-+ *
-+ * MPIO		Port	Function
-+ * ----		----	--------
-+ * 0		2 	Mode bit 0
-+ * 1		2	Mode bit 1
-+ * 2		2	Terminate bus
-+ * 3		2	<reserved>
-+ * 4		3	Mode bit 0
-+ * 5		3	Mode bit 1
-+ * 6		3	Terminate bus
-+ * 7		3	<reserved>
-+ * 8		3	Enable
-+ * 9		3	Enable
-+ * 10		-	Red LED
-+ * 11..15	-	<unused>
-+ */
-+
-+/* IOT2000 MPIOs 0..7 */
-+#define IOT2000_UART_MODE_RS232		0x01
-+#define IOT2000_UART_MODE_RS485		0x02
-+#define IOT2000_UART_MODE_RS422		0x03
-+#define IOT2000_UART_TERMINATE_BUS	0x04
-+
-+#define IOT2000_UART1_MASK		0x0f
-+#define IOT2000_UART2_SHIFT		4
-+
-+#define IOT2000_UARTS_DEFAULT_MODE	0x11	/* both RS232 */
-+#define IOT2000_UARTS_DEFAULT_GPIO_MODE	0x88	/* direction pins as input */
-+
-+/* IOT2000 MPIOs 8..15 */
-+#define IOT2000_UARTS_ENABLE		0x03
-+
-+static int pci_iot2000_rs485_config(struct uart_port *port,
-+				    struct serial_rs485 *rs485)
-+{
-+	u8 __iomem *p = port->membase;
-+	u8 mask = IOT2000_UART1_MASK;
-+	u8 mode, value;
-+	bool is_rs485 = false;
-+
-+	if (rs485->flags & SER_RS485_ENABLED) {
-+		is_rs485 = true;
-+		if (rs485->flags & SER_RS485_RX_DURING_TX)
-+			mode = IOT2000_UART_MODE_RS422;
-+		else
-+			mode = IOT2000_UART_MODE_RS485;
-+
-+		if (rs485->flags & SER_RS485_TERMINATE_BUS)
-+			mode |= IOT2000_UART_TERMINATE_BUS;
-+	} else {
-+		mode = IOT2000_UART_MODE_RS232;
-+	}
-+
-+	if (port->line == 3) {
-+		mask <<= IOT2000_UART2_SHIFT;
-+		mode <<= IOT2000_UART2_SHIFT;
-+	}
-+
-+	value = readb(p + UART_EXAR_MPIOLVL_7_0);
-+	value &= ~mask;
-+	value |= mode;
-+	writeb(value, p + UART_EXAR_MPIOLVL_7_0);
-+
-+	value = readb(p + UART_EXAR_FCTR);
-+	if (is_rs485)
-+		value |= UART_FCTR_EXAR_485;
-+	else
-+		value &= ~UART_FCTR_EXAR_485;
-+	writeb(value, p + UART_EXAR_FCTR);
-+
-+	if (is_rs485)
-+		writeb(UART_EXAR_RS485_DLY(4), p + UART_MSR);
-+
-+	port->rs485 = *rs485;
-+
-+	return 0;
-+}
-+
- static int
- pci_xr17v35x_setup(struct serial_private *priv,
- 		  const struct pciserial_board *board,
- 		  struct uart_8250_port *port, int idx)
- {
-+	bool is_iot2000;
- 	u8 __iomem *p;
- 
- 	p = pci_ioremap_bar(priv->dev, 0);
-@@ -1799,6 +1881,11 @@ pci_xr17v35x_setup(struct serial_private *priv,
- 
- 	port->port.flags |= UPF_EXAR_EFR;
- 
-+	is_iot2000 = strcmp(dmi_get_system_info(DMI_BOARD_NAME),
-+			    "SIMATIC IOT2000") == 0;
-+	if (is_iot2000)
-+		port->port.rs485_config = pci_iot2000_rs485_config;
-+
- 	/*
- 	 * Setup the uart clock for the devices on expansion slot to
- 	 * half the clock speed of the main chip (which is 125MHz)
-@@ -1811,13 +1898,16 @@ pci_xr17v35x_setup(struct serial_private *priv,
- 	 */
- 	if (idx == 0) {
- 		writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
--		writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
-+		writeb(is_iot2000 ? IOT2000_UARTS_DEFAULT_MODE : 0x00,
-+		       p + UART_EXAR_MPIOLVL_7_0);
- 		writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
- 		writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
--		writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
-+		writeb(is_iot2000 ? IOT2000_UARTS_DEFAULT_GPIO_MODE : 0x00,
-+		       p + UART_EXAR_MPIOSEL_7_0);
- 		writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
- 		writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
--		writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
-+		writeb(is_iot2000 ? IOT2000_UARTS_ENABLE : 0x00,
-+		       p + UART_EXAR_MPIOLVL_15_8);
- 		writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
- 		writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
- 		writeb(0x00, p + UART_EXAR_MPIOSEL_15_8);
-diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h
-index cdb9f97a63c7..9be7eb2478fe 100644
---- a/include/uapi/linux/serial_reg.h
-+++ b/include/uapi/linux/serial_reg.h
-@@ -365,6 +365,8 @@
- #define UART_EXAR_SLEEP		0x8b	/* Sleep mode */
- #define UART_EXAR_DVID		0x8d	/* Device identification */
- 
-+#define UART_EXAR_RS485_DLY(x) (x << 4)
-+
- #define UART_EXAR_FCTR		0x08	/* Feature Control Register */
- #define UART_FCTR_EXAR_IRDA	0x10	/* IrDa data encode select */
- #define UART_FCTR_EXAR_485	0x20	/* Auto 485 half duplex dir ctl */
--- 
-2.12.0
-

+ 0 - 152
board/PSG/iot2000/linux-4.4-patches_orig/0006-serial-8250_pci-Add-support-for-red-user-LED-on-IOT2.patch

@@ -1,152 +0,0 @@
-From ef914549f1cbf53abf2720d8f5d163125484a000 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Mon, 9 Jan 2017 20:24:39 +0100
-Subject: [PATCH 06/27] serial: 8250_pci: Add support for red user LED on
- IOT2040
-
-The IOT2040 has a red LED connected to one of the MPIOs of the EXAR
-on-board UARTs. Wire it up to the LED subsystem.
-
-Based on work by Frank Ehlis and Sascha Weisenberger.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/tty/serial/8250/8250_pci.c | 80 +++++++++++++++++++++++++++++++++++++-
- 1 file changed, 79 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
-index 1a918f924313..5cd4fb8cb20b 100644
---- a/drivers/tty/serial/8250/8250_pci.c
-+++ b/drivers/tty/serial/8250/8250_pci.c
-@@ -23,6 +23,7 @@
- #include <linux/bitops.h>
- #include <linux/rational.h>
- #include <linux/dmi.h>
-+#include <linux/leds.h>
- 
- #include <asm/byteorder.h>
- #include <asm/io.h>
-@@ -59,6 +60,7 @@ struct serial_private {
- 	void __iomem		*remapped_bar[PCI_NUM_BAR_RESOURCES];
- 	struct pci_serial_quirk	*quirk;
- 	const struct pciserial_board *board;
-+	void			*quirk_private;
- 	int			line[0];
- };
- 
-@@ -1820,6 +1822,14 @@ xr17v35x_has_slave(struct serial_private *priv)
- 
- /* IOT2000 MPIOs 8..15 */
- #define IOT2000_UARTS_ENABLE		0x03
-+#define IOT2000_UART_LED_RED		0x04
-+
-+#define IOT2000_UART_LEDFS_NAME		"mpio_uart_led:red:user"
-+
-+struct iot2000_serial_private {
-+	u8 __iomem *membase;
-+	struct led_classdev led;
-+};
- 
- static int pci_iot2000_rs485_config(struct uart_port *port,
- 				    struct serial_rs485 *rs485)
-@@ -1867,13 +1877,43 @@ static int pci_iot2000_rs485_config(struct uart_port *port,
- 	return 0;
- }
- 
-+static void iot2000_brightness_set(struct led_classdev *cdev,
-+				   enum led_brightness brightness)
-+{
-+	struct iot2000_serial_private *iot2000_priv =
-+		container_of(cdev, struct iot2000_serial_private, led);
-+	u8 value;
-+
-+	value = readb(iot2000_priv->membase + UART_EXAR_MPIOLVL_15_8);
-+	if (brightness == LED_OFF)
-+		value &= ~IOT2000_UART_LED_RED;
-+	else
-+		value |= IOT2000_UART_LED_RED;
-+	writeb(value, iot2000_priv->membase + UART_EXAR_MPIOLVL_15_8);
-+}
-+
-+static enum led_brightness iot2000_brightness_get(struct led_classdev *cdev)
-+{
-+	struct iot2000_serial_private *iot2000_priv =
-+		container_of(cdev, struct iot2000_serial_private, led);
-+	u8 value;
-+
-+	value = readb(iot2000_priv->membase + UART_EXAR_MPIOLVL_15_8);
-+	if (value & IOT2000_UART_LED_RED)
-+		return LED_FULL;
-+
-+	return LED_OFF;
-+}
-+
- static int
- pci_xr17v35x_setup(struct serial_private *priv,
- 		  const struct pciserial_board *board,
- 		  struct uart_8250_port *port, int idx)
- {
-+	struct iot2000_serial_private *iot2000_priv = NULL;
- 	bool is_iot2000;
- 	u8 __iomem *p;
-+	int ret;
- 
- 	p = pci_ioremap_bar(priv->dev, 0);
- 	if (p == NULL)
-@@ -1919,7 +1959,44 @@ pci_xr17v35x_setup(struct serial_private *priv,
- 	writeb(128, p + UART_EXAR_RXTRG);
- 	iounmap(p);
- 
--	return pci_default_setup(priv, board, port, idx);
-+	ret = pci_default_setup(priv, board, port, idx);
-+	if (ret)
-+		return ret;
-+
-+	/* on IOT2000, register the red LED attached to the MPIO */
-+	if (is_iot2000 && idx == 0) {
-+		iot2000_priv = kzalloc(sizeof(*iot2000_priv), GFP_KERNEL);
-+		if (!iot2000_priv)
-+			return -ENOMEM;
-+
-+		iot2000_priv->membase = port->port.membase;
-+
-+		iot2000_priv->led.name = IOT2000_UART_LEDFS_NAME;
-+		iot2000_priv->led.max_brightness = 1;
-+		iot2000_priv->led.brightness_set = iot2000_brightness_set;
-+		iot2000_priv->led.brightness_get = iot2000_brightness_get;
-+		iot2000_priv->led.default_trigger = "none";
-+		ret = led_classdev_register(port->port.dev, &iot2000_priv->led);
-+		if (ret) {
-+			kfree(iot2000_priv);
-+			return ret;
-+		}
-+
-+		priv->quirk_private = iot2000_priv;
-+	}
-+
-+	return 0;
-+}
-+
-+void pci_xr17v35x_exit(struct pci_dev *dev)
-+{
-+	struct serial_private *priv = pci_get_drvdata(dev);
-+	struct iot2000_serial_private *iot2000_priv = priv->quirk_private;
-+
-+	if (iot2000_priv) {
-+		led_classdev_unregister(&iot2000_priv->led);
-+		kfree(iot2000_priv);
-+	}
- }
- 
- #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
-@@ -2571,6 +2648,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
- 		.subvendor	= PCI_ANY_ID,
- 		.subdevice	= PCI_ANY_ID,
- 		.setup		= pci_xr17v35x_setup,
-+		.exit		= pci_xr17v35x_exit,
- 	},
- 	{
- 		.vendor = PCI_VENDOR_ID_EXAR,
--- 
-2.12.0
-

+ 0 - 67
board/PSG/iot2000/linux-4.4-patches_orig/0007-spi-pxa2xx-Factor-out-handle_bad_msg.patch

@@ -1,67 +0,0 @@
-From fd5837ca7accfcdfa68d44ab38359d1fd0a6f142 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Mon, 16 Jan 2017 19:44:54 +0100
-Subject: [PATCH 07/27] spi: pxa2xx: Factor out handle_bad_msg
-
-Commit b03124825b8612bf371e5b4ccc2cd812ed3c2dbb upstream.
-
-As suggested by Andy Shevchenko: Decouple this corner cause from the
-general handling logic in ssp_int.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-pxa2xx.c | 29 +++++++++++++++--------------
- 1 file changed, 15 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
-index 082d447ad929..904439fa6a00 100644
---- a/drivers/spi/spi-pxa2xx.c
-+++ b/drivers/spi/spi-pxa2xx.c
-@@ -677,6 +677,20 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
- 	return IRQ_HANDLED;
- }
- 
-+static void handle_bad_msg(struct driver_data *drv_data)
-+{
-+	pxa2xx_spi_write(drv_data, SSCR0,
-+			 pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
-+	pxa2xx_spi_write(drv_data, SSCR1,
-+			 pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1);
-+	if (!pxa25x_ssp_comp(drv_data))
-+		pxa2xx_spi_write(drv_data, SSTO, 0);
-+	write_SSSR_CS(drv_data, drv_data->clear_sr);
-+
-+	dev_err(&drv_data->pdev->dev,
-+		"bad message state in interrupt handler\n");
-+}
-+
- static irqreturn_t ssp_int(int irq, void *dev_id)
- {
- 	struct driver_data *drv_data = dev_id;
-@@ -717,20 +731,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
- 		return IRQ_NONE;
- 
- 	if (!drv_data->cur_msg) {
--
--		pxa2xx_spi_write(drv_data, SSCR0,
--				 pxa2xx_spi_read(drv_data, SSCR0)
--				 & ~SSCR0_SSE);
--		pxa2xx_spi_write(drv_data, SSCR1,
--				 pxa2xx_spi_read(drv_data, SSCR1)
--				 & ~drv_data->int_cr1);
--		if (!pxa25x_ssp_comp(drv_data))
--			pxa2xx_spi_write(drv_data, SSTO, 0);
--		write_SSSR_CS(drv_data, drv_data->clear_sr);
--
--		dev_err(&drv_data->pdev->dev,
--			"bad message state in interrupt handler\n");
--
-+		handle_bad_msg(drv_data);
- 		/* Never fail */
- 		return IRQ_HANDLED;
- 	}
--- 
-2.12.0
-

+ 0 - 41
board/PSG/iot2000/linux-4.4-patches_orig/0008-spi-pxa2xx-Prepare-for-edge-triggered-interrupts.patch

@@ -1,41 +0,0 @@
-From 7f9a454ea467bb1ee31cf77ce1c7e0aa1950d6d1 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Sat, 21 Jan 2017 10:06:38 +0100
-Subject: [PATCH 08/27] spi: pxa2xx: Prepare for edge-triggered interrupts
-
-Commit e51e9b93049f624c179bab2c651995bca22b5bb7 upstream.
-
-When using the a device with edge-triggered interrupts, such as MSIs,
-the interrupt handler has to ensure that there is a point in time during
-its execution where all interrupts sources are silent so that a new
-event can trigger a new interrupt again.
-
-This is achieved here by disabling all interrupt sources for a moment
-before processing them according to the status register. If a new
-interrupt should have arrived after we read the status, it will now
-re-trigger the interrupt, even in edge mode.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spi-pxa2xx.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
-index 904439fa6a00..b52faa295698 100644
---- a/drivers/spi/spi-pxa2xx.c
-+++ b/drivers/spi/spi-pxa2xx.c
-@@ -730,6 +730,9 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
- 	if (!(status & mask))
- 		return IRQ_NONE;
- 
-+	pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg & ~drv_data->int_cr1);
-+	pxa2xx_spi_write(drv_data, SSCR1, sccr1_reg);
-+
- 	if (!drv_data->cur_msg) {
- 		handle_bad_msg(drv_data);
- 		/* Never fail */
--- 
-2.12.0
-

+ 0 - 39
board/PSG/iot2000/linux-4.4-patches_orig/0009-spi-pca2xx-pci-Allow-MSI.patch

@@ -1,39 +0,0 @@
-From e8bc5d5bb5b203ffe4a1266aa84dcfb740842f4a Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Mon, 26 Sep 2016 08:52:49 +0200
-Subject: [PATCH 09/27] spi: pca2xx-pci: Allow MSI
-
-Backport of 64e02cb0bdfc7cef0a01e2ad4d567fdc0a74450e upstream.
-
-Now that the core is ready for edge-triggered interrupts, we can safely
-allow the PCI versions that provide this to enable the feature and,
-thus, have less shared interrupts.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/spi/spi-pxa2xx-pci.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c
-index 562ffc1282bc..0b1c9c4aa355 100644
---- a/drivers/spi/spi-pxa2xx-pci.c
-+++ b/drivers/spi/spi-pxa2xx-pci.c
-@@ -156,10 +156,14 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
- 		dev_err(&dev->dev, "failed to ioremap() registers\n");
- 		return -EIO;
- 	}
--	ssp->irq = dev->irq;
- 	ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
- 	ssp->type = c->type;
- 
-+	pci_set_master(dev);
-+
-+	pci_enable_msi(dev);
-+	ssp->irq = dev->irq;
-+
- 	snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
- 	ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL,
- 					CLK_IS_ROOT, c->max_clk_rate);
--- 
-2.12.0
-

+ 0 - 129
board/PSG/iot2000/linux-4.4-patches_orig/0010-efi-Move-efi_status_to_err-to-drivers-firmware-efi.patch

@@ -1,129 +0,0 @@
-From b553ed1d8ee69dfde08677c0843dc2931c3c3ad0 Mon Sep 17 00:00:00 2001
-From: Matt Fleming <matt@codeblueprint.co.uk>
-Date: Mon, 25 Apr 2016 21:06:58 +0100
-Subject: [PATCH 10/27] efi: Move efi_status_to_err() to drivers/firmware/efi/
-
-Commit 806b0351c9ff9890c1ef0ba2c46237baef49ac79 upstream.
-
-Move efi_status_to_err() to the architecture independent code as it's
-generally useful in all bits of EFI code where there is a need to
-convert an efi_status_t to a kernel error value.
-
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1461614832-17633-27-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/efi.c  | 33 +++++++++++++++++++++++++++++++++
- drivers/firmware/efi/vars.c | 33 ---------------------------------
- include/linux/efi.h         |  2 ++
- 3 files changed, 35 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
-index 951d04e976c9..5e803916fbb6 100644
---- a/drivers/firmware/efi/efi.c
-+++ b/drivers/firmware/efi/efi.c
-@@ -748,3 +748,36 @@ u64 __weak efi_mem_attributes(unsigned long phys_addr)
- 	}
- 	return 0;
- }
-+
-+int efi_status_to_err(efi_status_t status)
-+{
-+	int err;
-+
-+	switch (status) {
-+	case EFI_SUCCESS:
-+		err = 0;
-+		break;
-+	case EFI_INVALID_PARAMETER:
-+		err = -EINVAL;
-+		break;
-+	case EFI_OUT_OF_RESOURCES:
-+		err = -ENOSPC;
-+		break;
-+	case EFI_DEVICE_ERROR:
-+		err = -EIO;
-+		break;
-+	case EFI_WRITE_PROTECTED:
-+		err = -EROFS;
-+		break;
-+	case EFI_SECURITY_VIOLATION:
-+		err = -EACCES;
-+		break;
-+	case EFI_NOT_FOUND:
-+		err = -ENOENT;
-+		break;
-+	default:
-+		err = -EINVAL;
-+	}
-+
-+	return err;
-+}
-diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
-index c7eeeb44e72a..56228c50c6f4 100644
---- a/drivers/firmware/efi/vars.c
-+++ b/drivers/firmware/efi/vars.c
-@@ -318,39 +318,6 @@ check_var_size(u32 attributes, unsigned long size)
- 	return fops->query_variable_store(attributes, size);
- }
- 
--static int efi_status_to_err(efi_status_t status)
--{
--	int err;
--
--	switch (status) {
--	case EFI_SUCCESS:
--		err = 0;
--		break;
--	case EFI_INVALID_PARAMETER:
--		err = -EINVAL;
--		break;
--	case EFI_OUT_OF_RESOURCES:
--		err = -ENOSPC;
--		break;
--	case EFI_DEVICE_ERROR:
--		err = -EIO;
--		break;
--	case EFI_WRITE_PROTECTED:
--		err = -EROFS;
--		break;
--	case EFI_SECURITY_VIOLATION:
--		err = -EACCES;
--		break;
--	case EFI_NOT_FOUND:
--		err = -ENOENT;
--		break;
--	default:
--		err = -EINVAL;
--	}
--
--	return err;
--}
--
- static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
- 				struct list_head *head)
- {
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 496c2d4ff76e..729c9116a067 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -999,6 +999,8 @@ static inline void
- efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
- #endif
- 
-+extern int efi_status_to_err(efi_status_t status);
-+
- /*
-  * Variable Attributes
-  */
--- 
-2.12.0
-

+ 0 - 431
board/PSG/iot2000/linux-4.4-patches_orig/0011-efi-Add-capsule-update-support.patch

@@ -1,431 +0,0 @@
-From 62694114a8052ff871f0cdc86034e4711f7b7579 Mon Sep 17 00:00:00 2001
-From: Matt Fleming <matt@codeblueprint.co.uk>
-Date: Mon, 25 Apr 2016 21:06:59 +0100
-Subject: [PATCH 11/27] efi: Add 'capsule' update support
-
-Commit f0133f3c5b8bb34ec4dec50c27e7a655aeee8935 upstream.
-
-The EFI capsule mechanism allows data blobs to be passed to the EFI
-firmware. A common use case is performing firmware updates. This patch
-just introduces the main infrastructure for interacting with the
-firmware, and a driver that allows users to upload capsules will come
-in a later patch.
-
-Once a capsule has been passed to the firmware, the next reboot must
-be performed using the ResetSystem() EFI runtime service, which may
-involve overriding the reboot type specified by reboot=. This ensures
-the reset value returned by QueryCapsuleCapabilities() is used to
-reset the system, which is required for the capsule to be processed.
-efi_capsule_pending() is provided for this purpose.
-
-At the moment we only allow a single capsule blob to be sent to the
-firmware despite the fact that UpdateCapsule() takes a 'CapsuleCount'
-parameter. This simplifies the API and shouldn't result in any
-downside since it is still possible to send multiple capsules by
-repeatedly calling UpdateCapsule().
-
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Mark Salter <msalter@redhat.com>
-Cc: Peter Jones <pjones@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1461614832-17633-28-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/Makefile  |   1 +
- drivers/firmware/efi/capsule.c | 300 +++++++++++++++++++++++++++++++++++++++++
- drivers/firmware/efi/reboot.c  |  12 +-
- include/linux/efi.h            |  14 ++
- 4 files changed, 326 insertions(+), 1 deletion(-)
- create mode 100644 drivers/firmware/efi/capsule.c
-
-diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
-index ec379a4164cc..54b19cdbfcf8 100644
---- a/drivers/firmware/efi/Makefile
-+++ b/drivers/firmware/efi/Makefile
-@@ -10,6 +10,7 @@
- KASAN_SANITIZE_runtime-wrappers.o	:= n
- 
- obj-$(CONFIG_EFI)			+= efi.o vars.o reboot.o
-+obj-$(CONFIG_EFI)			+= capsule.o
- obj-$(CONFIG_EFI_VARS)			+= efivars.o
- obj-$(CONFIG_EFI_ESRT)			+= esrt.o
- obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
-diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
-new file mode 100644
-index 000000000000..0de55944ac0b
---- /dev/null
-+++ b/drivers/firmware/efi/capsule.c
-@@ -0,0 +1,300 @@
-+/*
-+ * EFI capsule support.
-+ *
-+ * Copyright 2013 Intel Corporation; author Matt Fleming
-+ *
-+ * This file is part of the Linux kernel, and is made available under
-+ * the terms of the GNU General Public License version 2.
-+ */
-+
-+#define pr_fmt(fmt) "efi: " fmt
-+
-+#include <linux/slab.h>
-+#include <linux/mutex.h>
-+#include <linux/highmem.h>
-+#include <linux/efi.h>
-+#include <linux/vmalloc.h>
-+#include <asm/io.h>
-+
-+typedef struct {
-+	u64 length;
-+	u64 data;
-+} efi_capsule_block_desc_t;
-+
-+static bool capsule_pending;
-+static int efi_reset_type = -1;
-+
-+/*
-+ * capsule_mutex serialises access to both capsule_pending and
-+ * efi_reset_type.
-+ */
-+static DEFINE_MUTEX(capsule_mutex);
-+
-+/**
-+ * efi_capsule_pending - has a capsule been passed to the firmware?
-+ * @reset_type: store the type of EFI reset if capsule is pending
-+ *
-+ * To ensure that the registered capsule is processed correctly by the
-+ * firmware we need to perform a specific type of reset. If a capsule is
-+ * pending return the reset type in @reset_type.
-+ *
-+ * This function will race with callers of efi_capsule_update(), for
-+ * example, calling this function while somebody else is in
-+ * efi_capsule_update() but hasn't reached efi_capsue_update_locked()
-+ * will miss the updates to capsule_pending and efi_reset_type after
-+ * efi_capsule_update_locked() completes.
-+ *
-+ * A non-racy use is from platform reboot code because we use
-+ * system_state to ensure no capsules can be sent to the firmware once
-+ * we're at SYSTEM_RESTART. See efi_capsule_update_locked().
-+ */
-+bool efi_capsule_pending(int *reset_type)
-+{
-+	bool rv = false;
-+
-+	mutex_lock(&capsule_mutex);
-+	if (!capsule_pending)
-+		goto out;
-+
-+	if (reset_type)
-+		*reset_type = efi_reset_type;
-+	rv = true;
-+out:
-+	mutex_unlock(&capsule_mutex);
-+	return rv;
-+}
-+
-+/*
-+ * Whitelist of EFI capsule flags that we support.
-+ *
-+ * We do not handle EFI_CAPSULE_INITIATE_RESET because that would
-+ * require us to prepare the kernel for reboot. Refuse to load any
-+ * capsules with that flag and any other flags that we do not know how
-+ * to handle.
-+ */
-+#define EFI_CAPSULE_SUPPORTED_FLAG_MASK			\
-+	(EFI_CAPSULE_PERSIST_ACROSS_RESET | EFI_CAPSULE_POPULATE_SYSTEM_TABLE)
-+
-+/**
-+ * efi_capsule_supported - does the firmware support the capsule?
-+ * @guid: vendor guid of capsule
-+ * @flags: capsule flags
-+ * @size: size of capsule data
-+ * @reset: the reset type required for this capsule
-+ *
-+ * Check whether a capsule with @flags is supported by the firmware
-+ * and that @size doesn't exceed the maximum size for a capsule.
-+ *
-+ * No attempt is made to check @reset against the reset type required
-+ * by any pending capsules because of the races involved.
-+ */
-+int efi_capsule_supported(efi_guid_t guid, u32 flags, size_t size, int *reset)
-+{
-+	efi_capsule_header_t *capsule;
-+	efi_status_t status;
-+	u64 max_size;
-+	int rv = 0;
-+
-+	if (flags & ~EFI_CAPSULE_SUPPORTED_FLAG_MASK)
-+		return -EINVAL;
-+
-+	capsule = kmalloc(sizeof(*capsule), GFP_KERNEL);
-+	if (!capsule)
-+		return -ENOMEM;
-+
-+	capsule->headersize = capsule->imagesize = sizeof(*capsule);
-+	memcpy(&capsule->guid, &guid, sizeof(efi_guid_t));
-+	capsule->flags = flags;
-+
-+	status = efi.query_capsule_caps(&capsule, 1, &max_size, reset);
-+	if (status != EFI_SUCCESS) {
-+		rv = efi_status_to_err(status);
-+		goto out;
-+	}
-+
-+	if (size > max_size)
-+		rv = -ENOSPC;
-+out:
-+	kfree(capsule);
-+	return rv;
-+}
-+EXPORT_SYMBOL_GPL(efi_capsule_supported);
-+
-+/*
-+ * Every scatter gather list (block descriptor) page must end with a
-+ * continuation pointer. The last continuation pointer of the last
-+ * page must be zero to mark the end of the chain.
-+ */
-+#define SGLIST_PER_PAGE	((PAGE_SIZE / sizeof(efi_capsule_block_desc_t)) - 1)
-+
-+/*
-+ * How many scatter gather list (block descriptor) pages do we need
-+ * to map @count pages?
-+ */
-+static inline unsigned int sg_pages_num(unsigned int count)
-+{
-+	return DIV_ROUND_UP(count, SGLIST_PER_PAGE);
-+}
-+
-+/**
-+ * efi_capsule_update_locked - pass a single capsule to the firmware
-+ * @capsule: capsule to send to the firmware
-+ * @sg_pages: array of scatter gather (block descriptor) pages
-+ * @reset: the reset type required for @capsule
-+ *
-+ * Since this function must be called under capsule_mutex check
-+ * whether efi_reset_type will conflict with @reset, and atomically
-+ * set it and capsule_pending if a capsule was successfully sent to
-+ * the firmware.
-+ *
-+ * We also check to see if the system is about to restart, and if so,
-+ * abort. This avoids races between efi_capsule_update() and
-+ * efi_capsule_pending().
-+ */
-+static int
-+efi_capsule_update_locked(efi_capsule_header_t *capsule,
-+			  struct page **sg_pages, int reset)
-+{
-+	efi_physical_addr_t sglist_phys;
-+	efi_status_t status;
-+
-+	lockdep_assert_held(&capsule_mutex);
-+
-+	/*
-+	 * If someone has already registered a capsule that requires a
-+	 * different reset type, we're out of luck and must abort.
-+	 */
-+	if (efi_reset_type >= 0 && efi_reset_type != reset) {
-+		pr_err("Conflicting capsule reset type %d (%d).\n",
-+		       reset, efi_reset_type);
-+		return -EINVAL;
-+	}
-+
-+	/*
-+	 * If the system is getting ready to restart it may have
-+	 * called efi_capsule_pending() to make decisions (such as
-+	 * whether to force an EFI reboot), and we're racing against
-+	 * that call. Abort in that case.
-+	 */
-+	if (unlikely(system_state == SYSTEM_RESTART)) {
-+		pr_warn("Capsule update raced with reboot, aborting.\n");
-+		return -EINVAL;
-+	}
-+
-+	sglist_phys = page_to_phys(sg_pages[0]);
-+
-+	status = efi.update_capsule(&capsule, 1, sglist_phys);
-+	if (status == EFI_SUCCESS) {
-+		capsule_pending = true;
-+		efi_reset_type = reset;
-+	}
-+
-+	return efi_status_to_err(status);
-+}
-+
-+/**
-+ * efi_capsule_update - send a capsule to the firmware
-+ * @capsule: capsule to send to firmware
-+ * @pages: an array of capsule data pages
-+ *
-+ * Build a scatter gather list with EFI capsule block descriptors to
-+ * map the capsule described by @capsule with its data in @pages and
-+ * send it to the firmware via the UpdateCapsule() runtime service.
-+ *
-+ * @capsule must be a virtual mapping of the first page in @pages
-+ * (@pages[0]) in the kernel address space. That is, a
-+ * capsule_header_t that describes the entire contents of the capsule
-+ * must be at the start of the first data page.
-+ *
-+ * Even though this function will validate that the firmware supports
-+ * the capsule guid, users will likely want to check that
-+ * efi_capsule_supported() returns true before calling this function
-+ * because it makes it easier to print helpful error messages.
-+ *
-+ * If the capsule is successfully submitted to the firmware, any
-+ * subsequent calls to efi_capsule_pending() will return true. @pages
-+ * must not be released or modified if this function returns
-+ * successfully.
-+ *
-+ * Callers must be prepared for this function to fail, which can
-+ * happen if we raced with system reboot or if there is already a
-+ * pending capsule that has a reset type that conflicts with the one
-+ * required by @capsule. Do NOT use efi_capsule_pending() to detect
-+ * this conflict since that would be racy. Instead, submit the capsule
-+ * to efi_capsule_update() and check the return value.
-+ *
-+ * Return 0 on success, a converted EFI status code on failure.
-+ */
-+int efi_capsule_update(efi_capsule_header_t *capsule, struct page **pages)
-+{
-+	u32 imagesize = capsule->imagesize;
-+	efi_guid_t guid = capsule->guid;
-+	unsigned int count, sg_count;
-+	u32 flags = capsule->flags;
-+	struct page **sg_pages;
-+	int rv, reset_type;
-+	int i, j;
-+
-+	rv = efi_capsule_supported(guid, flags, imagesize, &reset_type);
-+	if (rv)
-+		return rv;
-+
-+	count = DIV_ROUND_UP(imagesize, PAGE_SIZE);
-+	sg_count = sg_pages_num(count);
-+
-+	sg_pages = kzalloc(sg_count * sizeof(*sg_pages), GFP_KERNEL);
-+	if (!sg_pages)
-+		return -ENOMEM;
-+
-+	for (i = 0; i < sg_count; i++) {
-+		sg_pages[i] = alloc_page(GFP_KERNEL);
-+		if (!sg_pages[i]) {
-+			rv = -ENOMEM;
-+			goto out;
-+		}
-+	}
-+
-+	for (i = 0; i < sg_count; i++) {
-+		efi_capsule_block_desc_t *sglist;
-+
-+		sglist = kmap(sg_pages[i]);
-+		if (!sglist) {
-+			rv = -ENOMEM;
-+			goto out;
-+		}
-+
-+		for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
-+			u64 sz = min_t(u64, imagesize, PAGE_SIZE);
-+
-+			sglist[j].length = sz;
-+			sglist[j].data = page_to_phys(*pages++);
-+
-+			imagesize -= sz;
-+			count--;
-+		}
-+
-+		/* Continuation pointer */
-+		sglist[j].length = 0;
-+
-+		if (i + 1 == sg_count)
-+			sglist[j].data = 0;
-+		else
-+			sglist[j].data = page_to_phys(sg_pages[i + 1]);
-+
-+		kunmap(sg_pages[i]);
-+	}
-+
-+	mutex_lock(&capsule_mutex);
-+	rv = efi_capsule_update_locked(capsule, sg_pages, reset_type);
-+	mutex_unlock(&capsule_mutex);
-+
-+out:
-+	for (i = 0; rv && i < sg_count; i++) {
-+		if (sg_pages[i])
-+			__free_page(sg_pages[i]);
-+	}
-+
-+	kfree(sg_pages);
-+	return rv;
-+}
-+EXPORT_SYMBOL_GPL(efi_capsule_update);
-diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
-index 9c59d1c795d1..62ead9b9d871 100644
---- a/drivers/firmware/efi/reboot.c
-+++ b/drivers/firmware/efi/reboot.c
-@@ -9,7 +9,8 @@ int efi_reboot_quirk_mode = -1;
- 
- void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
- {
--	int efi_mode;
-+	const char *str[] = { "cold", "warm", "shutdown", "platform" };
-+	int efi_mode, cap_reset_mode;
- 
- 	if (!efi_enabled(EFI_RUNTIME_SERVICES))
- 		return;
-@@ -30,6 +31,15 @@ void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
- 	if (efi_reboot_quirk_mode != -1)
- 		efi_mode = efi_reboot_quirk_mode;
- 
-+	if (efi_capsule_pending(&cap_reset_mode)) {
-+		if (efi_mode != cap_reset_mode)
-+			printk(KERN_CRIT "efi: %s reset requested but pending "
-+			       "capsule update requires %s reset... Performing "
-+			       "%s reset.\n", str[efi_mode], str[cap_reset_mode],
-+			       str[cap_reset_mode]);
-+		efi_mode = cap_reset_mode;
-+	}
-+
- 	efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL);
- }
- 
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 729c9116a067..848678a1cace 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -123,6 +123,13 @@ typedef struct {
- } efi_capsule_header_t;
- 
- /*
-+ * EFI capsule flags
-+ */
-+#define EFI_CAPSULE_PERSIST_ACROSS_RESET	0x00010000
-+#define EFI_CAPSULE_POPULATE_SYSTEM_TABLE	0x00020000
-+#define EFI_CAPSULE_INITIATE_RESET		0x00040000
-+
-+/*
-  * Allocation types for calls to boottime->allocate_pages.
-  */
- #define EFI_ALLOCATE_ANY_PAGES		0
-@@ -1214,6 +1221,13 @@ int efivars_sysfs_init(void);
- #define EFIVARS_DATA_SIZE_MAX 1024
- 
- #endif /* CONFIG_EFI_VARS */
-+extern bool efi_capsule_pending(int *reset_type);
-+
-+extern int efi_capsule_supported(efi_guid_t guid, u32 flags,
-+				 size_t size, int *reset);
-+
-+extern int efi_capsule_update(efi_capsule_header_t *capsule,
-+			      struct page **pages);
- 
- #ifdef CONFIG_EFI_RUNTIME_MAP
- int efi_runtime_map_init(struct kobject *);
--- 
-2.12.0
-

+ 0 - 69
board/PSG/iot2000/linux-4.4-patches_orig/0012-x86-efi-Force-EFI-reboot-to-process-pending-capsules.patch

@@ -1,69 +0,0 @@
-From 6a03e25a705c8d59bb9a849b9eee13f04b0a7b1d Mon Sep 17 00:00:00 2001
-From: Matt Fleming <matt@codeblueprint.co.uk>
-Date: Mon, 25 Apr 2016 21:07:00 +0100
-Subject: [PATCH 12/27] x86/efi: Force EFI reboot to process pending capsules
-
-Commit 87615a34d561ef59bd0cffc73256a21220dfdffd upstream.
-
-If an EFI capsule has been sent to the firmware we must match the type
-of EFI reset against that required by the capsule to ensure it is
-processed correctly.
-
-Force an EFI reboot if a capsule is pending for the next reset.
-
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1461614832-17633-29-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- arch/x86/kernel/reboot.c | 9 +++++++++
- include/linux/efi.h      | 6 ++++++
- 2 files changed, 15 insertions(+)
-
-diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
-index f660d63f40fe..01d9e1edda07 100644
---- a/arch/x86/kernel/reboot.c
-+++ b/arch/x86/kernel/reboot.c
-@@ -535,6 +535,15 @@ static void native_machine_emergency_restart(void)
- 	mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0;
- 	*((unsigned short *)__va(0x472)) = mode;
- 
-+	/*
-+	 * If an EFI capsule has been registered with the firmware then
-+	 * override the reboot= parameter.
-+	 */
-+	if (efi_capsule_pending(NULL)) {
-+		pr_info("EFI capsule is pending, forcing EFI reboot.\n");
-+		reboot_type = BOOT_EFI;
-+	}
-+
- 	for (;;) {
- 		/* Could also try the reset bit in the Hammer NB */
- 		switch (reboot_type) {
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 848678a1cace..a1a41d027b93 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -1004,6 +1004,12 @@ static inline bool efi_enabled(int feature)
- }
- static inline void
- efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
-+
-+static inline bool
-+efi_capsule_pending(int *reset_type)
-+{
-+	return false;
-+}
- #endif
- 
- extern int efi_status_to_err(efi_status_t status);
--- 
-2.12.0
-

+ 0 - 425
board/PSG/iot2000/linux-4.4-patches_orig/0013-efi-Add-misc-char-driver-interface-to-update-EFI-fir.patch

@@ -1,425 +0,0 @@
-From d11fee242c86754daf76f76b6adab7ccddd1834e Mon Sep 17 00:00:00 2001
-From: "Kweh, Hock Leong" <hock.leong.kweh@intel.com>
-Date: Mon, 25 Apr 2016 21:07:01 +0100
-Subject: [PATCH 13/27] efi: Add misc char driver interface to update EFI
- firmware
-
-Commit 65117f1aa1b2d145fd5ca376bde642794d0aae1b upstream.
-
-This patch introduces a kernel module to expose a capsule loader
-interface (misc char device file note) for users to upload capsule
-binaries.
-
-Example:
-
-  cat firmware.bin > /dev/efi_capsule_loader
-
-Any upload error will be returned while doing "cat" through file
-operation write() function call.
-
-Signed-off-by: Kweh, Hock Leong <hock.leong.kweh@intel.com>
-[ Update comments and Kconfig text ]
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Reviewed-by: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc: Andy Lutomirski <luto@amacapital.net>
-Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Peter Jones <pjones@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Sam Protsenko <semen.protsenko@linaro.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1461614832-17633-30-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/Kconfig          |  10 +
- drivers/firmware/efi/Makefile         |   1 +
- drivers/firmware/efi/capsule-loader.c | 343 ++++++++++++++++++++++++++++++++++
- 3 files changed, 354 insertions(+)
- create mode 100644 drivers/firmware/efi/capsule-loader.c
-
-diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
-index e1670d533f97..de221bbde9c9 100644
---- a/drivers/firmware/efi/Kconfig
-+++ b/drivers/firmware/efi/Kconfig
-@@ -87,6 +87,16 @@ config EFI_RUNTIME_WRAPPERS
- config EFI_ARMSTUB
- 	bool
- 
-+config EFI_CAPSULE_LOADER
-+	tristate "EFI capsule loader"
-+	depends on EFI
-+	help
-+	  This option exposes a loader interface "/dev/efi_capsule_loader" for
-+	  users to load EFI capsules. This driver requires working runtime
-+	  capsule support in the firmware, which many OEMs do not provide.
-+
-+	  Most users should say N.
-+
- endmenu
- 
- config UEFI_CPER
-diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
-index 54b19cdbfcf8..2c8562de3a5f 100644
---- a/drivers/firmware/efi/Makefile
-+++ b/drivers/firmware/efi/Makefile
-@@ -19,3 +19,4 @@ obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
- obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
- obj-$(CONFIG_EFI_STUB)			+= libstub/
- obj-$(CONFIG_EFI_FAKE_MEMMAP)		+= fake_mem.o
-+obj-$(CONFIG_EFI_CAPSULE_LOADER)	+= capsule-loader.o
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-new file mode 100644
-index 000000000000..c99c24bc79b0
---- /dev/null
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -0,0 +1,343 @@
-+/*
-+ * EFI capsule loader driver.
-+ *
-+ * Copyright 2015 Intel Corporation
-+ *
-+ * This file is part of the Linux kernel, and is made available under
-+ * the terms of the GNU General Public License version 2.
-+ */
-+
-+#define pr_fmt(fmt) "efi: " fmt
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/miscdevice.h>
-+#include <linux/highmem.h>
-+#include <linux/slab.h>
-+#include <linux/mutex.h>
-+#include <linux/efi.h>
-+
-+#define NO_FURTHER_WRITE_ACTION -1
-+
-+struct capsule_info {
-+	bool		header_obtained;
-+	int		reset_type;
-+	long		index;
-+	size_t		count;
-+	size_t		total_size;
-+	struct page	**pages;
-+	size_t		page_bytes_remain;
-+};
-+
-+/**
-+ * efi_free_all_buff_pages - free all previous allocated buffer pages
-+ * @cap_info: pointer to current instance of capsule_info structure
-+ *
-+ *	In addition to freeing buffer pages, it flags NO_FURTHER_WRITE_ACTION
-+ *	to cease processing data in subsequent write(2) calls until close(2)
-+ *	is called.
-+ **/
-+static void efi_free_all_buff_pages(struct capsule_info *cap_info)
-+{
-+	while (cap_info->index > 0)
-+		__free_page(cap_info->pages[--cap_info->index]);
-+
-+	cap_info->index = NO_FURTHER_WRITE_ACTION;
-+}
-+
-+/**
-+ * efi_capsule_setup_info - obtain the efi capsule header in the binary and
-+ *			    setup capsule_info structure
-+ * @cap_info: pointer to current instance of capsule_info structure
-+ * @kbuff: a mapped first page buffer pointer
-+ * @hdr_bytes: the total received number of bytes for efi header
-+ **/
-+static ssize_t efi_capsule_setup_info(struct capsule_info *cap_info,
-+				      void *kbuff, size_t hdr_bytes)
-+{
-+	efi_capsule_header_t *cap_hdr;
-+	size_t pages_needed;
-+	int ret;
-+	void *temp_page;
-+
-+	/* Only process data block that is larger than efi header size */
-+	if (hdr_bytes < sizeof(efi_capsule_header_t))
-+		return 0;
-+
-+	/* Reset back to the correct offset of header */
-+	cap_hdr = kbuff - cap_info->count;
-+	pages_needed = ALIGN(cap_hdr->imagesize, PAGE_SIZE) >> PAGE_SHIFT;
-+
-+	if (pages_needed == 0) {
-+		pr_err("%s: pages count invalid\n", __func__);
-+		return -EINVAL;
-+	}
-+
-+	/* Check if the capsule binary supported */
-+	ret = efi_capsule_supported(cap_hdr->guid, cap_hdr->flags,
-+				    cap_hdr->imagesize,
-+				    &cap_info->reset_type);
-+	if (ret) {
-+		pr_err("%s: efi_capsule_supported() failed\n",
-+		       __func__);
-+		return ret;
-+	}
-+
-+	cap_info->total_size = cap_hdr->imagesize;
-+	temp_page = krealloc(cap_info->pages,
-+			     pages_needed * sizeof(void *),
-+			     GFP_KERNEL | __GFP_ZERO);
-+	if (!temp_page) {
-+		pr_debug("%s: krealloc() failed\n", __func__);
-+		return -ENOMEM;
-+	}
-+
-+	cap_info->pages = temp_page;
-+	cap_info->header_obtained = true;
-+
-+	return 0;
-+}
-+
-+/**
-+ * efi_capsule_submit_update - invoke the efi_capsule_update API once binary
-+ *			       upload done
-+ * @cap_info: pointer to current instance of capsule_info structure
-+ **/
-+static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
-+{
-+	int ret;
-+	void *cap_hdr_temp;
-+
-+	cap_hdr_temp = kmap(cap_info->pages[0]);
-+	if (!cap_hdr_temp) {
-+		pr_debug("%s: kmap() failed\n", __func__);
-+		return -EFAULT;
-+	}
-+
-+	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
-+	kunmap(cap_info->pages[0]);
-+	if (ret) {
-+		pr_err("%s: efi_capsule_update() failed\n", __func__);
-+		return ret;
-+	}
-+
-+	/* Indicate capsule binary uploading is done */
-+	cap_info->index = NO_FURTHER_WRITE_ACTION;
-+	pr_info("%s: Successfully upload capsule file with reboot type '%s'\n",
-+		__func__, !cap_info->reset_type ? "RESET_COLD" :
-+		cap_info->reset_type == 1 ? "RESET_WARM" :
-+		"RESET_SHUTDOWN");
-+	return 0;
-+}
-+
-+/**
-+ * efi_capsule_write - store the capsule binary and pass it to
-+ *		       efi_capsule_update() API
-+ * @file: file pointer
-+ * @buff: buffer pointer
-+ * @count: number of bytes in @buff
-+ * @offp: not used
-+ *
-+ *	Expectation:
-+ *	- A user space tool should start at the beginning of capsule binary and
-+ *	  pass data in sequentially.
-+ *	- Users should close and re-open this file note in order to upload more
-+ *	  capsules.
-+ *	- After an error returned, user should close the file and restart the
-+ *	  operation for the next try otherwise -EIO will be returned until the
-+ *	  file is closed.
-+ *	- An EFI capsule header must be located at the beginning of capsule
-+ *	  binary file and passed in as first block data of write operation.
-+ **/
-+static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
-+				 size_t count, loff_t *offp)
-+{
-+	int ret = 0;
-+	struct capsule_info *cap_info = file->private_data;
-+	struct page *page;
-+	void *kbuff = NULL;
-+	size_t write_byte;
-+
-+	if (count == 0)
-+		return 0;
-+
-+	/* Return error while NO_FURTHER_WRITE_ACTION is flagged */
-+	if (cap_info->index < 0)
-+		return -EIO;
-+
-+	/* Only alloc a new page when previous page is full */
-+	if (!cap_info->page_bytes_remain) {
-+		page = alloc_page(GFP_KERNEL);
-+		if (!page) {
-+			pr_debug("%s: alloc_page() failed\n", __func__);
-+			ret = -ENOMEM;
-+			goto failed;
-+		}
-+
-+		cap_info->pages[cap_info->index++] = page;
-+		cap_info->page_bytes_remain = PAGE_SIZE;
-+	}
-+
-+	page = cap_info->pages[cap_info->index - 1];
-+
-+	kbuff = kmap(page);
-+	if (!kbuff) {
-+		pr_debug("%s: kmap() failed\n", __func__);
-+		ret = -EFAULT;
-+		goto failed;
-+	}
-+	kbuff += PAGE_SIZE - cap_info->page_bytes_remain;
-+
-+	/* Copy capsule binary data from user space to kernel space buffer */
-+	write_byte = min_t(size_t, count, cap_info->page_bytes_remain);
-+	if (copy_from_user(kbuff, buff, write_byte)) {
-+		pr_debug("%s: copy_from_user() failed\n", __func__);
-+		ret = -EFAULT;
-+		goto fail_unmap;
-+	}
-+	cap_info->page_bytes_remain -= write_byte;
-+
-+	/* Setup capsule binary info structure */
-+	if (!cap_info->header_obtained) {
-+		ret = efi_capsule_setup_info(cap_info, kbuff,
-+					     cap_info->count + write_byte);
-+		if (ret)
-+			goto fail_unmap;
-+	}
-+
-+	cap_info->count += write_byte;
-+	kunmap(page);
-+
-+	/* Submit the full binary to efi_capsule_update() API */
-+	if (cap_info->header_obtained &&
-+	    cap_info->count >= cap_info->total_size) {
-+		if (cap_info->count > cap_info->total_size) {
-+			pr_err("%s: upload size exceeded header defined size\n",
-+			       __func__);
-+			ret = -EINVAL;
-+			goto failed;
-+		}
-+
-+		ret = efi_capsule_submit_update(cap_info);
-+		if (ret)
-+			goto failed;
-+	}
-+
-+	return write_byte;
-+
-+fail_unmap:
-+	kunmap(page);
-+failed:
-+	efi_free_all_buff_pages(cap_info);
-+	return ret;
-+}
-+
-+/**
-+ * efi_capsule_flush - called by file close or file flush
-+ * @file: file pointer
-+ * @id: not used
-+ *
-+ *	If a capsule is being partially uploaded then calling this function
-+ *	will be treated as upload termination and will free those completed
-+ *	buffer pages and -ECANCELED will be returned.
-+ **/
-+static int efi_capsule_flush(struct file *file, fl_owner_t id)
-+{
-+	int ret = 0;
-+	struct capsule_info *cap_info = file->private_data;
-+
-+	if (cap_info->index > 0) {
-+		pr_err("%s: capsule upload not complete\n", __func__);
-+		efi_free_all_buff_pages(cap_info);
-+		ret = -ECANCELED;
-+	}
-+
-+	return ret;
-+}
-+
-+/**
-+ * efi_capsule_release - called by file close
-+ * @inode: not used
-+ * @file: file pointer
-+ *
-+ *	We will not free successfully submitted pages since efi update
-+ *	requires data to be maintained across system reboot.
-+ **/
-+static int efi_capsule_release(struct inode *inode, struct file *file)
-+{
-+	struct capsule_info *cap_info = file->private_data;
-+
-+	kfree(cap_info->pages);
-+	kfree(file->private_data);
-+	file->private_data = NULL;
-+	return 0;
-+}
-+
-+/**
-+ * efi_capsule_open - called by file open
-+ * @inode: not used
-+ * @file: file pointer
-+ *
-+ *	Will allocate each capsule_info memory for each file open call.
-+ *	This provided the capability to support multiple file open feature
-+ *	where user is not needed to wait for others to finish in order to
-+ *	upload their capsule binary.
-+ **/
-+static int efi_capsule_open(struct inode *inode, struct file *file)
-+{
-+	struct capsule_info *cap_info;
-+
-+	cap_info = kzalloc(sizeof(*cap_info), GFP_KERNEL);
-+	if (!cap_info)
-+		return -ENOMEM;
-+
-+	cap_info->pages = kzalloc(sizeof(void *), GFP_KERNEL);
-+	if (!cap_info->pages) {
-+		kfree(cap_info);
-+		return -ENOMEM;
-+	}
-+
-+	file->private_data = cap_info;
-+
-+	return 0;
-+}
-+
-+static const struct file_operations efi_capsule_fops = {
-+	.owner = THIS_MODULE,
-+	.open = efi_capsule_open,
-+	.write = efi_capsule_write,
-+	.flush = efi_capsule_flush,
-+	.release = efi_capsule_release,
-+	.llseek = no_llseek,
-+};
-+
-+static struct miscdevice efi_capsule_misc = {
-+	.minor = MISC_DYNAMIC_MINOR,
-+	.name = "efi_capsule_loader",
-+	.fops = &efi_capsule_fops,
-+};
-+
-+static int __init efi_capsule_loader_init(void)
-+{
-+	int ret;
-+
-+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
-+		return -ENODEV;
-+
-+	ret = misc_register(&efi_capsule_misc);
-+	if (ret)
-+		pr_err("%s: Failed to register misc char file note\n",
-+		       __func__);
-+
-+	return ret;
-+}
-+module_init(efi_capsule_loader_init);
-+
-+static void __exit efi_capsule_loader_exit(void)
-+{
-+	misc_deregister(&efi_capsule_misc);
-+}
-+module_exit(efi_capsule_loader_exit);
-+
-+MODULE_DESCRIPTION("EFI capsule firmware binary loader");
-+MODULE_LICENSE("GPL v2");
--- 
-2.12.0
-

+ 0 - 130
board/PSG/iot2000/linux-4.4-patches_orig/0014-efi-capsule-Make-efi_capsule_pending-lockless.patch

@@ -1,130 +0,0 @@
-From 1aa79e59dad5141bc7e9f5ff12e1c2b361268314 Mon Sep 17 00:00:00 2001
-From: Matt Fleming <matt@codeblueprint.co.uk>
-Date: Fri, 6 May 2016 22:39:27 +0100
-Subject: [PATCH 14/27] efi/capsule: Make efi_capsule_pending() lockless
-
-Commit 62075e581802ea1842d5d3c490a7e46330bdb9e1 upstream.
-
-Taking a mutex in the reboot path is bogus because we cannot sleep
-with interrupts disabled, such as when rebooting due to panic(),
-
-  BUG: sleeping function called from invalid context at kernel/locking/mutex.c:97
-  in_atomic(): 0, irqs_disabled(): 1, pid: 7, name: rcu_sched
-  Call Trace:
-    dump_stack+0x63/0x89
-    ___might_sleep+0xd8/0x120
-    __might_sleep+0x49/0x80
-    mutex_lock+0x20/0x50
-    efi_capsule_pending+0x1d/0x60
-    native_machine_emergency_restart+0x59/0x280
-    machine_emergency_restart+0x19/0x20
-    emergency_restart+0x18/0x20
-    panic+0x1ba/0x217
-
-In this case all other CPUs will have been stopped by the time we
-execute the platform reboot code, so 'capsule_pending' cannot change
-under our feet. We wouldn't care even if it could since we cannot wait
-for it complete.
-
-Also, instead of relying on the external 'system_state' variable just
-use a reboot notifier, so we can set 'stop_capsules' while holding
-'capsule_mutex', thereby avoiding a race where system_state is updated
-while we're in the middle of efi_capsule_update_locked() (since CPUs
-won't have been stopped at that point).
-
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Cc: Andy Lutomirski <luto@amacapital.net>
-Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Brian Gerst <brgerst@gmail.com>
-Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-Cc: Denys Vlasenko <dvlasenk@redhat.com>
-Cc: H. Peter Anvin <hpa@zytor.com>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1462570771-13324-2-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/capsule.c | 35 +++++++++++++++++++++++++----------
- 1 file changed, 25 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
-index 0de55944ac0b..e530540f368c 100644
---- a/drivers/firmware/efi/capsule.c
-+++ b/drivers/firmware/efi/capsule.c
-@@ -22,11 +22,12 @@ typedef struct {
- } efi_capsule_block_desc_t;
- 
- static bool capsule_pending;
-+static bool stop_capsules;
- static int efi_reset_type = -1;
- 
- /*
-  * capsule_mutex serialises access to both capsule_pending and
-- * efi_reset_type.
-+ * efi_reset_type and stop_capsules.
-  */
- static DEFINE_MUTEX(capsule_mutex);
- 
-@@ -50,18 +51,13 @@ static DEFINE_MUTEX(capsule_mutex);
-  */
- bool efi_capsule_pending(int *reset_type)
- {
--	bool rv = false;
--
--	mutex_lock(&capsule_mutex);
- 	if (!capsule_pending)
--		goto out;
-+		return false;
- 
- 	if (reset_type)
- 		*reset_type = efi_reset_type;
--	rv = true;
--out:
--	mutex_unlock(&capsule_mutex);
--	return rv;
-+
-+	return true;
- }
- 
- /*
-@@ -176,7 +172,7 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule,
- 	 * whether to force an EFI reboot), and we're racing against
- 	 * that call. Abort in that case.
- 	 */
--	if (unlikely(system_state == SYSTEM_RESTART)) {
-+	if (unlikely(stop_capsules)) {
- 		pr_warn("Capsule update raced with reboot, aborting.\n");
- 		return -EINVAL;
- 	}
-@@ -298,3 +294,22 @@ out:
- 	return rv;
- }
- EXPORT_SYMBOL_GPL(efi_capsule_update);
-+
-+static int capsule_reboot_notify(struct notifier_block *nb, unsigned long event, void *cmd)
-+{
-+	mutex_lock(&capsule_mutex);
-+	stop_capsules = true;
-+	mutex_unlock(&capsule_mutex);
-+
-+	return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block capsule_reboot_nb = {
-+	.notifier_call = capsule_reboot_notify,
-+};
-+
-+static int __init capsule_reboot_register(void)
-+{
-+	return register_reboot_notifier(&capsule_reboot_nb);
-+}
-+core_initcall(capsule_reboot_register);
--- 
-2.12.0
-

+ 0 - 101
board/PSG/iot2000/linux-4.4-patches_orig/0015-efi-capsule-Move-capsule-to-the-stack-in-efi_capsule.patch

@@ -1,101 +0,0 @@
-From 13110f0357554bb359de56f7f330a7425557b044 Mon Sep 17 00:00:00 2001
-From: Matt Fleming <matt@codeblueprint.co.uk>
-Date: Fri, 6 May 2016 22:39:29 +0100
-Subject: [PATCH 15/27] efi/capsule: Move 'capsule' to the stack in
- efi_capsule_supported()
-
-Commit fb7a84cac03541f4da18dfa25b3f4767d4efc6fc upstream.
-
-Dan Carpenter reports that passing the address of the pointer to the
-kmalloc()'d memory for 'capsule' is dangerous:
-
- "drivers/firmware/efi/capsule.c:109 efi_capsule_supported()
-  warn: did you mean to pass the address of 'capsule'
-
-   108
-   109          status = efi.query_capsule_caps(&capsule, 1, &max_size, reset);
-                                                ^^^^^^^^
-  If we modify capsule inside this function call then at the end of the
-  function we aren't freeing the original pointer that we allocated."
-
-Ard Biesheuvel noted that we don't even need to call kmalloc() since the
-object we allocate isn't very big and doesn't need to persist after the
-function returns.
-
-Place 'capsule' on the stack instead.
-
-Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Andy Lutomirski <luto@amacapital.net>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Brian Gerst <brgerst@gmail.com>
-Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-Cc: Denys Vlasenko <dvlasenk@redhat.com>
-Cc: H. Peter Anvin <hpa@zytor.com>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: joeyli <jlee@suse.com>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1462570771-13324-4-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/capsule.c | 29 +++++++++++------------------
- 1 file changed, 11 insertions(+), 18 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
-index e530540f368c..53b9fd2293ee 100644
---- a/drivers/firmware/efi/capsule.c
-+++ b/drivers/firmware/efi/capsule.c
-@@ -86,33 +86,26 @@ bool efi_capsule_pending(int *reset_type)
-  */
- int efi_capsule_supported(efi_guid_t guid, u32 flags, size_t size, int *reset)
- {
--	efi_capsule_header_t *capsule;
-+	efi_capsule_header_t capsule;
-+	efi_capsule_header_t *cap_list[] = { &capsule };
- 	efi_status_t status;
- 	u64 max_size;
--	int rv = 0;
- 
- 	if (flags & ~EFI_CAPSULE_SUPPORTED_FLAG_MASK)
- 		return -EINVAL;
- 
--	capsule = kmalloc(sizeof(*capsule), GFP_KERNEL);
--	if (!capsule)
--		return -ENOMEM;
--
--	capsule->headersize = capsule->imagesize = sizeof(*capsule);
--	memcpy(&capsule->guid, &guid, sizeof(efi_guid_t));
--	capsule->flags = flags;
-+	capsule.headersize = capsule.imagesize = sizeof(capsule);
-+	memcpy(&capsule.guid, &guid, sizeof(efi_guid_t));
-+	capsule.flags = flags;
- 
--	status = efi.query_capsule_caps(&capsule, 1, &max_size, reset);
--	if (status != EFI_SUCCESS) {
--		rv = efi_status_to_err(status);
--		goto out;
--	}
-+	status = efi.query_capsule_caps(cap_list, 1, &max_size, reset);
-+	if (status != EFI_SUCCESS)
-+		return efi_status_to_err(status);
- 
- 	if (size > max_size)
--		rv = -ENOSPC;
--out:
--	kfree(capsule);
--	return rv;
-+		return -ENOSPC;
-+
-+	return 0;
- }
- EXPORT_SYMBOL_GPL(efi_capsule_supported);
- 
--- 
-2.12.0
-

+ 0 - 93
board/PSG/iot2000/linux-4.4-patches_orig/0016-efi-capsule-Allocate-whole-capsule-into-virtual-memo.patch

@@ -1,93 +0,0 @@
-From c5a04515ef38824a5f426e5d1b3f53ce2e34ceba Mon Sep 17 00:00:00 2001
-From: Austin Christ <austinwc@codeaurora.org>
-Date: Thu, 11 Aug 2016 11:42:00 +0100
-Subject: [PATCH 16/27] efi/capsule: Allocate whole capsule into virtual memory
-
-Commit 6862e6ad95e984991a6ceec592cf67831658f928 upstream.
-
-According to UEFI 2.6 section 7.5.3, the capsule should be in contiguous
-virtual memory and firmware may consume the capsule immediately. To
-correctly implement this functionality, the kernel driver needs to vmap
-the entire capsule at the time it is made available to firmware.
-
-The virtual allocation of the capsule update has been changed from kmap,
-which was only allocating the first page of the update, to vmap, and
-allocates the entire data payload.
-
-Signed-off-by: Austin Christ <austinwc@codeaurora.org>
-Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
-Cc: <stable@vger.kernel.org> # v4.7
-Cc: Andy Lutomirski <luto@kernel.org>
-Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Brian Gerst <brgerst@gmail.com>
-Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-Cc: Denys Vlasenko <dvlasenk@redhat.com>
-Cc: H. Peter Anvin <hpa@zytor.com>
-Cc: Josh Poimboeuf <jpoimboe@redhat.com>
-Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: linux-efi@vger.kernel.org
-Link: http://lkml.kernel.org/r/1470912120-22831-3-git-send-email-matt@codeblueprint.co.uk
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/firmware/efi/capsule-loader.c | 8 +++++---
- drivers/firmware/efi/capsule.c        | 6 +++---
- 2 files changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index c99c24bc79b0..9ae6c116c474 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -16,6 +16,7 @@
- #include <linux/slab.h>
- #include <linux/mutex.h>
- #include <linux/efi.h>
-+#include <linux/vmalloc.h>
- 
- #define NO_FURTHER_WRITE_ACTION -1
- 
-@@ -108,14 +109,15 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
- 	int ret;
- 	void *cap_hdr_temp;
- 
--	cap_hdr_temp = kmap(cap_info->pages[0]);
-+	cap_hdr_temp = vmap(cap_info->pages, cap_info->index,
-+			VM_MAP, PAGE_KERNEL);
- 	if (!cap_hdr_temp) {
--		pr_debug("%s: kmap() failed\n", __func__);
-+		pr_debug("%s: vmap() failed\n", __func__);
- 		return -EFAULT;
- 	}
- 
- 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
--	kunmap(cap_info->pages[0]);
-+	vunmap(cap_hdr_temp);
- 	if (ret) {
- 		pr_err("%s: efi_capsule_update() failed\n", __func__);
- 		return ret;
-diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
-index 53b9fd2293ee..6eedff45e6d7 100644
---- a/drivers/firmware/efi/capsule.c
-+++ b/drivers/firmware/efi/capsule.c
-@@ -190,9 +190,9 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule,
-  * map the capsule described by @capsule with its data in @pages and
-  * send it to the firmware via the UpdateCapsule() runtime service.
-  *
-- * @capsule must be a virtual mapping of the first page in @pages
-- * (@pages[0]) in the kernel address space. That is, a
-- * capsule_header_t that describes the entire contents of the capsule
-+ * @capsule must be a virtual mapping of the complete capsule update in the
-+ * kernel address space, as the capsule can be consumed immediately.
-+ * A capsule_header_t that describes the entire contents of the capsule
-  * must be at the start of the first data page.
-  *
-  * Even though this function will validate that the firmware supports
--- 
-2.12.0
-

+ 0 - 40
board/PSG/iot2000/linux-4.4-patches_orig/0017-efi-capsule-Fix-return-code-on-failing-kmap-vmap.patch

@@ -1,40 +0,0 @@
-From 986a04d80e757e09a5b69761c04af9443f44805d Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 24 Mar 2017 18:34:14 +0100
-Subject: [PATCH 17/27] efi/capsule: Fix return code on failing kmap/vmap
-
-If kmap or vmap fail, it means we ran out of memory. There are no
-user-provided addressed involved that would justify EFAULT.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 9ae6c116c474..91e91f7a8807 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -113,7 +113,7 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
- 			VM_MAP, PAGE_KERNEL);
- 	if (!cap_hdr_temp) {
- 		pr_debug("%s: vmap() failed\n", __func__);
--		return -EFAULT;
-+		return -ENOMEM;
- 	}
- 
- 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
-@@ -185,7 +185,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	kbuff = kmap(page);
- 	if (!kbuff) {
- 		pr_debug("%s: kmap() failed\n", __func__);
--		ret = -EFAULT;
-+		ret = -ENOMEM;
- 		goto failed;
- 	}
- 	kbuff += PAGE_SIZE - cap_info->page_bytes_remain;
--- 
-2.12.0
-

+ 0 - 70
board/PSG/iot2000/linux-4.4-patches_orig/0018-efi-capsule-Remove-pr_debug-on-ENOMEM-or-EFAULT.patch

@@ -1,70 +0,0 @@
-From 6a1dbce069aa3ff38d2ec6fedb37a7802e946ff2 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 24 Mar 2017 18:34:15 +0100
-Subject: [PATCH 18/27] efi/capsule: Remove pr_debug on ENOMEM or EFAULT
-
-Both cases are not worth a debug log message - the error code is telling
-enough.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 11 ++---------
- 1 file changed, 2 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 91e91f7a8807..7b57dda2417d 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -88,10 +88,8 @@ static ssize_t efi_capsule_setup_info(struct capsule_info *cap_info,
- 	temp_page = krealloc(cap_info->pages,
- 			     pages_needed * sizeof(void *),
- 			     GFP_KERNEL | __GFP_ZERO);
--	if (!temp_page) {
--		pr_debug("%s: krealloc() failed\n", __func__);
-+	if (!temp_page)
- 		return -ENOMEM;
--	}
- 
- 	cap_info->pages = temp_page;
- 	cap_info->header_obtained = true;
-@@ -111,10 +109,8 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
- 
- 	cap_hdr_temp = vmap(cap_info->pages, cap_info->index,
- 			VM_MAP, PAGE_KERNEL);
--	if (!cap_hdr_temp) {
--		pr_debug("%s: vmap() failed\n", __func__);
-+	if (!cap_hdr_temp)
- 		return -ENOMEM;
--	}
- 
- 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
- 	vunmap(cap_hdr_temp);
-@@ -171,7 +167,6 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	if (!cap_info->page_bytes_remain) {
- 		page = alloc_page(GFP_KERNEL);
- 		if (!page) {
--			pr_debug("%s: alloc_page() failed\n", __func__);
- 			ret = -ENOMEM;
- 			goto failed;
- 		}
-@@ -184,7 +179,6 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 
- 	kbuff = kmap(page);
- 	if (!kbuff) {
--		pr_debug("%s: kmap() failed\n", __func__);
- 		ret = -ENOMEM;
- 		goto failed;
- 	}
-@@ -193,7 +187,6 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	/* Copy capsule binary data from user space to kernel space buffer */
- 	write_byte = min_t(size_t, count, cap_info->page_bytes_remain);
- 	if (copy_from_user(kbuff, buff, write_byte)) {
--		pr_debug("%s: copy_from_user() failed\n", __func__);
- 		ret = -EFAULT;
- 		goto fail_unmap;
- 	}
--- 
-2.12.0
-

+ 0 - 88
board/PSG/iot2000/linux-4.4-patches_orig/0019-efi-capsule-Clean-up-pr_err-info-messages.patch

@@ -1,88 +0,0 @@
-From 99bed124420afaaa6aea9a80440e7fa80b27177b Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 24 Mar 2017 18:34:16 +0100
-Subject: [PATCH 19/27] efi/capsule: Clean up pr_err/info messages
-
-Avoid __func__, improve the information provided by some of the
-messages.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 19 ++++++++-----------
- 1 file changed, 8 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 7b57dda2417d..3fb91e1597a9 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -70,7 +70,7 @@ static ssize_t efi_capsule_setup_info(struct capsule_info *cap_info,
- 	pages_needed = ALIGN(cap_hdr->imagesize, PAGE_SIZE) >> PAGE_SHIFT;
- 
- 	if (pages_needed == 0) {
--		pr_err("%s: pages count invalid\n", __func__);
-+		pr_err("invalid capsule size");
- 		return -EINVAL;
- 	}
- 
-@@ -79,8 +79,7 @@ static ssize_t efi_capsule_setup_info(struct capsule_info *cap_info,
- 				    cap_hdr->imagesize,
- 				    &cap_info->reset_type);
- 	if (ret) {
--		pr_err("%s: efi_capsule_supported() failed\n",
--		       __func__);
-+		pr_err("capsule not supported\n");
- 		return ret;
- 	}
- 
-@@ -115,14 +114,14 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
- 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
- 	vunmap(cap_hdr_temp);
- 	if (ret) {
--		pr_err("%s: efi_capsule_update() failed\n", __func__);
-+		pr_err("capsule update failed\n");
- 		return ret;
- 	}
- 
- 	/* Indicate capsule binary uploading is done */
- 	cap_info->index = NO_FURTHER_WRITE_ACTION;
--	pr_info("%s: Successfully upload capsule file with reboot type '%s'\n",
--		__func__, !cap_info->reset_type ? "RESET_COLD" :
-+	pr_info("Successfully upload capsule file with reboot type '%s'\n",
-+		!cap_info->reset_type ? "RESET_COLD" :
- 		cap_info->reset_type == 1 ? "RESET_WARM" :
- 		"RESET_SHUTDOWN");
- 	return 0;
-@@ -207,8 +206,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	if (cap_info->header_obtained &&
- 	    cap_info->count >= cap_info->total_size) {
- 		if (cap_info->count > cap_info->total_size) {
--			pr_err("%s: upload size exceeded header defined size\n",
--			       __func__);
-+			pr_err("capsule upload size exceeded header defined size\n");
- 			ret = -EINVAL;
- 			goto failed;
- 		}
-@@ -242,7 +240,7 @@ static int efi_capsule_flush(struct file *file, fl_owner_t id)
- 	struct capsule_info *cap_info = file->private_data;
- 
- 	if (cap_info->index > 0) {
--		pr_err("%s: capsule upload not complete\n", __func__);
-+		pr_err("capsule upload not complete\n");
- 		efi_free_all_buff_pages(cap_info);
- 		ret = -ECANCELED;
- 	}
-@@ -321,8 +319,7 @@ static int __init efi_capsule_loader_init(void)
- 
- 	ret = misc_register(&efi_capsule_misc);
- 	if (ret)
--		pr_err("%s: Failed to register misc char file note\n",
--		       __func__);
-+		pr_err("Unable to register capsule loader device\n");
- 
- 	return ret;
- }
--- 
-2.12.0
-

+ 0 - 34
board/PSG/iot2000/linux-4.4-patches_orig/0020-efi-capsule-Adjust-return-type-of-efi_capsule_setup_.patch

@@ -1,34 +0,0 @@
-From 1bbe1e85d8f2dd2ad8ed3b120f04ea7f48d5a28e Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 24 Mar 2017 18:34:17 +0100
-Subject: [PATCH 20/27] efi/capsule: Adjust return type of
- efi_capsule_setup_info
-
-We actually expect int at the caller and never return any size
-information.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 3fb91e1597a9..37d3f6ec2d28 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -53,8 +53,8 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info)
-  * @kbuff: a mapped first page buffer pointer
-  * @hdr_bytes: the total received number of bytes for efi header
-  **/
--static ssize_t efi_capsule_setup_info(struct capsule_info *cap_info,
--				      void *kbuff, size_t hdr_bytes)
-+static int efi_capsule_setup_info(struct capsule_info *cap_info,
-+				  void *kbuff, size_t hdr_bytes)
- {
- 	efi_capsule_header_t *cap_hdr;
- 	size_t pages_needed;
--- 
-2.12.0
-

+ 0 - 128
board/PSG/iot2000/linux-4.4-patches_orig/0021-efi-capsule-loader-Use-a-cached-copy-of-the-capsule-.patch

@@ -1,128 +0,0 @@
-From bf59e06db6790038f4f4d25f641393d6e707907c Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Tue, 28 Mar 2017 12:49:56 +0100
-Subject: [PATCH 21/27] efi/capsule-loader: Use a cached copy of the capsule
- header
-
-Instead of kmapping the capsule data twice, copy the capsule header
-into the capsule info struct we keep locally. This is an improvement
-by itself, but will also enable handling of non-standard header formats
-more easily.
-
-Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 41 +++++++++++++++--------------------
- 1 file changed, 17 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 37d3f6ec2d28..5b012a467d7d 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -21,13 +21,13 @@
- #define NO_FURTHER_WRITE_ACTION -1
- 
- struct capsule_info {
--	bool		header_obtained;
--	int		reset_type;
--	long		index;
--	size_t		count;
--	size_t		total_size;
--	struct page	**pages;
--	size_t		page_bytes_remain;
-+	efi_capsule_header_t	header;
-+	int			reset_type;
-+	long			index;
-+	size_t			count;
-+	size_t			total_size;
-+	struct page		**pages;
-+	size_t			page_bytes_remain;
- };
- 
- /**
-@@ -56,7 +56,6 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info)
- static int efi_capsule_setup_info(struct capsule_info *cap_info,
- 				  void *kbuff, size_t hdr_bytes)
- {
--	efi_capsule_header_t *cap_hdr;
- 	size_t pages_needed;
- 	int ret;
- 	void *temp_page;
-@@ -66,8 +65,9 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- 		return 0;
- 
- 	/* Reset back to the correct offset of header */
--	cap_hdr = kbuff - cap_info->count;
--	pages_needed = ALIGN(cap_hdr->imagesize, PAGE_SIZE) >> PAGE_SHIFT;
-+	kbuff -= cap_info->count;
-+	memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
-+	pages_needed = ALIGN(cap_info->header.imagesize, PAGE_SIZE) / PAGE_SIZE;
- 
- 	if (pages_needed == 0) {
- 		pr_err("invalid capsule size");
-@@ -75,15 +75,16 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- 	}
- 
- 	/* Check if the capsule binary supported */
--	ret = efi_capsule_supported(cap_hdr->guid, cap_hdr->flags,
--				    cap_hdr->imagesize,
-+	ret = efi_capsule_supported(cap_info->header.guid,
-+				    cap_info->header.flags,
-+				    cap_info->header.imagesize,
- 				    &cap_info->reset_type);
- 	if (ret) {
- 		pr_err("capsule not supported\n");
- 		return ret;
- 	}
- 
--	cap_info->total_size = cap_hdr->imagesize;
-+	cap_info->total_size = cap_info->header.imagesize;
- 	temp_page = krealloc(cap_info->pages,
- 			     pages_needed * sizeof(void *),
- 			     GFP_KERNEL | __GFP_ZERO);
-@@ -91,7 +92,6 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- 		return -ENOMEM;
- 
- 	cap_info->pages = temp_page;
--	cap_info->header_obtained = true;
- 
- 	return 0;
- }
-@@ -104,15 +104,8 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
- {
- 	int ret;
--	void *cap_hdr_temp;
- 
--	cap_hdr_temp = vmap(cap_info->pages, cap_info->index,
--			VM_MAP, PAGE_KERNEL);
--	if (!cap_hdr_temp)
--		return -ENOMEM;
--
--	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
--	vunmap(cap_hdr_temp);
-+	ret = efi_capsule_update(&cap_info->header, cap_info->pages);
- 	if (ret) {
- 		pr_err("capsule update failed\n");
- 		return ret;
-@@ -192,7 +185,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	cap_info->page_bytes_remain -= write_byte;
- 
- 	/* Setup capsule binary info structure */
--	if (!cap_info->header_obtained) {
-+	if (cap_info->header.headersize == 0) {
- 		ret = efi_capsule_setup_info(cap_info, kbuff,
- 					     cap_info->count + write_byte);
- 		if (ret)
-@@ -203,7 +196,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 	kunmap(page);
- 
- 	/* Submit the full binary to efi_capsule_update() API */
--	if (cap_info->header_obtained &&
-+	if (cap_info->header.headersize > 0 &&
- 	    cap_info->count >= cap_info->total_size) {
- 		if (cap_info->count > cap_info->total_size) {
- 			pr_err("capsule upload size exceeded header defined size\n");
--- 
-2.12.0
-

+ 0 - 144
board/PSG/iot2000/linux-4.4-patches_orig/0022-efi-capsule-loader-Redirect-calls-to-efi_capsule_set.patch

@@ -1,144 +0,0 @@
-From cb0b223e1c31d240e6a883851fb84b66dc820cbf Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Tue, 28 Mar 2017 13:06:57 +0100
-Subject: [PATCH 22/27] efi/capsule-loader: Redirect calls to
- efi_capsule_setup_info via weak alias
-
-To allow platform specific code to hook into the capsule loading
-routines, indirect calls to efi_capsule_setup_info() via a weak alias
-of __efi_capsule_setup_info(), allowing platforms to redefine the former
-but still use the latter.
-
-Cc: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 56 +++++++++++++++++------------------
- include/linux/efi.h                   | 12 ++++++++
- 2 files changed, 39 insertions(+), 29 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index 5b012a467d7d..f7fdeab0bc37 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -20,16 +20,6 @@
- 
- #define NO_FURTHER_WRITE_ACTION -1
- 
--struct capsule_info {
--	efi_capsule_header_t	header;
--	int			reset_type;
--	long			index;
--	size_t			count;
--	size_t			total_size;
--	struct page		**pages;
--	size_t			page_bytes_remain;
--};
--
- /**
-  * efi_free_all_buff_pages - free all previous allocated buffer pages
-  * @cap_info: pointer to current instance of capsule_info structure
-@@ -46,28 +36,13 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info)
- 	cap_info->index = NO_FURTHER_WRITE_ACTION;
- }
- 
--/**
-- * efi_capsule_setup_info - obtain the efi capsule header in the binary and
-- *			    setup capsule_info structure
-- * @cap_info: pointer to current instance of capsule_info structure
-- * @kbuff: a mapped first page buffer pointer
-- * @hdr_bytes: the total received number of bytes for efi header
-- **/
--static int efi_capsule_setup_info(struct capsule_info *cap_info,
--				  void *kbuff, size_t hdr_bytes)
-+int __efi_capsule_setup_info(struct capsule_info *cap_info)
- {
- 	size_t pages_needed;
- 	int ret;
- 	void *temp_page;
- 
--	/* Only process data block that is larger than efi header size */
--	if (hdr_bytes < sizeof(efi_capsule_header_t))
--		return 0;
--
--	/* Reset back to the correct offset of header */
--	kbuff -= cap_info->count;
--	memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
--	pages_needed = ALIGN(cap_info->header.imagesize, PAGE_SIZE) / PAGE_SIZE;
-+	pages_needed = ALIGN(cap_info->total_size, PAGE_SIZE) / PAGE_SIZE;
- 
- 	if (pages_needed == 0) {
- 		pr_err("invalid capsule size");
-@@ -84,7 +59,6 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- 		return ret;
- 	}
- 
--	cap_info->total_size = cap_info->header.imagesize;
- 	temp_page = krealloc(cap_info->pages,
- 			     pages_needed * sizeof(void *),
- 			     GFP_KERNEL | __GFP_ZERO);
-@@ -97,6 +71,30 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info,
- }
- 
- /**
-+ * efi_capsule_setup_info - obtain the efi capsule header in the binary and
-+ *			    setup capsule_info structure
-+ * @cap_info: pointer to current instance of capsule_info structure
-+ * @kbuff: a mapped first page buffer pointer
-+ * @hdr_bytes: the total received number of bytes for efi header
-+ *
-+ * Platforms with non-standard capsule update mechanisms can override
-+ * this __weak function so they can perform any required capsule
-+ * image munging. See quark_quirk_function() for an example.
-+ **/
-+int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
-+				  size_t hdr_bytes)
-+{
-+	/* Only process data block that is larger than efi header size */
-+	if (hdr_bytes < sizeof(efi_capsule_header_t))
-+		return 0;
-+
-+	memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
-+	cap_info->total_size = cap_info->header.imagesize;
-+
-+	return __efi_capsule_setup_info(cap_info);
-+}
-+
-+/**
-  * efi_capsule_submit_update - invoke the efi_capsule_update API once binary
-  *			       upload done
-  * @cap_info: pointer to current instance of capsule_info structure
-@@ -186,7 +184,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 
- 	/* Setup capsule binary info structure */
- 	if (cap_info->header.headersize == 0) {
--		ret = efi_capsule_setup_info(cap_info, kbuff,
-+		ret = efi_capsule_setup_info(cap_info, kbuff - cap_info->count,
- 					     cap_info->count + write_byte);
- 		if (ret)
- 			goto fail_unmap;
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index a1a41d027b93..99d3f5bb9070 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -129,6 +129,18 @@ typedef struct {
- #define EFI_CAPSULE_POPULATE_SYSTEM_TABLE	0x00020000
- #define EFI_CAPSULE_INITIATE_RESET		0x00040000
- 
-+struct capsule_info {
-+	efi_capsule_header_t	header;
-+	int			reset_type;
-+	long			index;
-+	size_t			count;
-+	size_t			total_size;
-+	struct page		**pages;
-+	size_t			page_bytes_remain;
-+};
-+
-+int __efi_capsule_setup_info(struct capsule_info *cap_info);
-+
- /*
-  * Allocation types for calls to boottime->allocate_pages.
-  */
--- 
-2.12.0
-

+ 0 - 114
board/PSG/iot2000/linux-4.4-patches_orig/0023-efi-capsule-loader-Use-page-addresses-rather-than-st.patch

@@ -1,114 +0,0 @@
-From 30e7ad8198b22063c242d6f349d1e9d948e4d34d Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Tue, 28 Mar 2017 18:09:39 +0100
-Subject: [PATCH 23/27] efi/capsule-loader: Use page addresses rather than
- struct page pointers
-
-To give some leeway to code that handles non-standard capsule headers,
-let's keep an array of page addresses rather than struct page pointers.
-
-This gives special implementations of efi_capsule_setup_info() the
-opportunity to mangle the payload a bit before it is presented to the
-firmware, without putting any knowledge of the nature of such quirks
-into the generic code.
-
-Cc: Matt Fleming <matt@codeblueprint.co.uk>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/firmware/efi/capsule-loader.c | 12 ++++++++----
- drivers/firmware/efi/capsule.c        |  7 ++++---
- include/linux/efi.h                   |  4 ++--
- 3 files changed, 14 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
-index f7fdeab0bc37..feeafb673c07 100644
---- a/drivers/firmware/efi/capsule-loader.c
-+++ b/drivers/firmware/efi/capsule-loader.c
-@@ -20,6 +20,10 @@
- 
- #define NO_FURTHER_WRITE_ACTION -1
- 
-+#ifndef phys_to_page
-+#define phys_to_page(x)		pfn_to_page((x) >> PAGE_SHIFT)
-+#endif
-+
- /**
-  * efi_free_all_buff_pages - free all previous allocated buffer pages
-  * @cap_info: pointer to current instance of capsule_info structure
-@@ -31,7 +35,7 @@
- static void efi_free_all_buff_pages(struct capsule_info *cap_info)
- {
- 	while (cap_info->index > 0)
--		__free_page(cap_info->pages[--cap_info->index]);
-+		__free_page(phys_to_page(cap_info->pages[--cap_info->index]));
- 
- 	cap_info->index = NO_FURTHER_WRITE_ACTION;
- }
-@@ -161,12 +165,12 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
- 			goto failed;
- 		}
- 
--		cap_info->pages[cap_info->index++] = page;
-+		cap_info->pages[cap_info->index++] = page_to_phys(page);
- 		cap_info->page_bytes_remain = PAGE_SIZE;
-+	} else {
-+		page = phys_to_page(cap_info->pages[cap_info->index - 1]);
- 	}
- 
--	page = cap_info->pages[cap_info->index - 1];
--
- 	kbuff = kmap(page);
- 	if (!kbuff) {
- 		ret = -ENOMEM;
-diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
-index 6eedff45e6d7..57f85256feb2 100644
---- a/drivers/firmware/efi/capsule.c
-+++ b/drivers/firmware/efi/capsule.c
-@@ -214,7 +214,7 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule,
-  *
-  * Return 0 on success, a converted EFI status code on failure.
-  */
--int efi_capsule_update(efi_capsule_header_t *capsule, struct page **pages)
-+int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
- {
- 	u32 imagesize = capsule->imagesize;
- 	efi_guid_t guid = capsule->guid;
-@@ -253,10 +253,11 @@ int efi_capsule_update(efi_capsule_header_t *capsule, struct page **pages)
- 		}
- 
- 		for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
--			u64 sz = min_t(u64, imagesize, PAGE_SIZE);
-+			u64 sz = min_t(u64, imagesize,
-+				       PAGE_SIZE - (u64)*pages % PAGE_SIZE);
- 
- 			sglist[j].length = sz;
--			sglist[j].data = page_to_phys(*pages++);
-+			sglist[j].data = *pages++;
- 
- 			imagesize -= sz;
- 			count--;
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 99d3f5bb9070..3a67ce06f7f3 100644
---- a/include/linux/efi.h
-+++ b/include/linux/efi.h
-@@ -135,7 +135,7 @@ struct capsule_info {
- 	long			index;
- 	size_t			count;
- 	size_t			total_size;
--	struct page		**pages;
-+	phys_addr_t		*pages;
- 	size_t			page_bytes_remain;
- };
- 
-@@ -1245,7 +1245,7 @@ extern int efi_capsule_supported(efi_guid_t guid, u32 flags,
- 				 size_t size, int *reset);
- 
- extern int efi_capsule_update(efi_capsule_header_t *capsule,
--			      struct page **pages);
-+			      phys_addr_t *pages);
- 
- #ifdef CONFIG_EFI_RUNTIME_MAP
- int efi_runtime_map_init(struct kobject *);
--- 
-2.12.0
-

+ 0 - 202
board/PSG/iot2000/linux-4.4-patches_orig/0024-efi-capsule-Add-support-for-Quark-security-header.patch

@@ -1,202 +0,0 @@
-From b36534fedba5c188eefabf9a8fbbf4dd39495605 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 24 Mar 2017 18:34:20 +0100
-Subject: [PATCH 24/27] efi/capsule: Add support for Quark security header
-
-The firmware for Quark X102x prepends a security header to the capsule
-which is needed to support the mandatory secure boot on this processor.
-The header can be detected by checking for the "_CSH" signature and -
-to avoid any GUID conflict - validating its size field to contain the
-expected value. Then we need to look for the EFI header right after the
-security header and pass the real header to __efi_capsule_setup_info.
-
-To be minimal invasive and maximal safe, the quirk version of
-efi_capsule_identify_image is only effective on Quark processors.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- arch/x86/platform/efi/quirks.c | 137 +++++++++++++++++++++++++++++++++++++++++
- drivers/firmware/efi/Kconfig   |   9 +++
- 2 files changed, 146 insertions(+)
-
-diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
-index 1c7380da65ff..f0361323a805 100644
---- a/arch/x86/platform/efi/quirks.c
-+++ b/arch/x86/platform/efi/quirks.c
-@@ -10,12 +10,66 @@
- #include <linux/acpi.h>
- #include <asm/efi.h>
- #include <asm/uv/uv.h>
-+#include <asm/cpu_device_id.h>
- 
- #define EFI_MIN_RESERVE 5120
- 
- #define EFI_DUMMY_GUID \
- 	EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9)
- 
-+#define QUARK_CSH_SIGNATURE		0x5f435348	/* _CSH */
-+#define QUARK_SECURITY_HEADER_SIZE	0x400
-+
-+/*
-+ * Header prepended to the standard EFI capsule on Quark systems the are based
-+ * on Intel firmware BSP.
-+ * @csh_signature:	Unique identifier to sanity check signed module
-+ * 			presence ("_CSH").
-+ * @version:		Current version of CSH used. Should be one for Quark A0.
-+ * @modulesize:		Size of the entire module including the module header
-+ * 			and payload.
-+ * @security_version_number_index: Index of SVN to use for validation of signed
-+ * 			module.
-+ * @security_version_number: Used to prevent against roll back of modules.
-+ * @rsvd_module_id:	Currently unused for Clanton (Quark).
-+ * @rsvd_module_vendor:	Vendor Identifier. For Intel products value is
-+ * 			0x00008086.
-+ * @rsvd_date:		BCD representation of build date as yyyymmdd, where
-+ * 			yyyy=4 digit year, mm=1-12, dd=1-31.
-+ * @headersize:		Total length of the header including including any
-+ * 			padding optionally added by the signing tool.
-+ * @hash_algo:		What Hash is used in the module signing.
-+ * @cryp_algo:		What Crypto is used in the module signing.
-+ * @keysize:		Total length of the key data including including any
-+ * 			padding optionally added by the signing tool.
-+ * @signaturesize:	Total length of the signature including including any
-+ * 			padding optionally added by the signing tool.
-+ * @rsvd_next_header:	32-bit pointer to the next Secure Boot Module in the
-+ * 			chain, if there is a next header.
-+ * @rsvd:		Reserved, padding structure to required size.
-+ *
-+ * See also QuartSecurityHeader_t in
-+ * Quark_EDKII_v1.2.1.1/QuarkPlatformPkg/Include/QuarkBootRom.h
-+ * from https://downloadcenter.intel.com/download/23197/Intel-Quark-SoC-X1000-Board-Support-Package-BSP
-+ */
-+struct quark_security_header {
-+	u32 csh_signature;
-+	u32 version;
-+	u32 modulesize;
-+	u32 security_version_number_index;
-+	u32 security_version_number;
-+	u32 rsvd_module_id;
-+	u32 rsvd_module_vendor;
-+	u32 rsvd_date;
-+	u32 headersize;
-+	u32 hash_algo;
-+	u32 cryp_algo;
-+	u32 keysize;
-+	u32 signaturesize;
-+	u32 rsvd_next_header;
-+	u32 rsvd[2];
-+};
-+
- static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
- 
- static bool efi_no_storage_paranoia;
-@@ -288,3 +342,86 @@ bool efi_poweroff_required(void)
- {
- 	return !!acpi_gbl_reduced_hardware;
- }
-+
-+#ifdef CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH
-+
-+static int qrk_capsule_setup_info(struct capsule_info *cap_info, void **pkbuff,
-+				  size_t hdr_bytes)
-+{
-+	struct quark_security_header *csh = *pkbuff;
-+
-+	/* Only process data block that is larger than the security header */
-+	if (hdr_bytes < sizeof(struct quark_security_header))
-+		return 0;
-+
-+	if (csh->csh_signature != QUARK_CSH_SIGNATURE ||
-+	    csh->headersize != QUARK_SECURITY_HEADER_SIZE)
-+		return 1;
-+
-+	/* Only process data block if EFI header is included */
-+	if (hdr_bytes < QUARK_SECURITY_HEADER_SIZE +
-+			sizeof(efi_capsule_header_t))
-+		return 0;
-+
-+	pr_debug("Quark security header detected\n");
-+
-+	if (csh->rsvd_next_header != 0) {
-+		pr_err("multiple Quark security headers not supported\n");
-+		return -EINVAL;
-+	}
-+
-+	*pkbuff += csh->headersize;
-+	cap_info->total_size = csh->headersize;
-+
-+	/*
-+	 * Update the first page pointer to skip over the CSH header.
-+	 */
-+	cap_info->pages[0] += csh->headersize;
-+
-+	return 1;
-+}
-+
-+#define ICPU(family, model, quirk_handler) \
-+	{ X86_VENDOR_INTEL, family, model, X86_FEATURE_ANY, \
-+	  (unsigned long)&quirk_handler }
-+
-+static const struct x86_cpu_id efi_capsule_quirk_ids[] = {
-+	ICPU(5, 9, qrk_capsule_setup_info),	/* Intel Quark X1000 */
-+	{ }
-+};
-+
-+int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
-+			   size_t hdr_bytes)
-+{
-+	int (*quirk_handler)(struct capsule_info *, void **, size_t);
-+	const struct x86_cpu_id *id;
-+	int ret;
-+
-+	if (hdr_bytes < sizeof(efi_capsule_header_t))
-+		return 0;
-+
-+	cap_info->total_size = 0;
-+
-+	id = x86_match_cpu(efi_capsule_quirk_ids);
-+	if (id) {
-+		/*
-+		 * The quirk handler is supposed to return
-+		 *  - a value > 0 if the setup should continue, after advancing
-+		 *    kbuff as needed
-+		 *  - 0 if not enough hdr_bytes are available yet
-+		 *  - a negative error code otherwise
-+		 */
-+		quirk_handler = (typeof(quirk_handler))id->driver_data;
-+		ret = quirk_handler(cap_info, &kbuff, hdr_bytes);
-+		if (ret <= 0)
-+			return ret;
-+	}
-+
-+	memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
-+
-+	cap_info->total_size += cap_info->header.imagesize;
-+
-+	return __efi_capsule_setup_info(cap_info);
-+}
-+
-+#endif
-diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
-index de221bbde9c9..8dfeee3b9e54 100644
---- a/drivers/firmware/efi/Kconfig
-+++ b/drivers/firmware/efi/Kconfig
-@@ -97,6 +97,15 @@ config EFI_CAPSULE_LOADER
- 
- 	  Most users should say N.
- 
-+config EFI_CAPSULE_QUIRK_QUARK_CSH
-+	boolean "Add support for Quark capsules with non-standard headers"
-+	depends on X86 && !64BIT
-+	select EFI_CAPSULE_LOADER
-+	default y
-+	help
-+	  Add support for processing Quark X1000 EFI capsules, whose header
-+	  layout deviates from the layout mandated by the UEFI specification.
-+
- endmenu
- 
- config UEFI_CPER
--- 
-2.12.0
-

+ 0 - 77
board/PSG/iot2000/linux-4.4-patches_orig/0025-mfd-intel_quark_i2c_gpio-Use-dmi_system_id-table-for.patch

@@ -1,77 +0,0 @@
-From 81d39fbfbb4db3eab29c54c07ae79be1a24db599 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Sun, 21 May 2017 12:43:16 +0200
-Subject: [PATCH 25/27] mfd: intel_quark_i2c_gpio: Use dmi_system_id table for
- retrieving frequency
-
-Avoids reimplementation of DMI matching in intel_quark_i2c_setup.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/mfd/intel_quark_i2c_gpio.c | 33 +++++++++++++--------------------
- 1 file changed, 13 insertions(+), 20 deletions(-)
-
-diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
-index 042137465300..57d4396dab5d 100644
---- a/drivers/mfd/intel_quark_i2c_gpio.c
-+++ b/drivers/mfd/intel_quark_i2c_gpio.c
-@@ -60,19 +60,18 @@ struct intel_quark_mfd {
- 	struct clk_lookup	*i2c_clk_lookup;
- };
- 
--struct i2c_mode_info {
--	const char *name;
--	unsigned int i2c_scl_freq;
--};
--
--static const struct i2c_mode_info platform_i2c_mode_info[] = {
-+static const struct dmi_system_id dmi_platform_info[] = {
- 	{
--		.name = "Galileo",
--		.i2c_scl_freq = 100000,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
-+		},
-+		.driver_data = (void *)100000,
- 	},
- 	{
--		.name = "GalileoGen2",
--		.i2c_scl_freq = 400000,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
-+		},
-+		.driver_data = (void *)400000,
- 	},
- 	{}
- };
-@@ -167,8 +166,7 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
- 
- static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
- {
--	const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
--	const struct i2c_mode_info *info;
-+	const struct dmi_system_id *dmi_id;
- 	struct dw_i2c_platform_data *pdata;
- 	struct resource *res = (struct resource *)cell->resources;
- 	struct device *dev = &pdev->dev;
-@@ -188,14 +186,9 @@ static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
- 	/* Normal mode by default */
- 	pdata->i2c_scl_freq = 100000;
- 
--	if (board_name) {
--		for (info = platform_i2c_mode_info; info->name; info++) {
--			if (!strcmp(board_name, info->name)) {
--				pdata->i2c_scl_freq = info->i2c_scl_freq;
--				break;
--			}
--		}
--	}
-+	dmi_id = dmi_first_match(dmi_platform_info);
-+	if (dmi_id)
-+		pdata->i2c_scl_freq = (uintptr_t)dmi_id->driver_data;
- 
- 	cell->platform_data = pdata;
- 	cell->pdata_size = sizeof(*pdata);
--- 
-2.12.0
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-patches_orig/0026-mfd-intel_quark_i2c_gpio-Add-support-for-SIMATIC-IOT.patch

@@ -1,45 +0,0 @@
-From 2b8b5ae2e33e47057261aa0f5bb38b6b6e69bcee Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Sat, 6 May 2017 07:10:36 +0200
-Subject: [PATCH 26/27] mfd: intel_quark_i2c_gpio: Add support for SIMATIC
- IOT2000 platform
-
-The SIMATIC IOT2020 and IOT2040 are derived from the Galileo Gen2 board
-and share its I2C frequency.
-
-Signed-off-by: Sascha Weisenberger <sascha.weisenberger@siemens.com>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/mfd/intel_quark_i2c_gpio.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
-index 57d4396dab5d..1c09604978d3 100644
---- a/drivers/mfd/intel_quark_i2c_gpio.c
-+++ b/drivers/mfd/intel_quark_i2c_gpio.c
-@@ -73,6 +73,22 @@ static const struct dmi_system_id dmi_platform_info[] = {
- 		},
- 		.driver_data = (void *)400000,
- 	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-0YA2"),
-+		},
-+		.driver_data = (void *)400000,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-1YA2"),
-+		},
-+		.driver_data = (void *)400000,
-+	},
- 	{}
- };
- 
--- 
-2.12.0
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-patches_orig/0027-iot2000-hack-Work-around-DSDT-mistake.patch

@@ -1,44 +0,0 @@
-From c9125348a22f695fa543c96e8f6beca8cb26d6d7 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 25 May 2017 11:09:42 +0200
-Subject: [PATCH 27/27] iot2000-hack: Work around DSDT mistake
-
-Until we have a new firmware revision, fix up the incorrect GPIO
-interrupt pin in software.
-
-Nothing for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpiolib-acpi.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
-index cbbb67a6f1d6..ec1a092e9911 100644
---- a/drivers/gpio/gpiolib-acpi.c
-+++ b/drivers/gpio/gpiolib-acpi.c
-@@ -10,6 +10,7 @@
-  * published by the Free Software Foundation.
-  */
- 
-+#include <linux/dmi.h>
- #include <linux/errno.h>
- #include <linux/gpio.h>
- #include <linux/gpio/consumer.h>
-@@ -408,6 +409,13 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
- 		if (pin_index >= agpio->pin_table_length)
- 			return 1;
- 
-+		if (!strcmp(dmi_get_system_info(DMI_BOARD_NAME),
-+			    "SIMATIC IOT2000") &&
-+		    !strcmp(agpio->resource_source.string_ptr,
-+			    "\\_SB.PCI0.GIP0.GPO") &&
-+		    agpio->pin_table[pin_index] == 9)
-+			agpio->pin_table[pin_index] = 1;
-+
- 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
- 					      agpio->pin_table[pin_index]);
- 		lookup->info.gpioint =
--- 
-2.12.0
-

+ 0 - 95
board/PSG/iot2000/linux-4.4-patches_orig/0028-gpio-pca953x-provide-GPIO-base-based-on-_UID.patch

@@ -1,95 +0,0 @@
-From 81e166ec0a35ed5a01e2453603b0b1c73a0532cc Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Fri, 19 Feb 2016 07:18:26 -0800
-Subject: [PATCH 2/6] gpio: pca953x: provide GPIO base based on _UID
-
-Custom kernel for Intel Galileo Gen2 provides and moreover libmraa relies on
-the continuous GPIO space. To do such we have to configure GPIO base per each
-GPIO expander. The only value we can use is the ACPI _UID.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-
-Upstream-status: Inappropriate, custom code for legacy userspace
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/gpio/gpio-pca953x.c | 44 +++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 37 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index 2d4892cc70fb..f23a4b4c26a2 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -77,12 +77,6 @@ static const struct i2c_device_id pca953x_id[] = {
- };
- MODULE_DEVICE_TABLE(i2c, pca953x_id);
- 
--static const struct acpi_device_id pca953x_acpi_ids[] = {
--	{ "INT3491", 16 | PCA953X_TYPE | PCA_INT, },
--	{ }
--};
--MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
--
- #define MAX_BANK 5
- #define BANK_SZ 8
- 
-@@ -109,6 +103,35 @@ struct pca953x_chip {
- 	unsigned long driver_data;
- };
- 
-+struct pca953x_info {
-+	kernel_ulong_t driver_data;
-+	void (*setup)(struct pca953x_chip *chip);
-+};
-+
-+static void pca953x_setup_int3491(struct pca953x_chip *chip)
-+{
-+	struct acpi_device *adev = ACPI_COMPANION(&chip->client->dev);
-+	unsigned int uid;
-+
-+	if (kstrtouint(acpi_device_uid(adev), 0, &uid) || !uid--)
-+		return;
-+
-+	chip->gpio_start = 8 /* sch_gpio */ +
-+			   8 /* gpio-dwapb */ +
-+			  16 /* pca9535 */ * uid;
-+}
-+
-+static const struct pca953x_info pca953x_info_int3491 = {
-+	.driver_data = 16 | PCA953X_TYPE | PCA_INT,
-+	.setup = pca953x_setup_int3491,
-+};
-+
-+static const struct acpi_device_id pca953x_acpi_ids[] = {
-+	{ "INT3491",  (kernel_ulong_t)&pca953x_info_int3491 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
-+
- static inline struct pca953x_chip *to_pca(struct gpio_chip *gc)
- {
- 	return container_of(gc, struct pca953x_chip, gpio_chip);
-@@ -691,12 +714,19 @@ static int pca953x_probe(struct i2c_client *client,
- 		chip->driver_data = id->driver_data;
- 	} else {
- 		const struct acpi_device_id *id;
-+		const struct pca953x_info *info;
- 
- 		id = acpi_match_device(pca953x_acpi_ids, &client->dev);
- 		if (!id)
- 			return -ENODEV;
- 
--		chip->driver_data = id->driver_data;
-+		info = (struct pca953x_info *)id->driver_data;
-+		if (!info)
-+			return -ENODEV;
-+
-+		chip->driver_data = info->driver_data;
-+		if (info->setup)
-+			info->setup(chip);
- 	}
- 
- 	chip->chip_type = PCA_CHIP_TYPE(chip->driver_data);
--- 
-2.5.0
-

+ 0 - 497
board/PSG/iot2000/linux-4.4-patches_orig/0029-staging-iio-add-support-for-ADC1x8s102.patch

@@ -1,497 +0,0 @@
-From 903003b78c132f74a84e9bb722aac1c6af49825f Mon Sep 17 00:00:00 2001
-From: Todor Minchev <todor@minchev.co.uk>
-Date: Fri, 19 Feb 2016 07:18:29 -0800
-Subject: [PATCH 5/6] staging:iio: add support for ADC1x8s102.
-
-Adds new config and support for Texas Instruments ADC1x8S102 driver"
-
-config ADC1x8S102
-	tristate "Texas Instruments ADC1x8S102 driver"
-	depends on SPI
-	select IIO_BUFFER
-	select IIO_TRIGGERED_BUFFER
-	help
-		Say yes here to build support for Texas Instruments ADC1x8S102 ADC.
-		Provides direct access via sysfs.
-
-		To compile this driver as a module, choose M here: the module will
-		be called adc1x8s102
-
-Upstream-status: Forward-ported from Intel IOT Develper Kit Quark BSP
-
-Original author is Bogdan Pricop <bogdan.pricop@emutex.com>.
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/staging/iio/adc/Kconfig          |  13 ++
- drivers/staging/iio/adc/Makefile         |   1 +
- drivers/staging/iio/adc/adc1x8s102.c     | 387 +++++++++++++++++++++++++++++++
- include/linux/platform_data/adc1x8s102.h |  30 +++
- 4 files changed, 431 insertions(+)
- create mode 100644 drivers/staging/iio/adc/adc1x8s102.c
- create mode 100644 include/linux/platform_data/adc1x8s102.h
-
-diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
-index 94ae4232ee77..537c78540457 100644
---- a/drivers/staging/iio/adc/Kconfig
-+++ b/drivers/staging/iio/adc/Kconfig
-@@ -115,4 +115,17 @@ config SPEAR_ADC
- 
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called spear_adc.
-+
-+config ADC1x8S102
-+	tristate "Texas Instruments ADC1x8S102 driver"
-+	depends on SPI
-+	select IIO_BUFFER
-+	select IIO_TRIGGERED_BUFFER
-+	help
-+		Say yes here to build support for Texas Instruments ADC1x8S102 ADC.
-+		Provides direct access via sysfs.
-+
-+		To compile this driver as a module, choose M here: the module will
-+		be called adc1x8s102
-+
- endmenu
-diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
-index 1c4277dbd318..3fe38805581c 100644
---- a/drivers/staging/iio/adc/Makefile
-+++ b/drivers/staging/iio/adc/Makefile
-@@ -15,3 +15,4 @@ obj-$(CONFIG_AD7280) += ad7280a.o
- obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
- obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
- obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
-+obj-$(CONFIG_ADC1x8S102) += adc1x8s102.o
-diff --git a/drivers/staging/iio/adc/adc1x8s102.c b/drivers/staging/iio/adc/adc1x8s102.c
-new file mode 100644
-index 000000000000..52472e21823c
---- /dev/null
-+++ b/drivers/staging/iio/adc/adc1x8s102.c
-@@ -0,0 +1,387 @@
-+/*
-+ * ADC1x8S102 SPI ADC driver
-+ *
-+ * Copyright(c) 2013 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ * This IIO device driver is is designed to work with the following
-+ * analog to digital converters from Texas Instruments:
-+ *  ADC108S102
-+ *  ADC128S102
-+ * The communication with ADC chip is via the SPI bus (mode 3).
-+ */
-+
-+
-+#include <linux/iio/iio.h>
-+#include <linux/iio/buffer.h>
-+#include <linux/iio/types.h>
-+#include <linux/iio/triggered_buffer.h>
-+#include <linux/iio/trigger_consumer.h>
-+
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/spi/spi.h>
-+
-+#include <linux/platform_data/adc1x8s102.h>
-+#include <linux/regulator/consumer.h>
-+
-+/*
-+ * Defining the ADC resolution being 12 bits, we can use the same driver for
-+ * both ADC108S102 (10 bits resolution) and ADC128S102 (12 bits resolution)
-+ * chips. The ADC108S102 effectively returns a 12-bit result with the 2
-+ * least-significant bits unset.
-+ */
-+#define ADC1x8S102_BITS		12
-+#define ADC1x8S102_MAX_CHANNELS	8
-+
-+/* 16-bit SPI command format:
-+ *   [15:14] Ignored
-+ *   [13:11] 3-bit channel address
-+ *   [10:0]  Ignored
-+ */
-+#define ADC1x8S102_CMD(ch)		(((ch) << (8)) << (3))
-+
-+/*
-+ * 16-bit SPI response format:
-+ *   [15:12] Zeros
-+ *   [11:0]  12-bit ADC sample (for ADC108S102, [1:0] will always be 0).
-+ */
-+#define ADC1x8S102_RES_DATA(res)	(res & ((1 << ADC1x8S102_BITS) - 1))
-+
-+struct adc1x8s102_state {
-+	struct spi_device		*spi;
-+	struct regulator		*reg;
-+	u16				ext_vin;
-+	/* SPI transfer used by triggered buffer handler*/
-+	struct spi_transfer		ring_xfer;
-+	/* SPI transfer used by direct scan */
-+	struct spi_transfer		scan_single_xfer;
-+	/* SPI message used by ring_xfer SPI transfer */
-+	struct spi_message		ring_msg;
-+	/* SPI message used by scan_single_xfer SPI transfer */
-+	struct spi_message		scan_single_msg;
-+
-+	/* SPI message buffers:
-+	 *  tx_buf: |C0|C1|C2|C3|C4|C5|C6|C7|XX|
-+	 *  rx_buf: |XX|R0|R1|R2|R3|R4|R5|R6|R7|tt|tt|tt|tt|
-+	 *
-+	 *  tx_buf: 8 channel read commands, plus 1 dummy command
-+	 *  rx_buf: 1 dummy response, 8 channel responses, plus 64-bit timestamp
-+	 */
-+	__be16				rx_buf[13] ____cacheline_aligned;
-+	__be16				tx_buf[9];
-+
-+};
-+
-+#define ADC1X8S102_V_CHAN(index)					\
-+	{								\
-+		.type = IIO_VOLTAGE,					\
-+		.indexed = 1,						\
-+		.channel = index,					\
-+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
-+			BIT(IIO_CHAN_INFO_SCALE),		\
-+		.address = index,					\
-+		.scan_index = index,					\
-+		.scan_type = {						\
-+			.sign = 'u',					\
-+			.realbits = ADC1x8S102_BITS,			\
-+			.storagebits = 16,				\
-+			.endianness = IIO_BE,				\
-+		},							\
-+	}
-+
-+static const struct iio_chan_spec adc1x8s102_channels[] = {
-+	ADC1X8S102_V_CHAN(0),
-+	ADC1X8S102_V_CHAN(1),
-+	ADC1X8S102_V_CHAN(2),
-+	ADC1X8S102_V_CHAN(3),
-+	ADC1X8S102_V_CHAN(4),
-+	ADC1X8S102_V_CHAN(5),
-+	ADC1X8S102_V_CHAN(6),
-+	ADC1X8S102_V_CHAN(7),
-+	IIO_CHAN_SOFT_TIMESTAMP(8),
-+};
-+
-+
-+static int adc1x8s102_update_scan_mode(struct iio_dev *indio_dev,
-+		unsigned long const *active_scan_mask)
-+{
-+	struct adc1x8s102_state *st;
-+	int i, j;
-+
-+	st = iio_priv(indio_dev);
-+
-+	/* Fill in the first x shorts of tx_buf with the number of channels
-+	 * enabled for sampling by the triggered buffer
-+	 */
-+	for (i = 0, j = 0; i < ADC1x8S102_MAX_CHANNELS; i++) {
-+		if (test_bit(i, active_scan_mask)) {
-+			st->tx_buf[j] = cpu_to_be16(ADC1x8S102_CMD(i));
-+			j++;
-+		}
-+	}
-+	/* One dummy command added, to clock in the last response */
-+	st->tx_buf[j] = 0x00;
-+
-+	/* build SPI ring message */
-+	st->ring_xfer.tx_buf = &st->tx_buf[0];
-+	st->ring_xfer.rx_buf = &st->rx_buf[0];
-+	st->ring_xfer.len = (j + 1) * sizeof(__be16);
-+
-+	spi_message_init(&st->ring_msg);
-+	spi_message_add_tail(&st->ring_xfer, &st->ring_msg);
-+
-+	return 0;
-+}
-+
-+
-+static irqreturn_t adc1x8s102_trigger_handler(int irq, void *p)
-+{
-+	struct iio_poll_func *pf = p;
-+	struct iio_dev *indio_dev;
-+	struct adc1x8s102_state *st;
-+	s64 time_ns = 0;
-+	int b_sent;
-+
-+	indio_dev = pf->indio_dev;
-+	st = iio_priv(indio_dev);
-+
-+	b_sent = spi_sync(st->spi, &st->ring_msg);
-+	if (b_sent)
-+		goto done;
-+	if (indio_dev->scan_timestamp) {
-+		time_ns = iio_get_time_ns();
-+		memcpy((u8 *)st->rx_buf + st->ring_xfer.len, &time_ns,
-+				sizeof(time_ns));
-+	}
-+
-+	/* Skip the dummy response in the first slot */
-+	iio_push_to_buffers(indio_dev, (u8 *)&st->rx_buf[1]);
-+done:
-+	iio_trigger_notify_done(indio_dev->trig);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+
-+/*
-+ * returns:
-+ * positive (>=0)  value => SUCCESS
-+ * negative value => FAILURE
-+ */
-+static int adc1x8s102_scan_direct(struct adc1x8s102_state *st, unsigned ch)
-+{
-+	int ret;
-+
-+	if (ch >= ADC1x8S102_MAX_CHANNELS) {
-+		dev_err(&st->spi->dev, "AD channel number too big: %u\n", ch);
-+		return -1;
-+	}
-+
-+	st->tx_buf[0] = cpu_to_be16(ADC1x8S102_CMD(ch));
-+	ret = spi_sync(st->spi, &st->scan_single_msg);
-+	if (ret)
-+		return ret;
-+
-+	/* Skip the dummy response in the first slot */
-+	return be16_to_cpu(st->rx_buf[1]);
-+}
-+
-+
-+/*
-+ * returns:
-+ * positive (>=0)  value => SUCCESS
-+ * negative value => FAILURE
-+ */
-+static int adc1x8s102_read_raw(struct iio_dev *indio_dev,
-+			   struct iio_chan_spec const *chan,
-+			   int *val,
-+			   int *val2,
-+			   long m)
-+{
-+	int ret;
-+	struct adc1x8s102_state *st;
-+
-+	st = iio_priv(indio_dev);
-+
-+	switch (m) {
-+	case IIO_CHAN_INFO_RAW:
-+		mutex_lock(&indio_dev->mlock);
-+		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
-+			ret = -EBUSY;
-+			dev_warn(&st->spi->dev,
-+			 "indio_dev->currentmode is INDIO_BUFFER_TRIGGERED\n");
-+		} else {
-+			ret = adc1x8s102_scan_direct(st, chan->address);
-+		}
-+		mutex_unlock(&indio_dev->mlock);
-+
-+		if (ret < 0)
-+			return ret;
-+		*val = ADC1x8S102_RES_DATA(ret);
-+
-+		return IIO_VAL_INT;
-+	case IIO_CHAN_INFO_SCALE:
-+		switch (chan->type) {
-+		case IIO_VOLTAGE:
-+			if (NULL != st->reg)
-+				*val = regulator_get_voltage(st->reg) / 1000;
-+			else
-+				*val = st->ext_vin;
-+
-+			*val2 = chan->scan_type.realbits;
-+			return IIO_VAL_FRACTIONAL_LOG2;
-+		default:
-+			dev_warn(&st->spi->dev,
-+				 "Invalid channel type %u for channel %d\n",
-+				 chan->type, chan->channel);
-+			return -EINVAL;
-+		}
-+	default:
-+		dev_warn(&st->spi->dev, "Invalid IIO_CHAN_INFO: %lu\n", m);
-+		return -EINVAL;
-+	}
-+}
-+
-+
-+
-+static const struct iio_info adc1x8s102_info = {
-+	.read_raw		= &adc1x8s102_read_raw,
-+	.update_scan_mode	= &adc1x8s102_update_scan_mode,
-+	.driver_module		= THIS_MODULE,
-+};
-+
-+
-+static int adc1x8s102_probe(struct spi_device *spi)
-+{
-+	struct adc1x8s102_platform_data *pdata = spi->dev.platform_data;
-+	struct adc1x8s102_state *st;
-+	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
-+	int ret;
-+
-+	if (NULL == indio_dev) {
-+		dev_crit(&spi->dev, "Cannot allocate memory for indio_dev\n");
-+		return -ENOMEM;
-+	}
-+
-+	st = iio_priv(indio_dev);
-+	if (NULL == pdata) {
-+		dev_err(&spi->dev, "Cannot get adc1x8s102 platform data\n");
-+		return -EFAULT;
-+	}
-+	st->ext_vin = pdata->ext_vin;
-+
-+	/* Use regulator, if available. */
-+	st->reg = regulator_get(&spi->dev, "vref");
-+	if (IS_ERR(st->reg)) {
-+		ret = PTR_ERR(st->reg);
-+		dev_warn(&spi->dev,
-+			 "Cannot get 'vref' regulator\n");
-+		goto error_free;
-+	}
-+	ret = regulator_enable(st->reg);
-+	if (ret < 0) {
-+		dev_warn(&spi->dev,
-+			 "Cannot enable vref regulator\n");
-+		goto error_put_reg;
-+	}
-+
-+	spi_set_drvdata(spi, indio_dev);
-+	st->spi = spi;
-+
-+	indio_dev->name = spi_get_device_id(spi)->name;
-+	indio_dev->dev.parent = &spi->dev;
-+	indio_dev->modes = INDIO_DIRECT_MODE;
-+	indio_dev->channels = adc1x8s102_channels;
-+	indio_dev->num_channels = ARRAY_SIZE(adc1x8s102_channels);
-+	indio_dev->info = &adc1x8s102_info;
-+
-+	/* Setup default message */
-+	st->scan_single_xfer.tx_buf = st->tx_buf;
-+	st->scan_single_xfer.rx_buf = st->rx_buf;
-+	st->scan_single_xfer.len = 2 * sizeof(__be16);
-+	st->scan_single_xfer.cs_change = 0;
-+
-+	spi_message_init(&st->scan_single_msg);
-+	spi_message_add_tail(&st->scan_single_xfer, &st->scan_single_msg);
-+
-+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
-+			&adc1x8s102_trigger_handler, NULL);
-+	if (ret)
-+		goto error_disable_reg;
-+
-+	ret = iio_device_register(indio_dev);
-+	if (ret) {
-+		dev_err(&spi->dev,
-+			"Failed to register IIO device\n");
-+		goto error_cleanup_ring;
-+	}
-+	return 0;
-+
-+error_cleanup_ring:
-+	iio_triggered_buffer_cleanup(indio_dev);
-+error_disable_reg:
-+	regulator_disable(st->reg);
-+error_put_reg:
-+	regulator_put(st->reg);
-+error_free:
-+	iio_device_free(indio_dev);
-+
-+	return ret;
-+}
-+
-+
-+static int adc1x8s102_remove(struct spi_device *spi)
-+{
-+	struct iio_dev *indio_dev;
-+	struct adc1x8s102_state *st;
-+
-+	indio_dev = spi_get_drvdata(spi);
-+	if (NULL == indio_dev) {
-+		dev_err(&spi->dev, "Cannot get spi_device drvdata\n");
-+		return -EFAULT;
-+	}
-+
-+	st = iio_priv(indio_dev);
-+
-+	iio_device_unregister(indio_dev);
-+
-+	iio_triggered_buffer_cleanup(indio_dev);
-+
-+	regulator_disable(st->reg);
-+	regulator_put(st->reg);
-+
-+	iio_device_free(indio_dev);
-+
-+	return 0;
-+}
-+
-+
-+static const struct spi_device_id adc1x8s102_id[] = {
-+	{"adc1x8s102", 0},
-+	{}
-+};
-+MODULE_DEVICE_TABLE(spi, adc1x8s102_id);
-+
-+static struct spi_driver adc1x8s102_driver = {
-+	.driver = {
-+		.name	= "adc1x8s102",
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe		= adc1x8s102_probe,
-+	.remove		= adc1x8s102_remove,
-+	.id_table	= adc1x8s102_id,
-+};
-+module_spi_driver(adc1x8s102_driver);
-+
-+MODULE_AUTHOR("Bogdan Pricop <bogdan.pricop@emutex.com>");
-+MODULE_DESCRIPTION("Texas Instruments ADC1x8S102 driver");
-+MODULE_LICENSE("GPL v2");
-diff --git a/include/linux/platform_data/adc1x8s102.h b/include/linux/platform_data/adc1x8s102.h
-new file mode 100644
-index 000000000000..a32a499eb9fd
---- /dev/null
-+++ b/include/linux/platform_data/adc1x8s102.h
-@@ -0,0 +1,30 @@
-+/*
-+ * ADC1x8S102 SPI ADC driver
-+ *
-+ * Copyright(c) 2013 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ */
-+
-+
-+#ifndef __LINUX_PLATFORM_DATA_ADC1x8S102_H__
-+#define __LINUX_PLATFORM_DATA_ADC1x8S102_H__
-+
-+
-+/**
-+ * struct adc1x8s102_platform_data - Platform data for the adc1x8s102 ADC driver
-+ * @ext_vin: External input voltage range for all voltage input channels
-+ *	This is the voltage level of pin VA in millivolts
-+ **/
-+struct adc1x8s102_platform_data {
-+	u16  ext_vin;
-+};
-+
-+#endif /* __LINUX_PLATFORM_DATA_ADC1x8S102_H__ */
--- 
-2.5.0
-

+ 0 - 154
board/PSG/iot2000/linux-4.4-patches_orig/0030-adc1x8s102-support-ACPI-based-enumeration.patch

@@ -1,154 +0,0 @@
-From 66009f8977a62d3bd29d4b89a8e29d1095524aea Mon Sep 17 00:00:00 2001
-From: Ismo Puustinen <ismo.puustinen@intel.com>
-Date: Fri, 19 Feb 2016 07:18:30 -0800
-Subject: [PATCH 6/6] adc1x8s102: support ACPI-based enumeration.
-
-Upstream-status: Pending for ADC1x8s102 patch upstreaming to Linux kernel
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/staging/iio/adc/adc1x8s102.c | 76 ++++++++++++++++++++++++++++++------
- 1 file changed, 63 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/staging/iio/adc/adc1x8s102.c b/drivers/staging/iio/adc/adc1x8s102.c
-index 52472e21823c..881b145fd68a 100644
---- a/drivers/staging/iio/adc/adc1x8s102.c
-+++ b/drivers/staging/iio/adc/adc1x8s102.c
-@@ -1,7 +1,7 @@
- /*
-  * ADC1x8S102 SPI ADC driver
-  *
-- * Copyright(c) 2013 Intel Corporation.
-+ * Copyright(c) 2013-2015 Intel Corporation.
-  *
-  * This program is free software; you can redistribute it and/or modify it
-  * under the terms and conditions of the GNU General Public License,
-@@ -33,6 +33,13 @@
- #include <linux/platform_data/adc1x8s102.h>
- #include <linux/regulator/consumer.h>
- 
-+#include <linux/delay.h>
-+#include <linux/acpi.h>
-+#include <linux/property.h>
-+#include <linux/gpio.h>
-+
-+#include <linux/spi/pxa2xx_spi.h>
-+
- /*
-  * Defining the ADC resolution being 12 bits, we can use the same driver for
-  * both ADC108S102 (10 bits resolution) and ADC128S102 (12 bits resolution)
-@@ -259,14 +266,60 @@ static const struct iio_info adc1x8s102_info = {
- 	.driver_module		= THIS_MODULE,
- };
- 
-+struct adc1x8s102_spi_info {
-+	kernel_ulong_t driver_data;
-+	void (*setup)(struct spi_device *spi);
-+};
-+
-+static void adc1x8s102_setup_int3495(struct spi_device *spi)
-+{
-+	/* Galileo Gen 2 SPI setup */
-+
-+#define ADC1x8S102_GALILEO2_CS 8
-+
-+	struct pxa2xx_spi_chip *chip_data;
-+	chip_data = devm_kzalloc(&spi->dev, sizeof(*chip_data), GFP_KERNEL);
-+
-+	if (chip_data) {
-+		chip_data->gpio_cs = ADC1x8S102_GALILEO2_CS;
-+		spi->controller_data = chip_data;
-+		dev_info(&spi->dev, "setting GPIO CS value to %d\n", chip_data->gpio_cs);
-+		spi_setup(spi);
-+	}
-+}
-+
-+static const struct adc1x8s102_spi_info adc1x8s102_info_int3495 = {
-+	.driver_data = 0,
-+	.setup = adc1x8s102_setup_int3495,
-+};
-+
-+static const struct acpi_device_id adc1x8s102_acpi_ids[] = {
-+	{ "INT3495",  (kernel_ulong_t)&adc1x8s102_info_int3495 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(acpi, adc1x8s102_acpi_ids);
- 
- static int adc1x8s102_probe(struct spi_device *spi)
- {
- 	struct adc1x8s102_platform_data *pdata = spi->dev.platform_data;
- 	struct adc1x8s102_state *st;
- 	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
-+	const struct acpi_device_id *id;
- 	int ret;
- 
-+	id = acpi_match_device(adc1x8s102_acpi_ids, &spi->dev);
-+
-+	if (id) {
-+		const struct adc1x8s102_spi_info *info =
-+				(struct adc1x8s102_spi_info *)id->driver_data;
-+
-+		if (!info)
-+			return -ENODEV;
-+
-+		if (info->setup)
-+			info->setup(spi);
-+	}
-+
- 	if (NULL == indio_dev) {
- 		dev_crit(&spi->dev, "Cannot allocate memory for indio_dev\n");
- 		return -ENOMEM;
-@@ -274,10 +327,13 @@ static int adc1x8s102_probe(struct spi_device *spi)
- 
- 	st = iio_priv(indio_dev);
- 	if (NULL == pdata) {
--		dev_err(&spi->dev, "Cannot get adc1x8s102 platform data\n");
--		return -EFAULT;
-+		dev_warn(&spi->dev, "Cannot get adc1x8s102 platform data\n");
-+		/* FIXME: make this ACPI-dependent */
-+		st->ext_vin = 5000;
-+	}
-+	else {
-+		st->ext_vin = pdata->ext_vin;
- 	}
--	st->ext_vin = pdata->ext_vin;
- 
- 	/* Use regulator, if available. */
- 	st->reg = regulator_get(&spi->dev, "vref");
-@@ -297,7 +353,7 @@ static int adc1x8s102_probe(struct spi_device *spi)
- 	spi_set_drvdata(spi, indio_dev);
- 	st->spi = spi;
- 
--	indio_dev->name = spi_get_device_id(spi)->name;
-+	indio_dev->name = spi->modalias;
- 	indio_dev->dev.parent = &spi->dev;
- 	indio_dev->modes = INDIO_DIRECT_MODE;
- 	indio_dev->channels = adc1x8s102_channels;
-@@ -365,20 +421,14 @@ static int adc1x8s102_remove(struct spi_device *spi)
- }
- 
- 
--static const struct spi_device_id adc1x8s102_id[] = {
--	{"adc1x8s102", 0},
--	{}
--};
--MODULE_DEVICE_TABLE(spi, adc1x8s102_id);
--
- static struct spi_driver adc1x8s102_driver = {
- 	.driver = {
--		.name	= "adc1x8s102",
-+		.name   = "adc1x8s102",
- 		.owner	= THIS_MODULE,
-+		.acpi_match_table = ACPI_PTR(adc1x8s102_acpi_ids),
- 	},
- 	.probe		= adc1x8s102_probe,
- 	.remove		= adc1x8s102_remove,
--	.id_table	= adc1x8s102_id,
- };
- module_spi_driver(adc1x8s102_driver);
- 
--- 
-2.5.0
-

+ 0 - 373
board/PSG/iot2000/linux-4.4-patches_orig/0031-gpio-pca953x-add-drive-property.patch

@@ -1,373 +0,0 @@
-From 3d2455f9da30f923c6bd69014fad4cc4ea738be6 Mon Sep 17 00:00:00 2001
-From: Jussi Laako <jussi.laako@linux.intel.com>
-Date: Thu, 10 Mar 2016 11:58:11 -0800
-Subject: [PATCH] gpio-pca953x: add "drive" property
-
-Galileo gen 2 has support for setting GPIO modes. Expose these
-properties through the GPIO sysfs interface. This approach is bit hacky,
-since it changes the interface semantics.
-
-The original patch was by Josef Ahmad <josef.ahmad@linux.intel.com> and
-made on top of kernel 3.8.
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Jussi Laako <jussi.laako@linux.intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/gpio/gpio-pca953x.c   | 57 +++++++++++++++++++++++++++----
- drivers/gpio/gpiolib-sysfs.c  | 78 +++++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib.c        | 18 ++++++++++
- drivers/gpio/gpiolib.h        |  4 +++
- include/asm-generic/gpio.h    |  5 +++
- include/linux/gpio.h          | 10 ++++++
- include/linux/gpio/consumer.h | 11 ++++++
- include/linux/gpio/driver.h   |  2 ++
- 8 files changed, 178 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index f23a4b4c26a2..f99706fd470f 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -39,6 +39,9 @@
- #define PCA957X_MSK		6
- #define PCA957X_INTS		7
- 
-+#define PCA953X_PUPD_EN	35
-+#define PCA953X_PUPD_SEL	36
-+
- #define PCA_GPIO_MASK		0x00FF
- #define PCA_INT			0x0100
- #define PCA953X_TYPE		0x1000
-@@ -375,6 +378,43 @@ exit:
- 	mutex_unlock(&chip->i2c_lock);
- }
- 
-+static int pca953x_gpio_set_drive(struct gpio_chip *gc,
-+				 unsigned off, unsigned mode)
-+{
-+	struct pca953x_chip *chip;
-+	int ret = 0;
-+	int val;
-+
-+	chip = container_of(gc, struct pca953x_chip, gpio_chip);
-+
-+	if (chip->chip_type != PCA953X_TYPE)
-+		return -EINVAL;
-+
-+	mutex_lock(&chip->i2c_lock);
-+
-+	switch (mode) {
-+	case GPIOF_DRIVE_PULLUP:
-+		ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) ||
-+				pca953x_write_single(chip, PCA953X_PUPD_SEL, 1, off);
-+		break;
-+	case GPIOF_DRIVE_PULLDOWN:
-+		ret = pca953x_write_single(chip, PCA953X_PUPD_EN, 1, off) ||
-+				pca953x_write_single(chip, PCA953X_PUPD_SEL, 0, off);
-+		break;
-+	case GPIOF_DRIVE_STRONG:
-+	case GPIOF_DRIVE_HIZ:
-+		ret = pca953x_read_single(chip, PCA953X_PUPD_EN, &val, off) ||
-+				pca953x_write_single(chip, PCA953X_PUPD_EN, 0, off) ||
-+				pca953x_write_single(chip, PCA953X_PUPD_SEL, val, off);
-+		break;
-+	default:
-+		ret = -EINVAL;
-+	}
-+
-+	mutex_unlock(&chip->i2c_lock);
-+	return ret;
-+}
-+
- static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- {
- 	struct gpio_chip *gc;
-@@ -393,6 +433,9 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- 	gc->dev = &chip->client->dev;
- 	gc->owner = THIS_MODULE;
- 	gc->names = chip->names;
-+
-+	if (chip->chip_type == PCA953X_TYPE)
-+		gc->set_drive = pca953x_gpio_set_drive;
- }
- 
- #ifdef CONFIG_GPIO_PCA953X_IRQ
-@@ -552,7 +595,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
- }
- 
- static int pca953x_irq_setup(struct pca953x_chip *chip,
--			     int irq_base)
-+				 int irq_base)
- {
- 	struct i2c_client *client = chip->client;
- 	int ret, i, offset = 0;
-@@ -595,10 +638,10 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
- 		}
- 
- 		ret =  gpiochip_irqchip_add(&chip->gpio_chip,
--					    &pca953x_irq_chip,
--					    irq_base,
--					    handle_simple_irq,
--					    IRQ_TYPE_NONE);
-+						&pca953x_irq_chip,
-+						irq_base,
-+						handle_simple_irq,
-+						IRQ_TYPE_NONE);
- 		if (ret) {
- 			dev_err(&client->dev,
- 				"could not connect irqchip to gpiochip\n");
-@@ -615,7 +658,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
- 
- #else /* CONFIG_GPIO_PCA953X_IRQ */
- static int pca953x_irq_setup(struct pca953x_chip *chip,
--			     int irq_base)
-+				 int irq_base)
- {
- 	struct i2c_client *client = chip->client;
- 
-@@ -636,7 +679,7 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
- 		goto out;
- 
- 	ret = pca953x_read_regs(chip, PCA953X_DIRECTION,
--			       chip->reg_direction);
-+				   chip->reg_direction);
- 	if (ret)
- 		goto out;
- 
-diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
-index b57ed8e55ab5..b60e47738f84 100644
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -7,6 +7,7 @@
- #include <linux/interrupt.h>
- #include <linux/kdev_t.h>
- #include <linux/slab.h>
-+#include <linux/gpio.h>
- 
- #include "gpiolib.h"
- 
-@@ -350,6 +351,82 @@ static ssize_t active_low_store(struct device *dev,
- }
- static DEVICE_ATTR_RW(active_low);
- 
-+
-+static ssize_t gpio_drive_show(struct device *dev,
-+		struct device_attribute *attr, char *buf)
-+{
-+	const struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
-+		status = -EIO;
-+	} else {
-+		if (test_bit(FLAG_PULLUP, &desc->flags))
-+			status = sprintf(buf, "pullup\n");
-+		else if (test_bit(FLAG_PULLDOWN, &desc->flags))
-+			status = sprintf(buf, "pulldown\n");
-+		else if (test_bit(FLAG_STRONG, &desc->flags))
-+			status = sprintf(buf, "strong\n");
-+		else if (test_bit(FLAG_HIZ, &desc->flags))
-+			status = sprintf(buf, "hiz\n");
-+		else
-+			status = -EINVAL;
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status;
-+}
-+
-+static ssize_t gpio_drive_store(struct device *dev,
-+		struct device_attribute *attr, const char *buf, size_t size)
-+{
-+	struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags))
-+		status = -EIO;
-+	else {
-+		clear_bit(FLAG_PULLUP, &desc->flags);
-+		clear_bit(FLAG_PULLDOWN, &desc->flags);
-+		clear_bit(FLAG_STRONG, &desc->flags);
-+		clear_bit(FLAG_HIZ, &desc->flags);
-+		if (sysfs_streq(buf, "pullup")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLUP);
-+			if (!status) {
-+				set_bit(FLAG_PULLUP, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "pulldown")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLDOWN);
-+			if (!status) {
-+				set_bit(FLAG_PULLDOWN, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "strong")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_STRONG);
-+			if (!status) {
-+				set_bit(FLAG_STRONG, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "hiz")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_HIZ);
-+			if (!status) {
-+				set_bit(FLAG_HIZ, &desc->flags);
-+			}
-+		} else {
-+			status = -EINVAL;
-+		}
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status ? : size;
-+}
-+
-+static const DEVICE_ATTR(drive, 0644,
-+		gpio_drive_show, gpio_drive_store);
-+
-+
- static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
- 			       int n)
- {
-@@ -377,6 +454,7 @@ static struct attribute *gpio_attrs[] = {
- 	&dev_attr_edge.attr,
- 	&dev_attr_value.attr,
- 	&dev_attr_active_low.attr,
-+	&dev_attr_drive.attr,
- 	NULL,
- };
- 
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index 4e4c3083ae56..1f49d1522474 100644
---- a/drivers/gpio/gpiolib.c
-+++ b/drivers/gpio/gpiolib.c
-@@ -1248,6 +1248,24 @@ int gpiod_is_active_low(const struct gpio_desc *desc)
- }
- EXPORT_SYMBOL_GPL(gpiod_is_active_low);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode)
-+{
-+	unsigned long		flags;
-+	struct gpio_chip	*chip;
-+
-+	chip = desc->chip;
-+	if (!chip || !chip->set || !chip->set_drive)
-+		goto fail;
-+
-+	might_sleep_if(chip->can_sleep);
-+
-+	return chip->set_drive(chip, gpio_chip_hwgpio(desc), mode);
-+
-+fail:
-+	return -EINVAL;
-+}
-+EXPORT_SYMBOL_GPL(gpiod_set_drive);
-+
- /* I/O calls are only valid after configuration completed; the relevant
-  * "is this a valid GPIO" error checks should already have been done.
-  *
-diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
-index 98ab08c0aa2d..138faa1f6eff 100644
---- a/drivers/gpio/gpiolib.h
-+++ b/drivers/gpio/gpiolib.h
-@@ -96,6 +96,10 @@ struct gpio_desc {
- #define FLAG_OPEN_SOURCE 8	/* Gpio is open source type */
- #define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
- #define FLAG_IS_HOGGED	11	/* GPIO is hogged */
-+#define FLAG_PULLUP	12	/* Gpio drive is resistive pullup */
-+#define FLAG_PULLDOWN	13	/* Gpio drive is resistive pulldown */
-+#define FLAG_STRONG	14	/* Gpio drive is strong (fast output) */
-+#define FLAG_HIZ	15	/* Gpio drive is Hi-Z (input) */
- 
- 	/* Connection label */
- 	const char		*label;
-diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
-index 40ec1433f05d..519e8d458878 100644
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -76,6 +76,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return gpiod_set_debounce(gpio_to_desc(gpio), debounce);
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return gpiod_set_drive(gpio_to_desc(gpio), mode);
-+}
-+
- static inline int gpio_get_value_cansleep(unsigned gpio)
- {
- 	return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio));
-diff --git a/include/linux/gpio.h b/include/linux/gpio.h
-index d12b5d566e4b..344e62d27700 100644
---- a/include/linux/gpio.h
-+++ b/include/linux/gpio.h
-@@ -30,6 +30,11 @@
- #define GPIOF_EXPORT_DIR_FIXED	(GPIOF_EXPORT)
- #define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE)
- 
-+#define GPIOF_DRIVE_PULLUP	(1 << 7)
-+#define GPIOF_DRIVE_PULLDOWN	(1 << 8)
-+#define GPIOF_DRIVE_STRONG	(1 << 9)
-+#define GPIOF_DRIVE_HIZ		(1 << 10)
-+
- /**
-  * struct gpio - a structure describing a GPIO with configuration
-  * @gpio:	the GPIO number
-@@ -148,6 +153,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return -ENOSYS;
-+}
-+
- static inline int gpio_get_value(unsigned gpio)
- {
- 	/* GPIO can never have been requested or set as {in,out}put */
-diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
-index fb0fde686cb1..17f5f187699b 100644
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -122,6 +122,8 @@ void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
- 
- int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode);
-+
- int gpiod_is_active_low(const struct gpio_desc *desc);
- int gpiod_cansleep(const struct gpio_desc *desc);
- 
-@@ -376,6 +378,15 @@ static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+
-+static inline int gpiod_set_drive(unsigned gpio, unsigned mode)
-+{
-+	/* GPIO can never have been requested */
-+	WARN_ON(1);
-+	return -ENOSYS;
-+}
-+
-+
- static inline int gpiod_is_active_low(const struct gpio_desc *desc)
- {
- 	/* GPIO can never have been requested */
-diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
-index d1baebf350d8..8e86f56a730a 100644
---- a/include/linux/gpio/driver.h
-+++ b/include/linux/gpio/driver.h
-@@ -114,6 +114,8 @@ struct gpio_chip {
- 	int			(*set_debounce)(struct gpio_chip *chip,
- 						unsigned offset,
- 						unsigned debounce);
-+	int			(*set_drive)(struct gpio_chip *chip,
-+						unsigned offset, unsigned mode);
- 
- 	int			(*to_irq)(struct gpio_chip *chip,
- 						unsigned offset);
--- 
-2.5.0
-

+ 0 - 939
board/PSG/iot2000/linux-4.4-patches_orig/0032-pca9685-PCA9685-PWM-and-GPIO-multi-function-device.patch

@@ -1,939 +0,0 @@
-From c4efe23b7f93a3a3220cf3654ef5a8ed50c41fe0 Mon Sep 17 00:00:00 2001
-From: Josef Ahmad <josef.ahmad@linux.intel.com>
-Date: Fri, 19 Feb 2016 07:18:27 -0800
-Subject: [PATCH 3/6] pca9685: PCA9685 PWM and GPIO multi-function device.
-
-There is also a driver for the same chip in drivers/pwm. This version
-has support for setting the output in GPIO mode in addition to the PWM
-mode.
-
-Upstream-status: Forward-ported from Intel IOT Develper Kit Quark BSP.
-                 Inappropriate to the upstream kernel, because the
-                 upstream kernel already uses a different (non-mfd)
-                 driver for handling the same chip, and doesn't need
-                 to be backwards compatible.
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/mfd/Kconfig                   |  10 ++
- drivers/mfd/Makefile                  |   2 +
- drivers/mfd/pca9685-core.c            | 308 ++++++++++++++++++++++++++++++++++
- drivers/mfd/pca9685-gpio.c            | 108 ++++++++++++
- drivers/mfd/pca9685-pwm.c             | 262 +++++++++++++++++++++++++++++
- drivers/mfd/pca9685.h                 | 110 ++++++++++++
- include/linux/platform_data/pca9685.h |  51 ++++++
- 7 files changed, 851 insertions(+)
- create mode 100644 drivers/mfd/pca9685-core.c
- create mode 100644 drivers/mfd/pca9685-gpio.c
- create mode 100644 drivers/mfd/pca9685-pwm.c
- create mode 100644 drivers/mfd/pca9685.h
- create mode 100644 include/linux/platform_data/pca9685.h
-
-diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index 4d92df6ef9fe..059a22a30648 100644
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -385,6 +385,16 @@ config MFD_INTEL_MSIC
- 	  Passage) chip. This chip embeds audio, battery, GPIO, etc.
- 	  devices used in Intel Medfield platforms.
- 
-+config MFD_PCA9685
-+	tristate "NPX Semiconductors PCA9685 (PWM/GPIO) driver"
-+	depends on GPIOLIB && I2C && PWM
-+	select REGMAP_I2C
-+	help
-+	  NPX PCA9685 I2C-bus PWM controller with GPIO output interface support.
-+	  The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
-+	  Additionally, the driver allows the channels to be configured as GPIO
-+	  interface (output only).
-+
- config MFD_IPAQ_MICRO
- 	bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support"
- 	depends on SA1100_H3100 || SA1100_H3600
-diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
-index a8b76b81b467..f7434c027148 100644
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -142,6 +142,8 @@ obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
- obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
- obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
- obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
-+pca9685-objs			:= pca9685-core.o pca9685-gpio.o pca9685-pwm.o
-+obj-$(CONFIG_MFD_PCA9685)	+= pca9685.o
- obj-$(CONFIG_MFD_KEMPLD)	+= kempld-core.o
- obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO)	+= intel_quark_i2c_gpio.o
- obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
-diff --git a/drivers/mfd/pca9685-core.c b/drivers/mfd/pca9685-core.c
-new file mode 100644
-index 000000000000..3f63b6dfde5b
---- /dev/null
-+++ b/drivers/mfd/pca9685-core.c
-@@ -0,0 +1,308 @@
-+/*
-+ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
-+ * support.
-+ *
-+ * Copyright(c) 2013-2015 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
-+ * Additionally, the driver allows the channels to be configured as GPIO
-+ * interface (output only).
-+ */
-+
-+#include <linux/i2c.h>
-+#include <linux/module.h>
-+#include <linux/pwm.h>
-+#include <linux/gpio.h>
-+#include <linux/regmap.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/acpi.h>
-+#include <linux/property.h>
-+
-+#include "pca9685.h"
-+
-+static unsigned int en_invrt;
-+module_param(en_invrt, uint, 0);
-+MODULE_PARM_DESC(en_invrt, "Enable output logic state inverted mode");
-+
-+static unsigned int en_open_dr;
-+module_param(en_open_dr, uint, 0);
-+MODULE_PARM_DESC(en_open_dr,
-+	"The outputs are configured with an open-drain structure");
-+
-+static int gpio_base = -1; /*  requests dynamic ID allocation */
-+module_param(gpio_base, int, 0);
-+MODULE_PARM_DESC(gpio_base, "GPIO base number");
-+
-+static unsigned int pwm_period = PWM_PERIOD_DEF; /* PWM clock period */
-+module_param(pwm_period, uint, 0);
-+MODULE_PARM_DESC(pwm_period, "PWM clock period (nanoseconds)");
-+
-+static bool pca9685_register_volatile(struct device *dev, unsigned int reg)
-+{
-+	if (unlikely(reg == PCA9685_MODE1))
-+		return true;
-+	else
-+		return false;
-+}
-+
-+static struct regmap_config pca9685_regmap_i2c_config = {
-+	.reg_bits     = 8,
-+	.val_bits     = 8,
-+	.max_register = PCA9685_NUMREGS,
-+	.volatile_reg = pca9685_register_volatile,
-+	.cache_type   = REGCACHE_RBTREE,
-+};
-+
-+ssize_t pca9685_pwm_period_sysfs_show(struct device *dev,
-+					  struct device_attribute *attr,
-+					  char *buf)
-+{
-+	struct pca9685 *pca = dev_get_drvdata(dev);
-+
-+	return scnprintf(buf, PAGE_SIZE, "%u\n", pca->pwm_period);
-+}
-+
-+ssize_t pca9685_pwm_period_sysfs_store(struct device *dev,
-+					   struct device_attribute *attr,
-+					   const char *buf, size_t count)
-+{
-+	struct pca9685 *pca = dev_get_drvdata(dev);
-+	unsigned period_ns;
-+	int ret;
-+
-+	sscanf(buf, "%u", &period_ns);
-+
-+	ret = pca9685_update_prescale(pca, period_ns, true);
-+	if (ret)
-+		return ret;
-+
-+	return count;
-+}
-+
-+/* Sysfs attribute to allow PWM clock period adjustment at run-time
-+ * NOTE: All active channels will switch off momentarily if the
-+ * PWM clock period is changed
-+ */
-+static DEVICE_ATTR(pwm_period, S_IWUSR | S_IRUGO,
-+		   pca9685_pwm_period_sysfs_show,
-+		   pca9685_pwm_period_sysfs_store);
-+
-+u8 default_chan_mapping[] = {
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_PWM,
-+	PWM_CH_GPIO, PWM_CH_GPIO,
-+	PWM_CH_GPIO, PWM_CH_GPIO,
-+	PWM_CH_DISABLED /* ALL_LED disabled */
-+};
-+
-+static int pca9685_probe(struct i2c_client *client,
-+			 const struct i2c_device_id *id)
-+{
-+	struct pca9685_pdata *pdata;
-+	struct pca9685 *pca;
-+	int ret;
-+	int mode2;
-+
-+	pca = devm_kzalloc(&client->dev, sizeof(*pca), GFP_KERNEL);
-+	if (unlikely(!pca))
-+		return -ENOMEM;
-+
-+	pdata = client->dev.platform_data;
-+	if (likely(pdata)) {
-+		memcpy(pca->chan_mapping, pdata->chan_mapping,
-+				ARRAY_SIZE(pca->chan_mapping));
-+		pca->gpio_base = pdata->gpio_base;
-+		en_invrt       = pdata->en_invrt;
-+		en_open_dr     = pdata->en_open_dr;
-+	} else {
-+		dev_warn(&client->dev,
-+			 "Platform data not provided."
-+			 "Using default or mod params configuration.\n");
-+#if 1
-+        /* hack for Galileo 2*/
-+		pca->gpio_base = 64;
-+		memcpy(pca->chan_mapping, default_chan_mapping,
-+				ARRAY_SIZE(pca->chan_mapping));
-+#else
-+		pca->gpio_base = gpio_base;
-+		memset(pca->chan_mapping, PWM_CH_UNDEFINED,
-+				ARRAY_SIZE(pca->chan_mapping));
-+#endif
-+	}
-+
-+	if (unlikely(!i2c_check_functionality(client->adapter,
-+					I2C_FUNC_I2C |
-+					I2C_FUNC_SMBUS_BYTE_DATA))) {
-+		dev_err(&client->dev,
-+				"i2c adapter doesn't support required functionality\n");
-+		return -EIO;
-+	}
-+
-+	pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config);
-+	if (IS_ERR(pca->regmap)) {
-+		ret = PTR_ERR(pca->regmap);
-+		dev_err(&client->dev, "Failed to initialize register map: %d\n",
-+			ret);
-+		return ret;
-+	}
-+
-+	i2c_set_clientdata(client, pca);
-+
-+	/* registration of GPIO chip */
-+	pca->gpio_chip.label     = "pca9685-gpio";
-+	pca->gpio_chip.owner     = THIS_MODULE;
-+	pca->gpio_chip.set       = pca9685_gpio_set;
-+	pca->gpio_chip.get       = pca9685_gpio_get;
-+	pca->gpio_chip.can_sleep = 1;
-+	pca->gpio_chip.ngpio     = PCA9685_MAXCHAN;
-+	pca->gpio_chip.base      = pca->gpio_base;
-+	pca->gpio_chip.request   = pca9685_gpio_request;
-+	pca->gpio_chip.free      = pca9685_gpio_free;
-+
-+	mutex_init(&pca->lock);
-+
-+	ret = gpiochip_add(&pca->gpio_chip);
-+	if (unlikely(ret < 0)) {
-+		dev_err(&client->dev, "Could not register gpiochip, %d\n", ret);
-+		goto err;
-+	}
-+
-+	/* configure initial PWM settings */
-+	ret = pca9685_init_pwm_regs(pca, pwm_period);
-+	if (ret) {
-+		pr_err("Failed to initialize PWM registers\n");
-+		goto err_gpiochip;
-+	}
-+
-+	/* registration of PWM chip */
-+
-+	regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
-+
-+	/* update mode2 register */
-+	if (en_invrt)
-+		mode2 |= MODE2_INVRT;
-+	else
-+		mode2 &= ~MODE2_INVRT;
-+
-+	if (en_open_dr)
-+		mode2 &= ~MODE2_OUTDRV;
-+	else
-+		mode2 |= MODE2_OUTDRV;
-+
-+	regmap_write(pca->regmap, PCA9685_MODE2, mode2);
-+
-+	pca->pwm_chip.ops  = &pca9685_pwm_ops;
-+	/* add an extra channel for ALL_LED */
-+	pca->pwm_chip.npwm = PCA9685_MAXCHAN + 1;
-+	pca->pwm_chip.dev  = &client->dev;
-+	pca->pwm_chip.base = -1;
-+
-+	ret = pwmchip_add(&pca->pwm_chip);
-+	if (unlikely(ret < 0)) {
-+		dev_err(&client->dev, "pwmchip_add failed %d\n", ret);
-+		goto err_gpiochip;
-+	}
-+
-+	/* Also create a sysfs interface, providing a cmd line config option */
-+	ret = sysfs_create_file(&client->dev.kobj, &dev_attr_pwm_period.attr);
-+	if (unlikely(ret < 0)) {
-+		dev_err(&client->dev, "sysfs_create_file failed %d\n", ret);
-+		goto err_pwmchip;
-+	}
-+
-+	return ret;
-+
-+err_pwmchip:
-+	if (unlikely(pwmchip_remove(&pca->pwm_chip)))
-+		dev_warn(&client->dev, "%s failed\n", "pwmchip_remove()");
-+
-+err_gpiochip:
-+	gpiochip_remove(&pca->gpio_chip);
-+err:
-+	mutex_destroy(&pca->lock);
-+
-+	return ret;
-+}
-+
-+static int pca9685_remove(struct i2c_client *client)
-+{
-+	struct pca9685 *pca = i2c_get_clientdata(client);
-+	int ret;
-+
-+	regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
-+			MODE1_SLEEP);
-+
-+	gpiochip_remove(&pca->gpio_chip);
-+
-+	sysfs_remove_file(&client->dev.kobj, &dev_attr_pwm_period.attr);
-+
-+	ret = pwmchip_remove(&pca->pwm_chip);
-+	if (unlikely(ret))
-+		dev_err(&client->dev, "%s failed, %d\n",
-+				"pwmchip_remove()", ret);
-+
-+	mutex_destroy(&pca->lock);
-+
-+	return ret;
-+}
-+
-+static const struct acpi_device_id pca9685_acpi_ids[] = {
-+	{ "INT3492", 0 },
-+	{ /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(acpi, pca9685_acpi_ids);
-+
-+static const struct i2c_device_id pca9685_id[] = {
-+	{ "pca9685", 0 },
-+	{ /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(i2c, pca9685_id);
-+
-+static struct i2c_driver pca9685_i2c_driver = {
-+	.driver = {
-+		.name  = "mfd-pca9685",
-+		.owner = THIS_MODULE,
-+		.acpi_match_table = ACPI_PTR(pca9685_acpi_ids),
-+	},
-+	.probe     = pca9685_probe,
-+	.remove    = pca9685_remove,
-+	.id_table  = pca9685_id,
-+};
-+
-+static int __init pca9685_init(void)
-+{
-+	if (unlikely((pwm_period < PWM_PERIOD_MIN) ||
-+			 (PWM_PERIOD_MAX < pwm_period))) {
-+		pr_err("Invalid PWM period specified (valid range: %d-%d)\n",
-+			   PWM_PERIOD_MIN, PWM_PERIOD_MAX);
-+		return -EINVAL;
-+	}
-+
-+	return i2c_add_driver(&pca9685_i2c_driver);
-+}
-+/* register after i2c postcore initcall */
-+subsys_initcall(pca9685_init);
-+
-+static void __exit pca9685_exit(void)
-+{
-+	i2c_del_driver(&pca9685_i2c_driver);
-+}
-+module_exit(pca9685_exit);
-+
-+MODULE_AUTHOR("Wojciech Ziemba <wojciech.ziemba@emutex.com>");
-+MODULE_DESCRIPTION("NPX Semiconductors PCA9685 (PWM/GPIO) driver");
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/pca9685-gpio.c b/drivers/mfd/pca9685-gpio.c
-new file mode 100644
-index 000000000000..ed348af7c86e
---- /dev/null
-+++ b/drivers/mfd/pca9685-gpio.c
-@@ -0,0 +1,108 @@
-+/*
-+ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
-+ * support.
-+ *
-+ * Copyright(c) 2013-2015 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
-+ * Additionally, the driver allows the channels to be configured as GPIO
-+ * interface (output only).
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/module.h>
-+#include <linux/gpio.h>
-+#include <linux/pwm.h>
-+#include <linux/regmap.h>
-+
-+#include "pca9685.h"
-+
-+static inline struct pca9685 *gpio_to_pca(struct gpio_chip *gpio_chip)
-+{
-+	return container_of(gpio_chip, struct pca9685, gpio_chip);
-+}
-+
-+static inline int is_gpio_allowed(const struct pca9685 *pca, unsigned channel)
-+{
-+	return pca->chan_mapping[channel] & PWM_CH_GPIO;
-+}
-+
-+int pca9685_gpio_request(struct gpio_chip *chip, unsigned offset)
-+{
-+	struct pca9685 *pca;
-+	struct pwm_device *pwm;
-+	int ret = 0;
-+	pca = gpio_to_pca(chip);
-+
-+	/* validate channel constrains */
-+	if (!is_gpio_allowed(pca, offset))
-+		return -ENODEV;
-+
-+	/* return busy if channel is already allocated for pwm */
-+	pwm = &pca->pwm_chip.pwms[offset];
-+	if (test_bit(PWMF_REQUESTED, &pwm->flags))
-+		return -EBUSY;
-+
-+	/* clear the on counter */
-+	regmap_write(pca->regmap, LED_N_ON_L(offset), 0x0);
-+	regmap_write(pca->regmap, LED_N_ON_H(offset), 0x0);
-+
-+	/* clear the off counter */
-+	regmap_write(pca->regmap, LED_N_OFF_L(offset), 0x0);
-+	ret = regmap_write(pca->regmap, LED_N_OFF_H(offset), 0x0);
-+
-+	clear_sleep_bit(pca);
-+
-+	return ret;
-+}
-+
-+void pca9685_gpio_free(struct gpio_chip *chip, unsigned offset)
-+{
-+	struct pca9685 *pca;
-+
-+	pca = gpio_to_pca(chip);
-+
-+	/* clear the on counter reg */
-+	regmap_write(pca->regmap, LED_N_ON_L(offset), 0x0);
-+	regmap_write(pca->regmap, LED_N_ON_H(offset), 0x0);
-+
-+	set_sleep_bit(pca);
-+
-+	return;
-+}
-+
-+void pca9685_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-+{
-+	struct pca9685 *pca;
-+
-+	pca = gpio_to_pca(chip);
-+
-+	/* set the full-on bit */
-+	regmap_write(pca->regmap,  LED_N_ON_H(offset), (value << 4) & LED_FULL);
-+
-+	return;
-+}
-+
-+int pca9685_gpio_get(struct gpio_chip *chip, unsigned offset)
-+{
-+	struct pca9685 *pca;
-+	unsigned int val;
-+
-+	pca = gpio_to_pca(chip);
-+
-+	/* read the full-on bit */
-+	regmap_read(pca->regmap, LED_N_ON_H(offset), &val);
-+
-+	return !!val;
-+}
-+
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/pca9685-pwm.c b/drivers/mfd/pca9685-pwm.c
-new file mode 100644
-index 000000000000..0c0526374d67
---- /dev/null
-+++ b/drivers/mfd/pca9685-pwm.c
-@@ -0,0 +1,262 @@
-+/*
-+ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
-+ * support.
-+ *
-+ * Copyright(c) 2013-2015 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
-+ * Additionally, the driver allows the channels to be configured as GPIO
-+ * interface (output only).
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pwm.h>
-+#include <linux/gpio.h>
-+#include <linux/regmap.h>
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+
-+#include "pca9685.h"
-+
-+static inline struct pca9685 *pwm_to_pca(struct pwm_chip *pwm_chip)
-+{
-+	return container_of(pwm_chip, struct pca9685, pwm_chip);
-+}
-+
-+static inline int period_ns_to_prescale(unsigned period_ns)
-+{
-+	return (DIV_ROUND_CLOSEST(OSC_CLK_MHZ * period_ns,
-+			SAMPLE_RES * 1000)) - 1;
-+}
-+
-+static inline int is_pwm_allowed(const struct pca9685 *pca, unsigned channel)
-+{
-+	return pca->chan_mapping[channel] & PWM_CH_PWM;
-+}
-+
-+int pca9685_update_prescale(struct pca9685 *pca, unsigned period_ns,
-+			    bool reconfigure_channels)
-+{
-+	int pre_scale, i;
-+	struct pwm_device *pwm;
-+	unsigned long long duty_scale;
-+	unsigned long long new_duty_ns;
-+
-+	if (unlikely((period_ns < PWM_PERIOD_MIN) ||
-+		     (PWM_PERIOD_MAX < period_ns))) {
-+		pr_err("Invalid PWM period specified (valid range: %d-%d)\n",
-+		       PWM_PERIOD_MIN, PWM_PERIOD_MAX);
-+		return -EINVAL;
-+	}
-+
-+	mutex_lock(&pca->lock);
-+
-+	/* update pre_scale to the closest period */
-+	pre_scale = period_ns_to_prescale(period_ns);
-+	/* ensure sleep-mode bit is set
-+	 * NOTE: All active channels will switch off for at least 500 usecs
-+	 */
-+	regmap_update_bits(pca->regmap, PCA9685_MODE1,
-+			   MODE1_SLEEP, MODE1_SLEEP);
-+	regmap_write(pca->regmap, PCA9685_PRESCALE, pre_scale);
-+	/* clear sleep mode flag if at least 1 channel is active */
-+	if (pca->active_cnt > 0) {
-+		regmap_update_bits(pca->regmap, PCA9685_MODE1,
-+				   MODE1_SLEEP, 0x0);
-+		usleep_range(MODE1_RESTART_DELAY, MODE1_RESTART_DELAY * 2);
-+		regmap_update_bits(pca->regmap, PCA9685_MODE1,
-+				   MODE1_RESTART, MODE1_RESTART);
-+	}
-+
-+	if (reconfigure_channels) {
-+		for (i = 0; i < pca->pwm_chip.npwm; i++) {
-+			pwm = &pca->pwm_chip.pwms[i];
-+			pwm->period = period_ns;
-+			if (pwm->duty_cycle > 0) {
-+				/* Scale the rise time to maintain duty cycle */
-+				duty_scale = period_ns;
-+				duty_scale *= 1000000;
-+				do_div(duty_scale, pca->pwm_period);
-+				new_duty_ns = duty_scale * pwm->duty_cycle;
-+				do_div(new_duty_ns, 1000000);
-+				/* Update the duty_cycle */
-+				pwm_config(pwm, (int)new_duty_ns, pwm->period);
-+			}
-+		}
-+	}
-+	pca->pwm_period = period_ns;
-+
-+	mutex_unlock(&pca->lock);
-+	return 0;
-+}
-+
-+int pca9685_init_pwm_regs(struct pca9685 *pca, unsigned period_ns)
-+{
-+	int ret, chan;
-+
-+	/* set MODE1_SLEEP */
-+	ret = regmap_update_bits(pca->regmap, PCA9685_MODE1,
-+					MODE1_SLEEP, MODE1_SLEEP);
-+	if (unlikely(ret < 0))
-+		return ret;
-+
-+	/* configure the initial PWM clock period */
-+	ret = pca9685_update_prescale(pca, period_ns, false);
-+	if (unlikely(ret < 0))
-+		return ret;
-+
-+	/* reset PWM channel registers to power-on default values */
-+	for (chan = 0; chan < PCA9685_MAXCHAN; chan++) {
-+		ret = regmap_write(pca->regmap, LED_N_ON_L(chan), 0);
-+		if (unlikely(ret < 0))
-+			return ret;
-+		ret = regmap_write(pca->regmap, LED_N_ON_H(chan), 0);
-+		if (unlikely(ret < 0))
-+			return ret;
-+		ret = regmap_write(pca->regmap, LED_N_OFF_L(chan), 0);
-+		if (unlikely(ret < 0))
-+			return ret;
-+		ret = regmap_write(pca->regmap, LED_N_OFF_H(chan), LED_FULL);
-+		if (unlikely(ret < 0))
-+			return ret;
-+	}
-+	/* reset ALL_LED registers to power-on default values */
-+	ret = regmap_write(pca->regmap, PCA9685_ALL_LED_ON_L, 0);
-+	if (unlikely(ret < 0))
-+		return ret;
-+	ret = regmap_write(pca->regmap, PCA9685_ALL_LED_ON_H, 0);
-+	if (unlikely(ret < 0))
-+		return ret;
-+	ret = regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, 0);
-+	if (unlikely(ret < 0))
-+		return ret;
-+	ret = regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, LED_FULL);
-+	if (unlikely(ret < 0))
-+		return ret;
-+
-+	return ret;
-+}
-+
-+static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-+				int duty_ns, int period_ns)
-+{
-+	struct pca9685 *pca = pwm_to_pca(chip);
-+	unsigned long long duty;
-+	unsigned int	reg_on_h,
-+			reg_off_l,
-+			reg_off_h;
-+	int full_off;
-+
-+	/* Changing PWM period for a single channel at run-time not allowed.
-+	 * The PCA9685 PWM clock is shared across all PWM channels
-+	 */
-+	if (unlikely(period_ns != pwm->period))
-+		return -EPERM;
-+
-+	if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN)) {
-+		reg_on_h  = PCA9685_ALL_LED_ON_H;
-+		reg_off_l = PCA9685_ALL_LED_OFF_L;
-+		reg_off_h = PCA9685_ALL_LED_OFF_H;
-+	} else {
-+		reg_on_h  = LED_N_ON_H(pwm->hwpwm);
-+		reg_off_l = LED_N_OFF_L(pwm->hwpwm);
-+		reg_off_h = LED_N_OFF_H(pwm->hwpwm);
-+	}
-+
-+	duty = SAMPLE_RES * (unsigned long long)duty_ns;
-+	duty = DIV_ROUND_UP_ULL(duty, period_ns);
-+
-+	if (duty >= SAMPLE_RES) /* set the LED_FULL bit */
-+		return regmap_write(pca->regmap, reg_on_h, LED_FULL);
-+	else /* clear the LED_FULL bit */
-+		regmap_write(pca->regmap, reg_on_h, 0x00);
-+
-+	full_off = !test_bit(PWMF_ENABLED, &pwm->flags) << 4;
-+
-+	regmap_write(pca->regmap, reg_off_l, (int)duty & 0xff);
-+
-+	return regmap_write(pca->regmap, reg_off_h,
-+			((int)duty >> 8 | full_off) & 0x1f);
-+}
-+
-+static int pca9685_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+	struct pca9685 *pca = pwm_to_pca(chip);
-+	int ret;
-+
-+	unsigned int reg_off_h;
-+
-+	if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN))
-+		reg_off_h = PCA9685_ALL_LED_OFF_H;
-+	else
-+		reg_off_h = LED_N_OFF_H(pwm->hwpwm);
-+
-+	/* clear the full-off bit */
-+	ret = regmap_update_bits(pca->regmap, reg_off_h, LED_FULL, 0x0);
-+
-+	clear_sleep_bit(pca);
-+
-+	return ret;
-+}
-+
-+static void pca9685_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+	struct pca9685 *pca = pwm_to_pca(chip);
-+
-+	unsigned int reg_off_h;
-+
-+	if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN))
-+		reg_off_h = PCA9685_ALL_LED_OFF_H;
-+	else
-+		reg_off_h = LED_N_OFF_H(pwm->hwpwm);
-+
-+	/* set the LED_OFF counter. */
-+	regmap_update_bits(pca->regmap, reg_off_h, LED_FULL, LED_FULL);
-+
-+	set_sleep_bit(pca);
-+
-+	return;
-+}
-+
-+static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+	struct pca9685 *pca;
-+	struct gpio_chip *gpio_chip;
-+	unsigned channel = pwm->hwpwm;
-+
-+	pca = pwm_to_pca(chip);
-+
-+	/* validate channel constrains */
-+	if (!is_pwm_allowed(pca, channel))
-+		return -ENODEV;
-+
-+	/* return busy if channel is already allocated for gpio */
-+	gpio_chip = &pca->gpio_chip;
-+
-+	if ((channel < PCA9685_MAXCHAN) &&
-+		(gpiochip_is_requested(gpio_chip, channel)))
-+			return -EBUSY;
-+
-+	pwm->period = pca->pwm_period;
-+
-+	return 0;
-+}
-+
-+const struct pwm_ops pca9685_pwm_ops = {
-+	.enable  = pca9685_pwm_enable,
-+	.disable = pca9685_pwm_disable,
-+	.config  = pca9685_pwm_config,
-+	.request = pca9685_pwm_request,
-+	.owner   = THIS_MODULE,
-+};
-+
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/mfd/pca9685.h b/drivers/mfd/pca9685.h
-new file mode 100644
-index 000000000000..d678d30177f8
---- /dev/null
-+++ b/drivers/mfd/pca9685.h
-@@ -0,0 +1,110 @@
-+/*
-+ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
-+ * support.
-+ *
-+ * Copyright(c) 2013-2015 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
-+ * Additionally, the driver allows the channels to be configured as GPIO
-+ * interface (output only).
-+ */
-+
-+#ifndef __LINUX_MFD_PCA9685_H
-+#define __LINUX_MFD_PCA9685_H
-+
-+#include <linux/mutex.h>
-+#include <linux/gpio.h>
-+#include <linux/pwm.h>
-+#include <linux/platform_data/pca9685.h>
-+
-+#define PCA9685_MODE1		0x00
-+#define PCA9685_MODE2		0x01
-+#define PCA9685_SUBADDR1	0x02
-+#define PCA9685_SUBADDR2	0x03
-+#define PCA9685_SUBADDR3	0x04
-+#define PCA9685_LEDX_ON_L	0x06
-+#define PCA9685_LEDX_ON_H	0x07
-+#define PCA9685_LEDX_OFF_L	0x08
-+#define PCA9685_LEDX_OFF_H	0x09
-+
-+#define PCA9685_ALL_LED_ON_L	0xFA
-+#define PCA9685_ALL_LED_ON_H	0xFB
-+#define PCA9685_ALL_LED_OFF_L	0xFC
-+#define PCA9685_ALL_LED_OFF_H	0xFD
-+#define PCA9685_PRESCALE	0xFE
-+
-+#define PCA9685_NUMREGS		0xFF
-+
-+#define LED_FULL		(1 << 4)
-+#define MODE1_SLEEP		(1 << 4)
-+#define MODE1_RESTART		(1 << 7)
-+
-+#define MODE1_RESTART_DELAY	500
-+
-+#define LED_N_ON_H(N)	(PCA9685_LEDX_ON_H +  (4 * (N)))
-+#define LED_N_ON_L(N)	(PCA9685_LEDX_ON_L +  (4 * (N)))
-+#define LED_N_OFF_H(N)	(PCA9685_LEDX_OFF_H + (4 * (N)))
-+#define LED_N_OFF_L(N)	(PCA9685_LEDX_OFF_L + (4 * (N)))
-+
-+#define OSC_CLK_MHZ		      25 /* 25 MHz */
-+#define SAMPLE_RES		    4096 /* 12 bits */
-+#define PWM_PERIOD_MIN		  666666 /* ~1525 Hz */
-+#define PWM_PERIOD_MAX		41666666 /* 24 Hz */
-+#define PWM_PERIOD_DEF		 5000000 /* default 200 Hz */
-+
-+struct pca9685 {
-+	struct gpio_chip	gpio_chip;
-+	struct pwm_chip		pwm_chip;
-+	struct regmap		*regmap;
-+	struct mutex		lock; /* mutual exclusion semaphore */
-+	/* Array of channel allocation constrains */
-+	/* add an extra channel for ALL_LED */
-+	u8	chan_mapping[PCA9685_MAXCHAN + 1];
-+	int	gpio_base;
-+	int	active_cnt;
-+	int	pwm_exported_cnt;
-+	int	pwm_period;
-+};
-+
-+extern const struct pwm_ops pca9685_pwm_ops;
-+
-+int  pca9685_gpio_request(struct gpio_chip *chip, unsigned offset);
-+void pca9685_gpio_free(struct gpio_chip *chip, unsigned offset);
-+void pca9685_gpio_set(struct gpio_chip *chip, unsigned offset, int value);
-+int  pca9685_gpio_get(struct gpio_chip *chip, unsigned offset);
-+
-+int pca9685_init_pwm_regs(struct pca9685 *pca, unsigned period_ns);
-+int pca9685_update_prescale(struct pca9685 *pca, unsigned period_ns,
-+			    bool reconfigure_channels);
-+
-+static inline void set_sleep_bit(struct pca9685 *pca)
-+{
-+	mutex_lock(&pca->lock);
-+	/* set sleep mode flag if no more active LED channel*/
-+	if (--pca->active_cnt == 0)
-+		regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
-+				MODE1_SLEEP);
-+	mutex_unlock(&pca->lock);
-+}
-+
-+static inline void clear_sleep_bit(struct pca9685 *pca)
-+{
-+	mutex_lock(&pca->lock);
-+	/* clear sleep mode flag if at least 1 LED channel is active */
-+	if (pca->active_cnt++ == 0)
-+		regmap_update_bits(pca->regmap, PCA9685_MODE1,
-+				MODE1_SLEEP, 0x0);
-+
-+	mutex_unlock(&pca->lock);
-+}
-+
-+#endif	/* __LINUX_MFD_PCA9685_H */
-diff --git a/include/linux/platform_data/pca9685.h b/include/linux/platform_data/pca9685.h
-new file mode 100644
-index 000000000000..dbb83f707fe7
---- /dev/null
-+++ b/include/linux/platform_data/pca9685.h
-@@ -0,0 +1,51 @@
-+/*
-+ * Platform data for pca9685 driver
-+ *
-+ * Copyright(c) 2013-2015 Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ */
-+
-+#ifndef _PLAT_PCA9685_H_
-+#define _PLAT_PCA9685_H_
-+
-+#define PCA9685_MAXCHAN	16
-+#define MODE2_INVRT	(1 << 4)
-+#define MODE2_OUTDRV	(1 << 2)
-+
-+/* PWM channel allocation flags */
-+enum {
-+	PWM_CH_DISABLED  = 0,
-+	PWM_CH_PWM       = 1 << 0,
-+	PWM_CH_GPIO      = 1 << 1,
-+	/* allow PWM or GPIO */
-+	PWM_CH_UNDEFINED = PWM_CH_PWM | PWM_CH_GPIO,
-+};
-+
-+/**
-+ * struct pca9685_pdata - Platform data for pca9685 driver
-+ * @chan_mapping: Array of channel allocation constrains
-+ * @gpio_base: GPIO base
-+ * mode2_flags: mode2 register modification flags: INVRT and OUTDRV
-+ **/
-+struct pca9685_pdata {
-+	/* Array of channel allocation constrains */
-+	/* add an extra channel for ALL_LED */
-+	u8	chan_mapping[PCA9685_MAXCHAN + 1];
-+	/* GPIO base */
-+	int	gpio_base;
-+	/* mode2 flags */
-+	u8	en_invrt:1,   /* enable output logic state inverted mode */
-+		en_open_dr:1, /* enable if outputs are configured with an
-+						 open-drain structure */
-+		unused:6;
-+};
-+
-+#endif /* _PLAT_PCA9685_H_ */
--- 
-2.5.0
-

+ 0 - 36
board/PSG/iot2000/linux-4.4-patches_orig/0033-spi-pxa2xx-fixed-ACPI-based-enumeration-of-SPI-devic.patch

@@ -1,36 +0,0 @@
-From cd83f4095b234652ae65321f35700f7e3441f0f9 Mon Sep 17 00:00:00 2001
-From: Ismo Puustinen <ismo.puustinen@intel.com>
-Date: Fri, 19 Feb 2016 07:18:28 -0800
-Subject: [PATCH 4/6] spi-pxa2xx: fixed ACPI-based enumeration of SPI devices.
-
-Slave devices were not enumerated by ACPI data because the ACPI handle
-for the spi-pxa2xx controller was NULL if it was itself enumerated by
-PCI.
-
-Original patch by Mika Westerberg <mika.westerberg@intel.com>.
-
-Upstream-status: Inappropriate, will be fixed with a bigger overhaul of
-                 SPI/ACPI interaction.
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- drivers/spi/spi-pxa2xx-pci.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c
-index d19d7f28aecb..562ffc1282bc 100644
---- a/drivers/spi/spi-pxa2xx-pci.c
-+++ b/drivers/spi/spi-pxa2xx-pci.c
-@@ -169,6 +169,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
- 	memset(&pi, 0, sizeof(pi));
- 	pi.parent = &dev->dev;
- 	pi.name = "pxa2xx-spi";
-+	pi.fwnode = dev->dev.fwnode;
- 	pi.id = ssp->port_id;
- 	pi.data = &spi_pdata;
- 	pi.size_data = sizeof(spi_pdata);
--- 
-2.5.0
-

+ 0 - 1218
board/PSG/iot2000/linux-4.4-patches_orig/0034-acpi-added-a-custom-DSDT-file.patch

@@ -1,1218 +0,0 @@
-From 4086f8c349569926fd8fbe967ec24bdeabc79f95 Mon Sep 17 00:00:00 2001
-From: Ismo Puustinen <ismo.puustinen@intel.com>
-Date: Fri, 19 Feb 2016 07:18:25 -0800
-Subject: [PATCH 1/6] acpi: added a custom DSDT file.
-
-The file has fixed GPIO IRQ assignment and moved SPI devices to be under
-the SPI bus in the ACPI definitions as assumed by ACPI version 5.
-
-Upstream-status: Inappropriate, custom firmware
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- include/DSDT.hex | 1191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 1191 insertions(+)
- create mode 100644 include/DSDT.hex
-
-diff --git a/include/DSDT.hex b/include/DSDT.hex
-new file mode 100644
-index 000000000000..b1e296048090
---- /dev/null
-+++ b/include/DSDT.hex
-@@ -0,0 +1,1191 @@
-+/*
-+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * 
-+ * Intel ACPI Component Architecture
-+ * ASL+ Optimizing Compiler version 20150515-64
-+ * Copyright (c) 2000 - 2015 Intel Corporation
-+ * 
-+ * Compilation of "dsdt-fixed-spi.dsl" - Wed Sep 23 12:49:37 2015
-+ * 
-+ * C source code output
-+ * AML code block contains 0x23F5 bytes
-+ *
-+ */
-+unsigned char AmlCode[] =
-+{
-+    0x44,0x53,0x44,0x54,0xF5,0x23,0x00,0x00,  /* 00000000    "DSDT.#.." */
-+    0x01,0xD3,0x49,0x4E,0x54,0x45,0x4C,0x20,  /* 00000008    "..INTEL " */
-+    0x51,0x75,0x61,0x72,0x6B,0x4E,0x63,0x53,  /* 00000010    "QuarkNcS" */
-+    0x03,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
-+    0x15,0x05,0x15,0x20,0x08,0x47,0x50,0x49,  /* 00000020    "... .GPI" */
-+    0x43,0x00,0x5B,0x80,0x44,0x42,0x47,0x30,  /* 00000028    "C.[.DBG0" */
-+    0x01,0x0A,0x80,0x01,0x5B,0x81,0x0B,0x44,  /* 00000030    "....[..D" */
-+    0x42,0x47,0x30,0x01,0x49,0x4F,0x38,0x30,  /* 00000038    "BG0.IO80" */
-+    0x08,0x5B,0x80,0x41,0x43,0x4D,0x53,0x01,  /* 00000040    ".[.ACMS." */
-+    0x0A,0x72,0x0A,0x02,0x5B,0x81,0x10,0x41,  /* 00000048    ".r..[..A" */
-+    0x43,0x4D,0x53,0x01,0x49,0x4E,0x44,0x58,  /* 00000050    "CMS.INDX" */
-+    0x08,0x44,0x41,0x54,0x41,0x08,0x5B,0x80,  /* 00000058    ".DATA.[." */
-+    0x4D,0x4E,0x56,0x53,0x00,0x0C,0x90,0x8C,  /* 00000060    "MNVS...." */
-+    0x1C,0x0F,0x0B,0x00,0x02,0x5B,0x81,0x45,  /* 00000068    ".....[.E" */
-+    0x07,0x4D,0x4E,0x56,0x53,0x01,0x4F,0x53,  /* 00000070    ".MNVS.OS" */
-+    0x54,0x50,0x20,0x43,0x46,0x47,0x44,0x20,  /* 00000078    "TP CFGD " */
-+    0x48,0x50,0x45,0x41,0x20,0x50,0x31,0x42,  /* 00000080    "HPEA P1B" */
-+    0x42,0x20,0x50,0x42,0x41,0x42,0x20,0x47,  /* 00000088    "B PBAB G" */
-+    0x50,0x30,0x42,0x20,0x47,0x50,0x41,0x42,  /* 00000090    "P0B GPAB" */
-+    0x20,0x53,0x4D,0x42,0x42,0x20,0x4E,0x52,  /* 00000098    " SMBB NR" */
-+    0x56,0x31,0x20,0x57,0x44,0x54,0x42,0x20,  /* 000000A0    "V1 WDTB " */
-+    0x48,0x50,0x54,0x42,0x20,0x48,0x50,0x54,  /* 000000A8    "HPTB HPT" */
-+    0x53,0x20,0x50,0x45,0x58,0x42,0x20,0x50,  /* 000000B0    "S PEXB P" */
-+    0x45,0x58,0x53,0x20,0x52,0x43,0x42,0x42,  /* 000000B8    "EXS RCBB" */
-+    0x20,0x52,0x43,0x42,0x53,0x20,0x41,0x50,  /* 000000C0    " RCBS AP" */
-+    0x43,0x42,0x20,0x41,0x50,0x43,0x53,0x20,  /* 000000C8    "CB APCS " */
-+    0x54,0x50,0x4D,0x50,0x20,0x44,0x42,0x47,  /* 000000D0    "TPMP DBG" */
-+    0x50,0x20,0x50,0x54,0x59,0x50,0x20,0x41,  /* 000000D8    "P PTYP A" */
-+    0x4C,0x54,0x53,0x20,0x5B,0x80,0x47,0x50,  /* 000000E0    "LTS [.GP" */
-+    0x45,0x42,0x01,0x0B,0x00,0x11,0x0A,0x40,  /* 000000E8    "EB.....@" */
-+    0x5B,0x81,0x13,0x47,0x50,0x45,0x42,0x00,  /* 000000F0    "[..GPEB." */
-+    0x00,0x40,0x08,0x53,0x4D,0x49,0x45,0x20,  /* 000000F8    ".@.SMIE " */
-+    0x53,0x4D,0x49,0x53,0x20,0x10,0x12,0x5F,  /* 00000100    "SMIS .._" */
-+    0x50,0x52,0x5F,0x5B,0x83,0x0B,0x43,0x50,  /* 00000108    "PR_[..CP" */
-+    0x55,0x30,0x01,0x10,0x10,0x00,0x00,0x06,  /* 00000110    "U0......" */
-+    0x08,0x5F,0x53,0x30,0x5F,0x12,0x06,0x04,  /* 00000118    "._S0_..." */
-+    0x00,0x00,0x00,0x00,0x08,0x5F,0x53,0x33,  /* 00000120    "....._S3" */
-+    0x5F,0x12,0x07,0x04,0x0A,0x05,0x00,0x00,  /* 00000128    "_......." */
-+    0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x07,  /* 00000130    ".._S4_.." */
-+    0x04,0x0A,0x06,0x00,0x00,0x00,0x08,0x5F,  /* 00000138    "......._" */
-+    0x53,0x35,0x5F,0x12,0x07,0x04,0x0A,0x07,  /* 00000140    "S5_....." */
-+    0x00,0x00,0x00,0x10,0x4E,0x12,0x5F,0x47,  /* 00000148    "....N._G" */
-+    0x50,0x45,0x14,0x13,0x5F,0x4C,0x30,0x44,  /* 00000150    "PE.._L0D" */
-+    0x00,0x86,0x5C,0x2E,0x5F,0x53,0x42,0x5F,  /* 00000158    "..\._SB_" */
-+    0x53,0x4C,0x50,0x42,0x0A,0x02,0x14,0x13,  /* 00000160    "SLPB...." */
-+    0x5F,0x4C,0x30,0x45,0x00,0x86,0x5C,0x2E,  /* 00000168    "_L0E..\." */
-+    0x5F,0x53,0x42,0x5F,0x50,0x57,0x52,0x42,  /* 00000170    "_SB_PWRB" */
-+    0x0A,0x02,0x14,0x4D,0x0C,0x5F,0x4C,0x30,  /* 00000178    "...M._L0" */
-+    0x46,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,  /* 00000180    "F..\/._S" */
-+    0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x44,  /* 00000188    "B_PCI0SD" */
-+    0x49,0x4F,0x0A,0x02,0x86,0x5C,0x2F,0x03,  /* 00000190    "IO...\/." */
-+    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 00000198    "_SB_PCI0" */
-+    0x55,0x52,0x54,0x30,0x0A,0x02,0x86,0x5C,  /* 000001A0    "URT0...\" */
-+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 000001A8    "/._SB_PC" */
-+    0x49,0x30,0x55,0x53,0x42,0x44,0x0A,0x02,  /* 000001B0    "I0USBD.." */
-+    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 000001B8    ".\/._SB_" */
-+    0x50,0x43,0x49,0x30,0x45,0x48,0x43,0x49,  /* 000001C0    "PCI0EHCI" */
-+    0x0A,0x02,0x86,0x5C,0x2F,0x03,0x5F,0x53,  /* 000001C8    "...\/._S" */
-+    0x42,0x5F,0x50,0x43,0x49,0x30,0x4F,0x48,  /* 000001D0    "B_PCI0OH" */
-+    0x43,0x49,0x0A,0x02,0x86,0x5C,0x2F,0x03,  /* 000001D8    "CI...\/." */
-+    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 000001E0    "_SB_PCI0" */
-+    0x55,0x52,0x54,0x31,0x0A,0x02,0x86,0x5C,  /* 000001E8    "URT1...\" */
-+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 000001F0    "/._SB_PC" */
-+    0x49,0x30,0x45,0x4E,0x54,0x30,0x0A,0x02,  /* 000001F8    "I0ENT0.." */
-+    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00000200    ".\/._SB_" */
-+    0x50,0x43,0x49,0x30,0x45,0x4E,0x54,0x31,  /* 00000208    "PCI0ENT1" */
-+    0x0A,0x02,0x86,0x5C,0x2F,0x03,0x5F,0x53,  /* 00000210    "...\/._S" */
-+    0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x50,  /* 00000218    "B_PCI0SP" */
-+    0x49,0x30,0x0A,0x02,0x86,0x5C,0x2F,0x03,  /* 00000220    "I0...\/." */
-+    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 00000228    "_SB_PCI0" */
-+    0x53,0x50,0x49,0x31,0x0A,0x02,0x86,0x5C,  /* 00000230    "SPI1...\" */
-+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000238    "/._SB_PC" */
-+    0x49,0x30,0x47,0x49,0x50,0x30,0x0A,0x02,  /* 00000240    "I0GIP0.." */
-+    0x14,0x06,0x5F,0x4C,0x31,0x30,0x00,0x14,  /* 00000248    ".._L10.." */
-+    0x2A,0x5F,0x4C,0x31,0x31,0x00,0x86,0x5C,  /* 00000250    "*_L11..\" */
-+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000258    "/._SB_PC" */
-+    0x49,0x30,0x50,0x45,0x58,0x30,0x0A,0x02,  /* 00000260    "I0PEX0.." */
-+    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00000268    ".\/._SB_" */
-+    0x50,0x43,0x49,0x30,0x50,0x45,0x58,0x31,  /* 00000270    "PCI0PEX1" */
-+    0x0A,0x02,0x5B,0x82,0x23,0x2E,0x5F,0x53,  /* 00000278    "..[.#._S" */
-+    0x42,0x5F,0x53,0x4C,0x50,0x42,0x08,0x5F,  /* 00000280    "B_SLPB._" */
-+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0E,  /* 00000288    "HID.A..." */
-+    0x14,0x0E,0x5F,0x50,0x52,0x57,0x00,0xA4,  /* 00000290    ".._PRW.." */
-+    0x12,0x06,0x02,0x0A,0x0D,0x0A,0x04,0x5B,  /* 00000298    ".......[" */
-+    0x82,0x23,0x2E,0x5F,0x53,0x42,0x5F,0x50,  /* 000002A0    ".#._SB_P" */
-+    0x57,0x52,0x42,0x08,0x5F,0x48,0x49,0x44,  /* 000002A8    "WRB._HID" */
-+    0x0C,0x41,0xD0,0x0C,0x0C,0x14,0x0E,0x5F,  /* 000002B0    ".A....._" */
-+    0x50,0x52,0x57,0x00,0xA4,0x12,0x06,0x02,  /* 000002B8    "PRW....." */
-+    0x0A,0x0E,0x0A,0x04,0x14,0x08,0x5F,0x57,  /* 000002C0    "......_W" */
-+    0x41,0x4B,0x09,0xA4,0x00,0x14,0x20,0x5F,  /* 000002C8    "AK.... _" */
-+    0x50,0x54,0x53,0x01,0xA0,0x19,0x93,0x68,  /* 000002D0    "PTS....h" */
-+    0x0A,0x03,0x70,0xFF,0x53,0x4D,0x49,0x53,  /* 000002D8    "..p.SMIS" */
-+    0x70,0x53,0x4D,0x49,0x45,0x60,0x7D,0x60,  /* 000002E0    "pSMIE`}`" */
-+    0x0A,0x04,0x53,0x4D,0x49,0x45,0x14,0x0C,  /* 000002E8    "..SMIE.." */
-+    0x5F,0x50,0x49,0x43,0x01,0x70,0x68,0x47,  /* 000002F0    "_PIC.phG" */
-+    0x50,0x49,0x43,0x10,0x89,0x0F,0x02,0x5F,  /* 000002F8    "PIC...._" */
-+    0x53,0x42,0x5F,0x5B,0x82,0x80,0x44,0x01,  /* 00000300    "SB_[..D." */
-+    0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49,  /* 00000308    "PCI0._HI" */
-+    0x44,0x0C,0x41,0xD0,0x0A,0x08,0x08,0x5F,  /* 00000310    "D.A...._" */
-+    0x43,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,  /* 00000318    "CID.A..." */
-+    0x08,0x5F,0x41,0x44,0x52,0x00,0x14,0x4D,  /* 00000320    "._ADR..M" */
-+    0x10,0x5F,0x49,0x4E,0x49,0x00,0x70,0x0A,  /* 00000328    "._INI.p." */
-+    0xF0,0x4F,0x53,0x54,0x50,0xA0,0x4E,0x0F,  /* 00000330    ".OSTP.N." */
-+    0x5B,0x12,0x5F,0x4F,0x53,0x49,0x60,0xA0,  /* 00000338    "[._OSI`." */
-+    0x19,0x5F,0x4F,0x53,0x49,0x0D,0x57,0x69,  /* 00000340    "._OSI.Wi" */
-+    0x6E,0x64,0x6F,0x77,0x73,0x20,0x32,0x30,  /* 00000348    "ndows 20" */
-+    0x30,0x31,0x00,0x70,0x01,0x4F,0x53,0x54,  /* 00000350    "01.p.OST" */
-+    0x50,0xA0,0x1E,0x5F,0x4F,0x53,0x49,0x0D,  /* 00000358    "P.._OSI." */
-+    0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x20,  /* 00000360    "Windows " */
-+    0x32,0x30,0x30,0x31,0x20,0x53,0x50,0x31,  /* 00000368    "2001 SP1" */
-+    0x00,0x70,0x0A,0x02,0x4F,0x53,0x54,0x50,  /* 00000370    ".p..OSTP" */
-+    0xA0,0x1E,0x5F,0x4F,0x53,0x49,0x0D,0x57,  /* 00000378    ".._OSI.W" */
-+    0x69,0x6E,0x64,0x6F,0x77,0x73,0x20,0x32,  /* 00000380    "indows 2" */
-+    0x30,0x30,0x31,0x20,0x53,0x50,0x32,0x00,  /* 00000388    "001 SP2." */
-+    0x70,0x0A,0x04,0x4F,0x53,0x54,0x50,0xA0,  /* 00000390    "p..OSTP." */
-+    0x1C,0x5F,0x4F,0x53,0x49,0x0D,0x57,0x69,  /* 00000398    "._OSI.Wi" */
-+    0x6E,0x64,0x6F,0x77,0x73,0x20,0x32,0x30,  /* 000003A0    "ndows 20" */
-+    0x30,0x31,0x2E,0x31,0x00,0x70,0x0A,0x08,  /* 000003A8    "01.1.p.." */
-+    0x4F,0x53,0x54,0x50,0xA0,0x1A,0x5F,0x4F,  /* 000003B0    "OSTP.._O" */
-+    0x53,0x49,0x0D,0x57,0x69,0x6E,0x64,0x6F,  /* 000003B8    "SI.Windo" */
-+    0x77,0x73,0x20,0x32,0x30,0x30,0x36,0x00,  /* 000003C0    "ws 2006." */
-+    0x70,0x0A,0x10,0x4F,0x53,0x54,0x50,0xA0,  /* 000003C8    "p..OSTP." */
-+    0x1A,0x5F,0x4F,0x53,0x49,0x0D,0x57,0x69,  /* 000003D0    "._OSI.Wi" */
-+    0x6E,0x64,0x6F,0x77,0x73,0x20,0x32,0x30,  /* 000003D8    "ndows 20" */
-+    0x30,0x39,0x00,0x70,0x0A,0x11,0x4F,0x53,  /* 000003E0    "09.p..OS" */
-+    0x54,0x50,0xA0,0x1A,0x5F,0x4F,0x53,0x49,  /* 000003E8    "TP.._OSI" */
-+    0x0D,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,  /* 000003F0    ".Windows" */
-+    0x20,0x32,0x30,0x31,0x32,0x00,0x70,0x0A,  /* 000003F8    " 2012.p." */
-+    0x12,0x4F,0x53,0x54,0x50,0xA0,0x1A,0x5F,  /* 00000400    ".OSTP.._" */
-+    0x4F,0x53,0x49,0x0D,0x57,0x69,0x6E,0x64,  /* 00000408    "OSI.Wind" */
-+    0x6F,0x77,0x73,0x20,0x32,0x30,0x31,0x33,  /* 00000410    "ows 2013" */
-+    0x00,0x70,0x0A,0x13,0x4F,0x53,0x54,0x50,  /* 00000418    ".p..OSTP" */
-+    0xA0,0x13,0x5F,0x4F,0x53,0x49,0x0D,0x4C,  /* 00000420    ".._OSI.L" */
-+    0x69,0x6E,0x75,0x78,0x00,0x70,0x0A,0xF0,  /* 00000428    "inux.p.." */
-+    0x4F,0x53,0x54,0x50,0x08,0x50,0x42,0x52,  /* 00000430    "OSTP.PBR" */
-+    0x53,0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,  /* 00000438    "S.B..n.." */
-+    0x00,0x02,0x0C,0x00,0x00,0x00,0x00,0x00,  /* 00000440    "........" */
-+    0x1F,0x00,0x00,0x00,0x20,0x00,0x88,0x0D,  /* 00000448    ".... ..." */
-+    0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x00,  /* 00000450    "........" */
-+    0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x47,0x01,  /* 00000458    "......G." */
-+    0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,  /* 00000460    "........" */
-+    0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,  /* 00000468    "........" */
-+    0xFF,0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,  /* 00000470    "........" */
-+    0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x00,  /* 00000478    "........" */
-+    0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00,  /* 00000480    "........" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,  /* 00000488    "........" */
-+    0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00,  /* 00000490    "........" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,  /* 00000498    "........" */
-+    0xBF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000004A0    "........" */
-+    0xC0,0xFE,0x79,0x00,0x14,0x4F,0x04,0x5F,  /* 000004A8    "..y..O._" */
-+    0x43,0x52,0x53,0x00,0x8A,0x50,0x42,0x52,  /* 000004B0    "CRS..PBR" */
-+    0x53,0x0A,0x5C,0x4D,0x4D,0x49,0x4E,0x8A,  /* 000004B8    "S.\MMIN." */
-+    0x50,0x42,0x52,0x53,0x0A,0x60,0x4D,0x4D,  /* 000004C0    "PBRS.`MM" */
-+    0x41,0x58,0x8A,0x50,0x42,0x52,0x53,0x0A,  /* 000004C8    "AX.PBRS." */
-+    0x68,0x4D,0x4C,0x45,0x4E,0x7B,0x4D,0x4E,  /* 000004D0    "hMLEN{MN" */
-+    0x52,0x44,0x0A,0x03,0x0A,0x08,0x0C,0x00,  /* 000004D8    "RD......" */
-+    0xF0,0xFF,0xFF,0x4D,0x4D,0x49,0x4E,0x72,  /* 000004E0    "...MMINr" */
-+    0x74,0x4D,0x4D,0x41,0x58,0x4D,0x4D,0x49,  /* 000004E8    "tMMAXMMI" */
-+    0x4E,0x00,0x01,0x4D,0x4C,0x45,0x4E,0xA4,  /* 000004F0    "N..MLEN." */
-+    0x50,0x42,0x52,0x53,0x5B,0x80,0x4D,0x4E,  /* 000004F8    "PBRS[.MN" */
-+    0x52,0x5F,0x02,0x0A,0xD0,0x0A,0x10,0x5B,  /* 00000500    "R_.....[" */
-+    0x81,0x10,0x4D,0x4E,0x52,0x5F,0x03,0x4D,  /* 00000508    "..MNR_.M" */
-+    0x43,0x52,0x5F,0x20,0x4D,0x44,0x52,0x5F,  /* 00000510    "CR_ MDR_" */
-+    0x20,0x14,0x25,0x4D,0x4E,0x52,0x44,0x0A,  /* 00000518    " .%MNRD." */
-+    0x7D,0x79,0x68,0x0A,0x10,0x00,0x79,0x69,  /* 00000520    "}yh...yi" */
-+    0x0A,0x08,0x00,0x60,0x7D,0x60,0x0C,0xF0,  /* 00000528    "...`}`.." */
-+    0x00,0x00,0x10,0x60,0x70,0x60,0x4D,0x43,  /* 00000530    "...`p`MC" */
-+    0x52,0x5F,0xA4,0x4D,0x44,0x52,0x5F,0x14,  /* 00000538    "R_.MDR_." */
-+    0x26,0x4D,0x4E,0x57,0x52,0x0B,0x70,0x6A,  /* 00000540    "&MNWR.pj" */
-+    0x4D,0x44,0x52,0x5F,0x7D,0x79,0x68,0x0A,  /* 00000548    "MDR_}yh." */
-+    0x10,0x00,0x79,0x69,0x0A,0x08,0x00,0x60,  /* 00000550    "..yi...`" */
-+    0x7D,0x60,0x0C,0xF0,0x00,0x00,0x11,0x60,  /* 00000558    "}`.....`" */
-+    0x70,0x60,0x4D,0x43,0x52,0x5F,0x14,0x49,  /* 00000560    "p`MCR_.I" */
-+    0x1C,0x5F,0x50,0x52,0x54,0x00,0xA0,0x47,  /* 00000568    "._PRT..G" */
-+    0x11,0x93,0x47,0x50,0x49,0x43,0x00,0xA4,  /* 00000570    "..GPIC.." */
-+    0x12,0x4D,0x10,0x0D,0x12,0x13,0x04,0x0C,  /* 00000578    ".M......" */
-+    0xFF,0xFF,0x14,0x00,0x00,0x5E,0x2E,0x4C,  /* 00000580    ".....^.L" */
-+    0x50,0x43,0x5F,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000588    "PC_LNKA." */
-+    0x12,0x13,0x04,0x0C,0xFF,0xFF,0x14,0x00,  /* 00000590    "........" */
-+    0x01,0x5E,0x2E,0x4C,0x50,0x43,0x5F,0x4C,  /* 00000598    ".^.LPC_L" */
-+    0x4E,0x4B,0x42,0x00,0x12,0x14,0x04,0x0C,  /* 000005A0    "NKB....." */
-+    0xFF,0xFF,0x14,0x00,0x0A,0x02,0x5E,0x2E,  /* 000005A8    "......^." */
-+    0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,0x43,  /* 000005B0    "LPC_LNKC" */
-+    0x00,0x12,0x14,0x04,0x0C,0xFF,0xFF,0x14,  /* 000005B8    "........" */
-+    0x00,0x0A,0x03,0x5E,0x2E,0x4C,0x50,0x43,  /* 000005C0    "...^.LPC" */
-+    0x5F,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x13,  /* 000005C8    "_LNKD..." */
-+    0x04,0x0C,0xFF,0xFF,0x15,0x00,0x00,0x5E,  /* 000005D0    ".......^" */
-+    0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,  /* 000005D8    ".LPC_LNK" */
-+    0x41,0x00,0x12,0x13,0x04,0x0C,0xFF,0xFF,  /* 000005E0    "A......." */
-+    0x15,0x00,0x01,0x5E,0x2E,0x4C,0x50,0x43,  /* 000005E8    "...^.LPC" */
-+    0x5F,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x14,  /* 000005F0    "_LNKB..." */
-+    0x04,0x0C,0xFF,0xFF,0x15,0x00,0x0A,0x02,  /* 000005F8    "........" */
-+    0x5E,0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,  /* 00000600    "^.LPC_LN" */
-+    0x4B,0x43,0x00,0x12,0x14,0x04,0x0C,0xFF,  /* 00000608    "KC......" */
-+    0xFF,0x15,0x00,0x0A,0x03,0x5E,0x2E,0x4C,  /* 00000610    ".....^.L" */
-+    0x50,0x43,0x5F,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000618    "PC_LNKD." */
-+    0x12,0x13,0x04,0x0C,0xFF,0xFF,0x17,0x00,  /* 00000620    "........" */
-+    0x00,0x5E,0x2E,0x4C,0x50,0x43,0x5F,0x4C,  /* 00000628    ".^.LPC_L" */
-+    0x4E,0x4B,0x45,0x00,0x12,0x13,0x04,0x0C,  /* 00000630    "NKE....." */
-+    0xFF,0xFF,0x17,0x00,0x01,0x5E,0x2E,0x4C,  /* 00000638    ".....^.L" */
-+    0x50,0x43,0x5F,0x4C,0x4E,0x4B,0x46,0x00,  /* 00000640    "PC_LNKF." */
-+    0x12,0x14,0x04,0x0C,0xFF,0xFF,0x17,0x00,  /* 00000648    "........" */
-+    0x0A,0x02,0x5E,0x2E,0x4C,0x50,0x43,0x5F,  /* 00000650    "..^.LPC_" */
-+    0x4C,0x4E,0x4B,0x47,0x00,0x12,0x14,0x04,  /* 00000658    "LNKG...." */
-+    0x0C,0xFF,0xFF,0x17,0x00,0x0A,0x03,0x5E,  /* 00000660    ".......^" */
-+    0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,  /* 00000668    ".LPC_LNK" */
-+    0x48,0x00,0x12,0x13,0x04,0x0C,0xFF,0xFF,  /* 00000670    "H......." */
-+    0x1F,0x00,0x00,0x5E,0x2E,0x4C,0x50,0x43,  /* 00000678    "...^.LPC" */
-+    0x5F,0x4C,0x4E,0x4B,0x41,0x00,0xA1,0x49,  /* 00000680    "_LNKA..I" */
-+    0x0A,0xA4,0x12,0x45,0x0A,0x0D,0x12,0x0B,  /* 00000688    "...E...." */
-+    0x04,0x0C,0xFF,0xFF,0x14,0x00,0x00,0x00,  /* 00000690    "........" */
-+    0x0A,0x10,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000698    "........" */
-+    0x14,0x00,0x01,0x00,0x0A,0x11,0x12,0x0C,  /* 000006A0    "........" */
-+    0x04,0x0C,0xFF,0xFF,0x14,0x00,0x0A,0x02,  /* 000006A8    "........" */
-+    0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF,  /* 000006B0    "........" */
-+    0xFF,0x14,0x00,0x0A,0x03,0x00,0x0A,0x13,  /* 000006B8    "........" */
-+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x15,0x00,  /* 000006C0    "........" */
-+    0x00,0x00,0x0A,0x10,0x12,0x0B,0x04,0x0C,  /* 000006C8    "........" */
-+    0xFF,0xFF,0x15,0x00,0x01,0x00,0x0A,0x11,  /* 000006D0    "........" */
-+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x15,0x00,  /* 000006D8    "........" */
-+    0x0A,0x02,0x00,0x0A,0x12,0x12,0x0C,0x04,  /* 000006E0    "........" */
-+    0x0C,0xFF,0xFF,0x15,0x00,0x0A,0x03,0x00,  /* 000006E8    "........" */
-+    0x0A,0x13,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000006F0    "........" */
-+    0x17,0x00,0x00,0x00,0x0A,0x14,0x12,0x0B,  /* 000006F8    "........" */
-+    0x04,0x0C,0xFF,0xFF,0x17,0x00,0x01,0x00,  /* 00000700    "........" */
-+    0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000708    "........" */
-+    0x17,0x00,0x0A,0x02,0x00,0x0A,0x16,0x12,  /* 00000710    "........" */
-+    0x0C,0x04,0x0C,0xFF,0xFF,0x17,0x00,0x0A,  /* 00000718    "........" */
-+    0x03,0x00,0x0A,0x17,0x12,0x0B,0x04,0x0C,  /* 00000720    "........" */
-+    0xFF,0xFF,0x1F,0x00,0x00,0x00,0x0A,0x10,  /* 00000728    "........" */
-+    0x5B,0x82,0x45,0x0B,0x49,0x4F,0x43,0x4D,  /* 00000730    "[.E.IOCM" */
-+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000738    "._HID.A." */
-+    0x0C,0x02,0x08,0x43,0x52,0x53,0x5F,0x11,  /* 00000740    "...CRS_." */
-+    0x42,0x04,0x0A,0x3E,0x86,0x09,0x00,0x00,  /* 00000748    "B..>...." */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000750    "........" */
-+    0x86,0x09,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000758    "........" */
-+    0x00,0x00,0x00,0x00,0x86,0x09,0x00,0x00,  /* 00000760    "........" */
-+    0x00,0x00,0x0C,0x00,0x00,0x00,0x02,0x00,  /* 00000768    "........" */
-+    0x86,0x09,0x00,0x00,0x00,0x00,0x0E,0x00,  /* 00000770    "........" */
-+    0x00,0x00,0x02,0x00,0x86,0x09,0x00,0x00,  /* 00000778    "........" */
-+    0x00,0x00,0x80,0xFF,0x00,0x00,0x80,0x00,  /* 00000780    "........" */
-+    0x79,0x00,0x14,0x4C,0x05,0x5F,0x43,0x52,  /* 00000788    "y..L._CR" */
-+    0x53,0x00,0x8A,0x43,0x52,0x53,0x5F,0x0A,  /* 00000790    "S..CRS_." */
-+    0x04,0x4D,0x42,0x52,0x30,0x70,0x50,0x45,  /* 00000798    ".MBR0pPE" */
-+    0x58,0x42,0x4D,0x42,0x52,0x30,0x8A,0x43,  /* 000007A0    "XBMBR0.C" */
-+    0x52,0x53,0x5F,0x0A,0x08,0x4D,0x42,0x52,  /* 000007A8    "RS_..MBR" */
-+    0x31,0x70,0x50,0x45,0x58,0x53,0x4D,0x42,  /* 000007B0    "1pPEXSMB" */
-+    0x52,0x31,0x8A,0x43,0x52,0x53,0x5F,0x0A,  /* 000007B8    "R1.CRS_." */
-+    0x10,0x4D,0x42,0x52,0x32,0x70,0x52,0x43,  /* 000007C0    ".MBR2pRC" */
-+    0x42,0x42,0x4D,0x42,0x52,0x32,0x8A,0x43,  /* 000007C8    "BBMBR2.C" */
-+    0x52,0x53,0x5F,0x0A,0x14,0x4D,0x42,0x52,  /* 000007D0    "RS_..MBR" */
-+    0x33,0x70,0x52,0x43,0x42,0x53,0x4D,0x42,  /* 000007D8    "3pRCBSMB" */
-+    0x52,0x33,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 000007E0    "R3.CRS_[" */
-+    0x82,0x45,0x10,0x50,0x45,0x58,0x30,0x08,  /* 000007E8    ".E.PEX0." */
-+    0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x17,  /* 000007F0    "_ADR...." */
-+    0x00,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 000007F8    ".._PRW.." */
-+    0x02,0x0A,0x11,0x0A,0x03,0x5B,0x80,0x50,  /* 00000800    ".....[.P" */
-+    0x45,0x53,0x30,0x02,0x0A,0x40,0x0A,0xA0,  /* 00000808    "ES0..@.." */
-+    0x5B,0x81,0x48,0x04,0x50,0x45,0x53,0x30,  /* 00000810    "[.H.PES0" */
-+    0x00,0x00,0x40,0x0D,0x41,0x42,0x50,0x30,  /* 00000818    "..@.ABP0" */
-+    0x01,0x00,0x02,0x50,0x44,0x43,0x30,0x01,  /* 00000820    "...PDC0." */
-+    0x00,0x02,0x50,0x44,0x53,0x30,0x01,0x00,  /* 00000828    "..PDS0.." */
-+    0x01,0x4C,0x53,0x43,0x30,0x01,0x00,0x27,  /* 00000830    ".LSC0..'" */
-+    0x00,0x10,0x50,0x4D,0x53,0x30,0x01,0x00,  /* 00000838    "..PMS0.." */
-+    0x4F,0x3A,0x00,0x1E,0x48,0x50,0x45,0x30,  /* 00000840    "O:..HPE0" */
-+    0x01,0x50,0x43,0x45,0x30,0x01,0x00,0x1E,  /* 00000848    ".PCE0..." */
-+    0x48,0x50,0x53,0x30,0x01,0x50,0x43,0x53,  /* 00000850    "HPS0.PCS" */
-+    0x30,0x01,0x14,0x43,0x09,0x5F,0x50,0x52,  /* 00000858    "0..C._PR" */
-+    0x54,0x00,0xA0,0x4B,0x05,0x93,0x47,0x50,  /* 00000860    "T..K..GP" */
-+    0x49,0x43,0x00,0xA4,0x12,0x41,0x05,0x04,  /* 00000868    "IC...A.." */
-+    0x12,0x12,0x04,0x0B,0xFF,0xFF,0x00,0x5E,  /* 00000870    ".......^" */
-+    0x5E,0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,  /* 00000878    "^.LPC_LN" */
-+    0x4B,0x45,0x00,0x12,0x12,0x04,0x0B,0xFF,  /* 00000880    "KE......" */
-+    0xFF,0x01,0x5E,0x5E,0x2E,0x4C,0x50,0x43,  /* 00000888    "..^^.LPC" */
-+    0x5F,0x4C,0x4E,0x4B,0x46,0x00,0x12,0x13,  /* 00000890    "_LNKF..." */
-+    0x04,0x0B,0xFF,0xFF,0x0A,0x02,0x5E,0x5E,  /* 00000898    "......^^" */
-+    0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,  /* 000008A0    ".LPC_LNK" */
-+    0x47,0x00,0x12,0x13,0x04,0x0B,0xFF,0xFF,  /* 000008A8    "G......." */
-+    0x0A,0x03,0x5E,0x5E,0x2E,0x4C,0x50,0x43,  /* 000008B0    "..^^.LPC" */
-+    0x5F,0x4C,0x4E,0x4B,0x48,0x00,0xA1,0x2F,  /* 000008B8    "_LNKH../" */
-+    0xA4,0x12,0x2C,0x04,0x12,0x09,0x04,0x0B,  /* 000008C0    "..,....." */
-+    0xFF,0xFF,0x00,0x00,0x0A,0x14,0x12,0x09,  /* 000008C8    "........" */
-+    0x04,0x0B,0xFF,0xFF,0x01,0x00,0x0A,0x15,  /* 000008D0    "........" */
-+    0x12,0x0A,0x04,0x0B,0xFF,0xFF,0x0A,0x02,  /* 000008D8    "........" */
-+    0x00,0x0A,0x16,0x12,0x0A,0x04,0x0B,0xFF,  /* 000008E0    "........" */
-+    0xFF,0x0A,0x03,0x00,0x0A,0x17,0x5B,0x82,  /* 000008E8    "......[." */
-+    0x45,0x10,0x50,0x45,0x58,0x31,0x08,0x5F,  /* 000008F0    "E.PEX1._" */
-+    0x41,0x44,0x52,0x0C,0x01,0x00,0x17,0x00,  /* 000008F8    "ADR....." */
-+    0x08,0x5F,0x50,0x52,0x57,0x12,0x06,0x02,  /* 00000900    "._PRW..." */
-+    0x0A,0x11,0x0A,0x03,0x5B,0x80,0x50,0x45,  /* 00000908    "....[.PE" */
-+    0x53,0x31,0x02,0x0A,0x40,0x0A,0xA0,0x5B,  /* 00000910    "S1..@..[" */
-+    0x81,0x48,0x04,0x50,0x45,0x53,0x31,0x00,  /* 00000918    ".H.PES1." */
-+    0x00,0x40,0x0D,0x41,0x42,0x50,0x31,0x01,  /* 00000920    ".@.ABP1." */
-+    0x00,0x02,0x50,0x44,0x43,0x31,0x01,0x00,  /* 00000928    "..PDC1.." */
-+    0x02,0x50,0x44,0x53,0x31,0x01,0x00,0x01,  /* 00000930    ".PDS1..." */
-+    0x4C,0x53,0x43,0x31,0x01,0x00,0x27,0x00,  /* 00000938    "LSC1..'." */
-+    0x10,0x50,0x4D,0x53,0x31,0x01,0x00,0x4F,  /* 00000940    ".PMS1..O" */
-+    0x3A,0x00,0x1E,0x48,0x50,0x45,0x31,0x01,  /* 00000948    ":..HPE1." */
-+    0x50,0x43,0x45,0x31,0x01,0x00,0x1E,0x48,  /* 00000950    "PCE1...H" */
-+    0x50,0x53,0x31,0x01,0x50,0x43,0x53,0x31,  /* 00000958    "PS1.PCS1" */
-+    0x01,0x14,0x43,0x09,0x5F,0x50,0x52,0x54,  /* 00000960    "..C._PRT" */
-+    0x00,0xA0,0x4B,0x05,0x93,0x47,0x50,0x49,  /* 00000968    "..K..GPI" */
-+    0x43,0x00,0xA4,0x12,0x41,0x05,0x04,0x12,  /* 00000970    "C...A..." */
-+    0x12,0x04,0x0B,0xFF,0xFF,0x00,0x5E,0x5E,  /* 00000978    "......^^" */
-+    0x2E,0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,  /* 00000980    ".LPC_LNK" */
-+    0x46,0x00,0x12,0x12,0x04,0x0B,0xFF,0xFF,  /* 00000988    "F......." */
-+    0x01,0x5E,0x5E,0x2E,0x4C,0x50,0x43,0x5F,  /* 00000990    ".^^.LPC_" */
-+    0x4C,0x4E,0x4B,0x47,0x00,0x12,0x13,0x04,  /* 00000998    "LNKG...." */
-+    0x0B,0xFF,0xFF,0x0A,0x02,0x5E,0x5E,0x2E,  /* 000009A0    ".....^^." */
-+    0x4C,0x50,0x43,0x5F,0x4C,0x4E,0x4B,0x48,  /* 000009A8    "LPC_LNKH" */
-+    0x00,0x12,0x13,0x04,0x0B,0xFF,0xFF,0x0A,  /* 000009B0    "........" */
-+    0x03,0x5E,0x5E,0x2E,0x4C,0x50,0x43,0x5F,  /* 000009B8    ".^^.LPC_" */
-+    0x4C,0x4E,0x4B,0x45,0x00,0xA1,0x2F,0xA4,  /* 000009C0    "LNKE../." */
-+    0x12,0x2C,0x04,0x12,0x09,0x04,0x0B,0xFF,  /* 000009C8    ".,......" */
-+    0xFF,0x00,0x00,0x0A,0x15,0x12,0x09,0x04,  /* 000009D0    "........" */
-+    0x0B,0xFF,0xFF,0x01,0x00,0x0A,0x16,0x12,  /* 000009D8    "........" */
-+    0x0A,0x04,0x0B,0xFF,0xFF,0x0A,0x02,0x00,  /* 000009E0    "........" */
-+    0x0A,0x17,0x12,0x0A,0x04,0x0B,0xFF,0xFF,  /* 000009E8    "........" */
-+    0x0A,0x03,0x00,0x0A,0x14,0x5B,0x82,0x22,  /* 000009F0    ".....[."" */
-+    0x53,0x44,0x49,0x4F,0x08,0x5F,0x41,0x44,  /* 000009F8    "SDIO._AD" */
-+    0x52,0x0C,0x00,0x00,0x14,0x00,0x08,0x5F,  /* 00000A00    "R......_" */
-+    0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,0x50,  /* 00000A08    "STA..._P" */
-+    0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,0x0A,  /* 00000A10    "RW......" */
-+    0x03,0x5B,0x82,0x22,0x55,0x52,0x54,0x30,  /* 00000A18    ".[."URT0" */
-+    0x08,0x5F,0x41,0x44,0x52,0x0C,0x01,0x00,  /* 00000A20    "._ADR..." */
-+    0x14,0x00,0x08,0x5F,0x53,0x54,0x41,0x0A,  /* 00000A28    "..._STA." */
-+    0x0F,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 00000A30    ".._PRW.." */
-+    0x02,0x0A,0x0F,0x0A,0x03,0x5B,0x82,0x22,  /* 00000A38    ".....[."" */
-+    0x55,0x53,0x42,0x44,0x08,0x5F,0x41,0x44,  /* 00000A40    "USBD._AD" */
-+    0x52,0x0C,0x02,0x00,0x14,0x00,0x08,0x5F,  /* 00000A48    "R......_" */
-+    0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,0x50,  /* 00000A50    "STA..._P" */
-+    0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,0x0A,  /* 00000A58    "RW......" */
-+    0x03,0x5B,0x82,0x22,0x45,0x48,0x43,0x49,  /* 00000A60    ".[."EHCI" */
-+    0x08,0x5F,0x41,0x44,0x52,0x0C,0x03,0x00,  /* 00000A68    "._ADR..." */
-+    0x14,0x00,0x08,0x5F,0x53,0x54,0x41,0x0A,  /* 00000A70    "..._STA." */
-+    0x0F,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 00000A78    ".._PRW.." */
-+    0x02,0x0A,0x0F,0x0A,0x03,0x5B,0x82,0x22,  /* 00000A80    ".....[."" */
-+    0x4F,0x48,0x43,0x49,0x08,0x5F,0x41,0x44,  /* 00000A88    "OHCI._AD" */
-+    0x52,0x0C,0x04,0x00,0x14,0x00,0x08,0x5F,  /* 00000A90    "R......_" */
-+    0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,0x50,  /* 00000A98    "STA..._P" */
-+    0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,0x0A,  /* 00000AA0    "RW......" */
-+    0x03,0x5B,0x82,0x22,0x55,0x52,0x54,0x31,  /* 00000AA8    ".[."URT1" */
-+    0x08,0x5F,0x41,0x44,0x52,0x0C,0x05,0x00,  /* 00000AB0    "._ADR..." */
-+    0x14,0x00,0x08,0x5F,0x53,0x54,0x41,0x0A,  /* 00000AB8    "..._STA." */
-+    0x0F,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 00000AC0    ".._PRW.." */
-+    0x02,0x0A,0x0F,0x0A,0x03,0x5B,0x82,0x22,  /* 00000AC8    ".....[."" */
-+    0x45,0x4E,0x54,0x30,0x08,0x5F,0x41,0x44,  /* 00000AD0    "ENT0._AD" */
-+    0x52,0x0C,0x06,0x00,0x14,0x00,0x08,0x5F,  /* 00000AD8    "R......_" */
-+    0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,0x50,  /* 00000AE0    "STA..._P" */
-+    0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,0x0A,  /* 00000AE8    "RW......" */
-+    0x03,0x5B,0x82,0x22,0x45,0x4E,0x54,0x31,  /* 00000AF0    ".[."ENT1" */
-+    0x08,0x5F,0x41,0x44,0x52,0x0C,0x07,0x00,  /* 00000AF8    "._ADR..." */
-+    0x14,0x00,0x08,0x5F,0x53,0x54,0x41,0x0A,  /* 00000B00    "..._STA." */
-+    0x0F,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 00000B08    ".._PRW.." */
-+    0x02,0x0A,0x0F,0x0A,0x03,0x5B,0x82,0x4A,  /* 00000B10    ".....[.J" */
-+    0x16,0x53,0x50,0x49,0x30,0x08,0x5F,0x41,  /* 00000B18    ".SPI0._A" */
-+    0x44,0x52,0x0C,0x00,0x00,0x15,0x00,0x08,  /* 00000B20    "DR......" */
-+    0x5F,0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,  /* 00000B28    "_STA..._" */
-+    0x50,0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,  /* 00000B30    "PRW....." */
-+    0x0A,0x03,0x5B,0x82,0x42,0x0A,0x41,0x44,  /* 00000B38    "..[.B.AD" */
-+    0x43,0x31,0x08,0x5F,0x48,0x49,0x44,0x0D,  /* 00000B40    "C1._HID." */
-+    0x49,0x4E,0x54,0x33,0x34,0x39,0x34,0x00,  /* 00000B48    "INT3494." */
-+    0x08,0x5F,0x43,0x49,0x44,0x0D,0x49,0x4E,  /* 00000B50    "._CID.IN" */
-+    0x54,0x33,0x34,0x39,0x34,0x00,0x08,0x52,  /* 00000B58    "T3494..R" */
-+    0x42,0x55,0x46,0x11,0x48,0x05,0x0A,0x54,  /* 00000B60    "BUF.H..T" */
-+    0x8E,0x22,0x00,0x01,0x00,0x02,0x02,0x00,  /* 00000B68    "."......" */
-+    0x00,0x01,0x09,0x00,0x00,0x09,0x3D,0x00,  /* 00000B70    "......=." */
-+    0x10,0x00,0x01,0x00,0x00,0x5C,0x5F,0x53,  /* 00000B78    ".....\_S" */
-+    0x42,0x5F,0x2E,0x50,0x43,0x49,0x30,0x2E,  /* 00000B80    "B_.PCI0." */
-+    0x53,0x50,0x49,0x30,0x00,0x8C,0x2A,0x00,  /* 00000B88    "SPI0..*." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00000B90    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00000B98    "........" */
-+    0x2D,0x00,0x00,0x00,0x08,0x00,0x5C,0x5F,  /* 00000BA0    "-.....\_" */
-+    0x53,0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,  /* 00000BA8    "SB.PCI0." */
-+    0x47,0x49,0x50,0x30,0x2E,0x47,0x50,0x4F,  /* 00000BB0    "GIP0.GPO" */
-+    0x5F,0x00,0x79,0x00,0x14,0x0B,0x5F,0x43,  /* 00000BB8    "_.y..._C" */
-+    0x52,0x53,0x00,0xA4,0x52,0x42,0x55,0x46,  /* 00000BC0    "RS..RBUF" */
-+    0x14,0x15,0x5F,0x53,0x54,0x41,0x00,0xA0,  /* 00000BC8    ".._STA.." */
-+    0x0B,0x92,0x93,0x50,0x54,0x59,0x50,0x0A,  /* 00000BD0    "...PTYP." */
-+    0x06,0xA4,0x00,0xA4,0x0A,0x0F,0x5B,0x82,  /* 00000BD8    "......[." */
-+    0x41,0x0A,0x41,0x44,0x43,0x32,0x08,0x5F,  /* 00000BE0    "A.ADC2._" */
-+    0x48,0x49,0x44,0x0D,0x49,0x4E,0x54,0x33,  /* 00000BE8    "HID.INT3" */
-+    0x34,0x39,0x35,0x00,0x08,0x5F,0x43,0x49,  /* 00000BF0    "495.._CI" */
-+    0x44,0x0D,0x49,0x4E,0x54,0x33,0x34,0x39,  /* 00000BF8    "D.INT349" */
-+    0x35,0x00,0x08,0x52,0x42,0x55,0x46,0x11,  /* 00000C00    "5..RBUF." */
-+    0x47,0x05,0x0A,0x53,0x8E,0x21,0x00,0x01,  /* 00000C08    "G..S.!.." */
-+    0x00,0x02,0x02,0x00,0x00,0x01,0x09,0x00,  /* 00000C10    "........" */
-+    0x78,0x51,0xFE,0x00,0x10,0x01,0x01,0x00,  /* 00000C18    "xQ......" */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,  /* 00000C20    ".\_SB.PC" */
-+    0x49,0x30,0x2E,0x53,0x50,0x49,0x30,0x00,  /* 00000C28    "I0.SPI0." */
-+    0x8C,0x2A,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00000C30    ".*......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00000C38    "........" */
-+    0x00,0x19,0x00,0x2D,0x00,0x00,0x00,0x08,  /* 00000C40    "...-...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,  /* 00000C48    ".\_SB.PC" */
-+    0x49,0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,  /* 00000C50    "I0.GIP0." */
-+    0x47,0x50,0x4F,0x5F,0x00,0x79,0x00,0x14,  /* 00000C58    "GPO_.y.." */
-+    0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,0x52,  /* 00000C60    "._CRS..R" */
-+    0x42,0x55,0x46,0x14,0x15,0x5F,0x53,0x54,  /* 00000C68    "BUF.._ST" */
-+    0x41,0x00,0xA0,0x0B,0x92,0x93,0x50,0x54,  /* 00000C70    "A.....PT" */
-+    0x59,0x50,0x0A,0x08,0xA4,0x00,0xA4,0x0A,  /* 00000C78    "YP......" */
-+    0x0F,0x5B,0x82,0x22,0x53,0x50,0x49,0x31,  /* 00000C80    ".[."SPI1" */
-+    0x08,0x5F,0x41,0x44,0x52,0x0C,0x01,0x00,  /* 00000C88    "._ADR..." */
-+    0x15,0x00,0x08,0x5F,0x53,0x54,0x41,0x0A,  /* 00000C90    "..._STA." */
-+    0x0F,0x08,0x5F,0x50,0x52,0x57,0x12,0x06,  /* 00000C98    ".._PRW.." */
-+    0x02,0x0A,0x0F,0x0A,0x03,0x5B,0x82,0x43,  /* 00000CA0    ".....[.C" */
-+    0x06,0x47,0x49,0x50,0x30,0x08,0x5F,0x41,  /* 00000CA8    ".GIP0._A" */
-+    0x44,0x52,0x0C,0x02,0x00,0x15,0x00,0x08,  /* 00000CB0    "DR......" */
-+    0x5F,0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,  /* 00000CB8    "_STA..._" */
-+    0x50,0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,  /* 00000CC0    "PRW....." */
-+    0x0A,0x03,0x5B,0x82,0x1E,0x47,0x50,0x4F,  /* 00000CC8    "..[..GPO" */
-+    0x5F,0x08,0x5F,0x41,0x44,0x52,0x00,0x08,  /* 00000CD0    "_._ADR.." */
-+    0x5F,0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,  /* 00000CD8    "_STA..._" */
-+    0x50,0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,  /* 00000CE0    "PRW....." */
-+    0x0A,0x03,0x5B,0x82,0x1E,0x49,0x32,0x43,  /* 00000CE8    "..[..I2C" */
-+    0x5F,0x08,0x5F,0x41,0x44,0x52,0x01,0x08,  /* 00000CF0    "_._ADR.." */
-+    0x5F,0x53,0x54,0x41,0x0A,0x0F,0x08,0x5F,  /* 00000CF8    "_STA..._" */
-+    0x50,0x52,0x57,0x12,0x06,0x02,0x0A,0x0F,  /* 00000D00    "PRW....." */
-+    0x0A,0x03,0x5B,0x82,0x4C,0x9D,0x4C,0x50,  /* 00000D08    "..[.L.LP" */
-+    0x43,0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,  /* 00000D10    "C_._ADR." */
-+    0x00,0x00,0x1F,0x00,0x5B,0x80,0x50,0x52,  /* 00000D18    "....[.PR" */
-+    0x52,0x30,0x02,0x0A,0x60,0x0A,0x08,0x5B,  /* 00000D20    "R0..`..[" */
-+    0x81,0x2E,0x50,0x52,0x52,0x30,0x00,0x50,  /* 00000D28    "..PRR0.P" */
-+    0x49,0x52,0x41,0x08,0x50,0x49,0x52,0x42,  /* 00000D30    "IRA.PIRB" */
-+    0x08,0x50,0x49,0x52,0x43,0x08,0x50,0x49,  /* 00000D38    ".PIRC.PI" */
-+    0x52,0x44,0x08,0x50,0x49,0x52,0x45,0x08,  /* 00000D40    "RD.PIRE." */
-+    0x50,0x49,0x52,0x46,0x08,0x50,0x49,0x52,  /* 00000D48    "PIRF.PIR" */
-+    0x47,0x08,0x50,0x49,0x52,0x48,0x08,0x5B,  /* 00000D50    "G.PIRH.[" */
-+    0x82,0x47,0x0C,0x4C,0x4E,0x4B,0x41,0x08,  /* 00000D58    ".G.LNKA." */
-+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000D60    "_HID.A.." */
-+    0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x14,  /* 00000D68    ".._UID.." */
-+    0x18,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0C,  /* 00000D70    "._STA..." */
-+    0x7B,0x50,0x49,0x52,0x41,0x0A,0x80,0x00,  /* 00000D78    "{PIRA..." */
-+    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 00000D80    "........" */
-+    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000D88    ".._DIS.}" */
-+    0x50,0x49,0x52,0x41,0x0A,0x80,0x50,0x49,  /* 00000D90    "PIRA..PI" */
-+    0x52,0x41,0x14,0x45,0x04,0x5F,0x43,0x52,  /* 00000D98    "RA.E._CR" */
-+    0x53,0x08,0x08,0x42,0x55,0x46,0x30,0x11,  /* 00000DA0    "S..BUF0." */
-+    0x09,0x0A,0x06,0x23,0x01,0x00,0x18,0x79,  /* 00000DA8    "...#...y" */
-+    0x00,0x8B,0x42,0x55,0x46,0x30,0x01,0x49,  /* 00000DB0    "..BUF0.I" */
-+    0x52,0x51,0x57,0xA0,0x0C,0x7B,0x50,0x49,  /* 00000DB8    "RQW..{PI" */
-+    0x52,0x41,0x0A,0x80,0x00,0x70,0x00,0x60,  /* 00000DC0    "RA...p.`" */
-+    0xA1,0x04,0x70,0x01,0x60,0x79,0x60,0x7B,  /* 00000DC8    "..p.`y`{" */
-+    0x50,0x49,0x52,0x41,0x0A,0x0F,0x00,0x49,  /* 00000DD0    "PIRA...I" */
-+    0x52,0x51,0x57,0xA4,0x42,0x55,0x46,0x30,  /* 00000DD8    "RQW.BUF0" */
-+    0x08,0x5F,0x50,0x52,0x53,0x11,0x09,0x0A,  /* 00000DE0    "._PRS..." */
-+    0x06,0x23,0xB8,0x1E,0x18,0x79,0x00,0x14,  /* 00000DE8    ".#...y.." */
-+    0x30,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000DF0    "0_SRS..h" */
-+    0x01,0x49,0x52,0x51,0x57,0x82,0x49,0x52,  /* 00000DF8    ".IRQW.IR" */
-+    0x51,0x57,0x60,0xA0,0x0F,0x92,0x93,0x49,  /* 00000E00    "QW`....I" */
-+    0x52,0x51,0x57,0x00,0x7B,0x60,0x0A,0x7F,  /* 00000E08    "RQW.{`.." */
-+    0x60,0x76,0x60,0xA1,0x06,0x7D,0x60,0x0A,  /* 00000E10    "`v`..}`." */
-+    0x80,0x60,0x70,0x60,0x50,0x49,0x52,0x41,  /* 00000E18    ".`p`PIRA" */
-+    0x5B,0x82,0x48,0x0C,0x4C,0x4E,0x4B,0x42,  /* 00000E20    "[.H.LNKB" */
-+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000E28    "._HID.A." */
-+    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 00000E30    "..._UID." */
-+    0x02,0x14,0x18,0x5F,0x53,0x54,0x41,0x00,  /* 00000E38    "..._STA." */
-+    0xA0,0x0C,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 00000E40    "..{PIRB." */
-+    0x80,0x00,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000E48    "........" */
-+    0x0A,0x0B,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 00000E50    "...._DIS" */
-+    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 00000E58    ".}PIRB.." */
-+    0x50,0x49,0x52,0x42,0x14,0x45,0x04,0x5F,  /* 00000E60    "PIRB.E._" */
-+    0x43,0x52,0x53,0x08,0x08,0x42,0x55,0x46,  /* 00000E68    "CRS..BUF" */
-+    0x30,0x11,0x09,0x0A,0x06,0x23,0x01,0x00,  /* 00000E70    "0....#.." */
-+    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x30,  /* 00000E78    ".y..BUF0" */
-+    0x01,0x49,0x52,0x51,0x57,0xA0,0x0C,0x7B,  /* 00000E80    ".IRQW..{" */
-+    0x50,0x49,0x52,0x42,0x0A,0x80,0x00,0x70,  /* 00000E88    "PIRB...p" */
-+    0x00,0x60,0xA1,0x04,0x70,0x01,0x60,0x79,  /* 00000E90    ".`..p.`y" */
-+    0x60,0x7B,0x50,0x49,0x52,0x42,0x0A,0x0F,  /* 00000E98    "`{PIRB.." */
-+    0x00,0x49,0x52,0x51,0x57,0xA4,0x42,0x55,  /* 00000EA0    ".IRQW.BU" */
-+    0x46,0x30,0x08,0x5F,0x50,0x52,0x53,0x11,  /* 00000EA8    "F0._PRS." */
-+    0x09,0x0A,0x06,0x23,0xB8,0x1E,0x18,0x79,  /* 00000EB0    "...#...y" */
-+    0x00,0x14,0x30,0x5F,0x53,0x52,0x53,0x01,  /* 00000EB8    "..0_SRS." */
-+    0x8B,0x68,0x01,0x49,0x52,0x51,0x57,0x82,  /* 00000EC0    ".h.IRQW." */
-+    0x49,0x52,0x51,0x57,0x60,0xA0,0x0F,0x92,  /* 00000EC8    "IRQW`..." */
-+    0x93,0x49,0x52,0x51,0x57,0x00,0x7B,0x60,  /* 00000ED0    ".IRQW.{`" */
-+    0x0A,0x7F,0x60,0x76,0x60,0xA1,0x06,0x7D,  /* 00000ED8    "..`v`..}" */
-+    0x60,0x0A,0x80,0x60,0x70,0x60,0x50,0x49,  /* 00000EE0    "`..`p`PI" */
-+    0x52,0x42,0x5B,0x82,0x48,0x0C,0x4C,0x4E,  /* 00000EE8    "RB[.H.LN" */
-+    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000EF0    "KC._HID." */
-+    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 00000EF8    "A...._UI" */
-+    0x44,0x0A,0x03,0x14,0x18,0x5F,0x53,0x54,  /* 00000F00    "D...._ST" */
-+    0x41,0x00,0xA0,0x0C,0x7B,0x50,0x49,0x52,  /* 00000F08    "A...{PIR" */
-+    0x43,0x0A,0x80,0x00,0xA4,0x0A,0x09,0xA1,  /* 00000F10    "C......." */
-+    0x04,0xA4,0x0A,0x0B,0x14,0x11,0x5F,0x44,  /* 00000F18    "......_D" */
-+    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 00000F20    "IS.}PIRC" */
-+    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x45,  /* 00000F28    "..PIRC.E" */
-+    0x04,0x5F,0x43,0x52,0x53,0x08,0x08,0x42,  /* 00000F30    "._CRS..B" */
-+    0x55,0x46,0x30,0x11,0x09,0x0A,0x06,0x23,  /* 00000F38    "UF0....#" */
-+    0x01,0x00,0x18,0x79,0x00,0x8B,0x42,0x55,  /* 00000F40    "...y..BU" */
-+    0x46,0x30,0x01,0x49,0x52,0x51,0x57,0xA0,  /* 00000F48    "F0.IRQW." */
-+    0x0C,0x7B,0x50,0x49,0x52,0x43,0x0A,0x80,  /* 00000F50    ".{PIRC.." */
-+    0x00,0x70,0x00,0x60,0xA1,0x04,0x70,0x01,  /* 00000F58    ".p.`..p." */
-+    0x60,0x79,0x60,0x7B,0x50,0x49,0x52,0x43,  /* 00000F60    "`y`{PIRC" */
-+    0x0A,0x0F,0x00,0x49,0x52,0x51,0x57,0xA4,  /* 00000F68    "...IRQW." */
-+    0x42,0x55,0x46,0x30,0x08,0x5F,0x50,0x52,  /* 00000F70    "BUF0._PR" */
-+    0x53,0x11,0x09,0x0A,0x06,0x23,0xB8,0x1E,  /* 00000F78    "S....#.." */
-+    0x18,0x79,0x00,0x14,0x30,0x5F,0x53,0x52,  /* 00000F80    ".y..0_SR" */
-+    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000F88    "S..h.IRQ" */
-+    0x57,0x82,0x49,0x52,0x51,0x57,0x60,0xA0,  /* 00000F90    "W.IRQW`." */
-+    0x0F,0x92,0x93,0x49,0x52,0x51,0x57,0x00,  /* 00000F98    "...IRQW." */
-+    0x7B,0x60,0x0A,0x7F,0x60,0x76,0x60,0xA1,  /* 00000FA0    "{`..`v`." */
-+    0x06,0x7D,0x60,0x0A,0x80,0x60,0x70,0x60,  /* 00000FA8    ".}`..`p`" */
-+    0x50,0x49,0x52,0x43,0x5B,0x82,0x48,0x0C,  /* 00000FB0    "PIRC[.H." */
-+    0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,  /* 00000FB8    "LNKD._HI" */
-+    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 00000FC0    "D.A...._" */
-+    0x55,0x49,0x44,0x0A,0x04,0x14,0x18,0x5F,  /* 00000FC8    "UID...._" */
-+    0x53,0x54,0x41,0x00,0xA0,0x0C,0x7B,0x50,  /* 00000FD0    "STA...{P" */
-+    0x49,0x52,0x44,0x0A,0x80,0x00,0xA4,0x0A,  /* 00000FD8    "IRD....." */
-+    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x11,  /* 00000FE0    "........" */
-+    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000FE8    "_DIS.}PI" */
-+    0x52,0x44,0x0A,0x80,0x50,0x49,0x52,0x44,  /* 00000FF0    "RD..PIRD" */
-+    0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x08,  /* 00000FF8    ".E._CRS." */
-+    0x08,0x42,0x55,0x46,0x30,0x11,0x09,0x0A,  /* 00001000    ".BUF0..." */
-+    0x06,0x23,0x01,0x00,0x18,0x79,0x00,0x8B,  /* 00001008    ".#...y.." */
-+    0x42,0x55,0x46,0x30,0x01,0x49,0x52,0x51,  /* 00001010    "BUF0.IRQ" */
-+    0x57,0xA0,0x0C,0x7B,0x50,0x49,0x52,0x44,  /* 00001018    "W..{PIRD" */
-+    0x0A,0x80,0x00,0x70,0x00,0x60,0xA1,0x04,  /* 00001020    "...p.`.." */
-+    0x70,0x01,0x60,0x79,0x60,0x7B,0x50,0x49,  /* 00001028    "p.`y`{PI" */
-+    0x52,0x44,0x0A,0x0F,0x00,0x49,0x52,0x51,  /* 00001030    "RD...IRQ" */
-+    0x57,0xA4,0x42,0x55,0x46,0x30,0x08,0x5F,  /* 00001038    "W.BUF0._" */
-+    0x50,0x52,0x53,0x11,0x09,0x0A,0x06,0x23,  /* 00001040    "PRS....#" */
-+    0xB8,0x1E,0x18,0x79,0x00,0x14,0x30,0x5F,  /* 00001048    "...y..0_" */
-+    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00001050    "SRS..h.I" */
-+    0x52,0x51,0x57,0x82,0x49,0x52,0x51,0x57,  /* 00001058    "RQW.IRQW" */
-+    0x60,0xA0,0x0F,0x92,0x93,0x49,0x52,0x51,  /* 00001060    "`....IRQ" */
-+    0x57,0x00,0x7B,0x60,0x0A,0x7F,0x60,0x76,  /* 00001068    "W.{`..`v" */
-+    0x60,0xA1,0x06,0x7D,0x60,0x0A,0x80,0x60,  /* 00001070    "`..}`..`" */
-+    0x70,0x60,0x50,0x49,0x52,0x44,0x5B,0x82,  /* 00001078    "p`PIRD[." */
-+    0x48,0x0C,0x4C,0x4E,0x4B,0x45,0x08,0x5F,  /* 00001080    "H.LNKE._" */
-+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 00001088    "HID.A..." */
-+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x05,0x14,  /* 00001090    "._UID..." */
-+    0x18,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0C,  /* 00001098    "._STA..." */
-+    0x7B,0x50,0x49,0x52,0x45,0x0A,0x80,0x00,  /* 000010A0    "{PIRE..." */
-+    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 000010A8    "........" */
-+    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 000010B0    ".._DIS.}" */
-+    0x50,0x49,0x52,0x45,0x0A,0x80,0x50,0x49,  /* 000010B8    "PIRE..PI" */
-+    0x52,0x45,0x14,0x45,0x04,0x5F,0x43,0x52,  /* 000010C0    "RE.E._CR" */
-+    0x53,0x08,0x08,0x42,0x55,0x46,0x30,0x11,  /* 000010C8    "S..BUF0." */
-+    0x09,0x0A,0x06,0x23,0x01,0x00,0x18,0x79,  /* 000010D0    "...#...y" */
-+    0x00,0x8B,0x42,0x55,0x46,0x30,0x01,0x49,  /* 000010D8    "..BUF0.I" */
-+    0x52,0x51,0x57,0xA0,0x0C,0x7B,0x50,0x49,  /* 000010E0    "RQW..{PI" */
-+    0x52,0x45,0x0A,0x80,0x00,0x70,0x00,0x60,  /* 000010E8    "RE...p.`" */
-+    0xA1,0x04,0x70,0x01,0x60,0x79,0x60,0x7B,  /* 000010F0    "..p.`y`{" */
-+    0x50,0x49,0x52,0x45,0x0A,0x0F,0x00,0x49,  /* 000010F8    "PIRE...I" */
-+    0x52,0x51,0x57,0xA4,0x42,0x55,0x46,0x30,  /* 00001100    "RQW.BUF0" */
-+    0x08,0x5F,0x50,0x52,0x53,0x11,0x09,0x0A,  /* 00001108    "._PRS..." */
-+    0x06,0x23,0xB8,0x1E,0x18,0x79,0x00,0x14,  /* 00001110    ".#...y.." */
-+    0x30,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00001118    "0_SRS..h" */
-+    0x01,0x49,0x52,0x51,0x57,0x82,0x49,0x52,  /* 00001120    ".IRQW.IR" */
-+    0x51,0x57,0x60,0xA0,0x0F,0x92,0x93,0x49,  /* 00001128    "QW`....I" */
-+    0x52,0x51,0x57,0x00,0x7B,0x60,0x0A,0x7F,  /* 00001130    "RQW.{`.." */
-+    0x60,0x76,0x60,0xA1,0x06,0x7D,0x60,0x0A,  /* 00001138    "`v`..}`." */
-+    0x80,0x60,0x70,0x60,0x50,0x49,0x52,0x45,  /* 00001140    ".`p`PIRE" */
-+    0x5B,0x82,0x48,0x0C,0x4C,0x4E,0x4B,0x46,  /* 00001148    "[.H.LNKF" */
-+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00001150    "._HID.A." */
-+    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 00001158    "..._UID." */
-+    0x06,0x14,0x18,0x5F,0x53,0x54,0x41,0x00,  /* 00001160    "..._STA." */
-+    0xA0,0x0C,0x7B,0x50,0x49,0x52,0x46,0x0A,  /* 00001168    "..{PIRF." */
-+    0x80,0x00,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00001170    "........" */
-+    0x0A,0x0B,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 00001178    "...._DIS" */
-+    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 00001180    ".}PIRB.." */
-+    0x50,0x49,0x52,0x46,0x14,0x45,0x04,0x5F,  /* 00001188    "PIRF.E._" */
-+    0x43,0x52,0x53,0x08,0x08,0x42,0x55,0x46,  /* 00001190    "CRS..BUF" */
-+    0x30,0x11,0x09,0x0A,0x06,0x23,0x01,0x00,  /* 00001198    "0....#.." */
-+    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x30,  /* 000011A0    ".y..BUF0" */
-+    0x01,0x49,0x52,0x51,0x57,0xA0,0x0C,0x7B,  /* 000011A8    ".IRQW..{" */
-+    0x50,0x49,0x52,0x46,0x0A,0x80,0x00,0x70,  /* 000011B0    "PIRF...p" */
-+    0x00,0x60,0xA1,0x04,0x70,0x01,0x60,0x79,  /* 000011B8    ".`..p.`y" */
-+    0x60,0x7B,0x50,0x49,0x52,0x46,0x0A,0x0F,  /* 000011C0    "`{PIRF.." */
-+    0x00,0x49,0x52,0x51,0x57,0xA4,0x42,0x55,  /* 000011C8    ".IRQW.BU" */
-+    0x46,0x30,0x08,0x5F,0x50,0x52,0x53,0x11,  /* 000011D0    "F0._PRS." */
-+    0x09,0x0A,0x06,0x23,0xB8,0x1E,0x18,0x79,  /* 000011D8    "...#...y" */
-+    0x00,0x14,0x30,0x5F,0x53,0x52,0x53,0x01,  /* 000011E0    "..0_SRS." */
-+    0x8B,0x68,0x01,0x49,0x52,0x51,0x57,0x82,  /* 000011E8    ".h.IRQW." */
-+    0x49,0x52,0x51,0x57,0x60,0xA0,0x0F,0x92,  /* 000011F0    "IRQW`..." */
-+    0x93,0x49,0x52,0x51,0x57,0x00,0x7B,0x60,  /* 000011F8    ".IRQW.{`" */
-+    0x0A,0x7F,0x60,0x76,0x60,0xA1,0x06,0x7D,  /* 00001200    "..`v`..}" */
-+    0x60,0x0A,0x80,0x60,0x70,0x60,0x50,0x49,  /* 00001208    "`..`p`PI" */
-+    0x52,0x46,0x5B,0x82,0x48,0x0C,0x4C,0x4E,  /* 00001210    "RF[.H.LN" */
-+    0x4B,0x47,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00001218    "KG._HID." */
-+    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 00001220    "A...._UI" */
-+    0x44,0x0A,0x07,0x14,0x18,0x5F,0x53,0x54,  /* 00001228    "D...._ST" */
-+    0x41,0x00,0xA0,0x0C,0x7B,0x50,0x49,0x52,  /* 00001230    "A...{PIR" */
-+    0x47,0x0A,0x80,0x00,0xA4,0x0A,0x09,0xA1,  /* 00001238    "G......." */
-+    0x04,0xA4,0x0A,0x0B,0x14,0x11,0x5F,0x44,  /* 00001240    "......_D" */
-+    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x47,  /* 00001248    "IS.}PIRG" */
-+    0x0A,0x80,0x50,0x49,0x52,0x47,0x14,0x45,  /* 00001250    "..PIRG.E" */
-+    0x04,0x5F,0x43,0x52,0x53,0x08,0x08,0x42,  /* 00001258    "._CRS..B" */
-+    0x55,0x46,0x30,0x11,0x09,0x0A,0x06,0x23,  /* 00001260    "UF0....#" */
-+    0x01,0x00,0x18,0x79,0x00,0x8B,0x42,0x55,  /* 00001268    "...y..BU" */
-+    0x46,0x30,0x01,0x49,0x52,0x51,0x57,0xA0,  /* 00001270    "F0.IRQW." */
-+    0x0C,0x7B,0x50,0x49,0x52,0x47,0x0A,0x80,  /* 00001278    ".{PIRG.." */
-+    0x00,0x70,0x00,0x60,0xA1,0x04,0x70,0x01,  /* 00001280    ".p.`..p." */
-+    0x60,0x79,0x60,0x7B,0x50,0x49,0x52,0x47,  /* 00001288    "`y`{PIRG" */
-+    0x0A,0x0F,0x00,0x49,0x52,0x51,0x57,0xA4,  /* 00001290    "...IRQW." */
-+    0x42,0x55,0x46,0x30,0x08,0x5F,0x50,0x52,  /* 00001298    "BUF0._PR" */
-+    0x53,0x11,0x09,0x0A,0x06,0x23,0xB8,0x1E,  /* 000012A0    "S....#.." */
-+    0x18,0x79,0x00,0x14,0x30,0x5F,0x53,0x52,  /* 000012A8    ".y..0_SR" */
-+    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 000012B0    "S..h.IRQ" */
-+    0x57,0x82,0x49,0x52,0x51,0x57,0x60,0xA0,  /* 000012B8    "W.IRQW`." */
-+    0x0F,0x92,0x93,0x49,0x52,0x51,0x57,0x00,  /* 000012C0    "...IRQW." */
-+    0x7B,0x60,0x0A,0x7F,0x60,0x76,0x60,0xA1,  /* 000012C8    "{`..`v`." */
-+    0x06,0x7D,0x60,0x0A,0x80,0x60,0x70,0x60,  /* 000012D0    ".}`..`p`" */
-+    0x50,0x49,0x52,0x47,0x5B,0x82,0x48,0x0C,  /* 000012D8    "PIRG[.H." */
-+    0x4C,0x4E,0x4B,0x48,0x08,0x5F,0x48,0x49,  /* 000012E0    "LNKH._HI" */
-+    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 000012E8    "D.A...._" */
-+    0x55,0x49,0x44,0x0A,0x08,0x14,0x18,0x5F,  /* 000012F0    "UID...._" */
-+    0x53,0x54,0x41,0x00,0xA0,0x0C,0x7B,0x50,  /* 000012F8    "STA...{P" */
-+    0x49,0x52,0x48,0x0A,0x80,0x00,0xA4,0x0A,  /* 00001300    "IRH....." */
-+    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x11,  /* 00001308    "........" */
-+    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00001310    "_DIS.}PI" */
-+    0x52,0x48,0x0A,0x80,0x50,0x49,0x52,0x48,  /* 00001318    "RH..PIRH" */
-+    0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x08,  /* 00001320    ".E._CRS." */
-+    0x08,0x42,0x55,0x46,0x30,0x11,0x09,0x0A,  /* 00001328    ".BUF0..." */
-+    0x06,0x23,0x01,0x00,0x18,0x79,0x00,0x8B,  /* 00001330    ".#...y.." */
-+    0x42,0x55,0x46,0x30,0x01,0x49,0x52,0x51,  /* 00001338    "BUF0.IRQ" */
-+    0x57,0xA0,0x0C,0x7B,0x50,0x49,0x52,0x48,  /* 00001340    "W..{PIRH" */
-+    0x0A,0x80,0x00,0x70,0x00,0x60,0xA1,0x04,  /* 00001348    "...p.`.." */
-+    0x70,0x01,0x60,0x79,0x60,0x7B,0x50,0x49,  /* 00001350    "p.`y`{PI" */
-+    0x52,0x48,0x0A,0x0F,0x00,0x49,0x52,0x51,  /* 00001358    "RH...IRQ" */
-+    0x57,0xA4,0x42,0x55,0x46,0x30,0x08,0x5F,  /* 00001360    "W.BUF0._" */
-+    0x50,0x52,0x53,0x11,0x09,0x0A,0x06,0x23,  /* 00001368    "PRS....#" */
-+    0xB8,0x1E,0x18,0x79,0x00,0x14,0x30,0x5F,  /* 00001370    "...y..0_" */
-+    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00001378    "SRS..h.I" */
-+    0x52,0x51,0x57,0x82,0x49,0x52,0x51,0x57,  /* 00001380    "RQW.IRQW" */
-+    0x60,0xA0,0x0F,0x92,0x93,0x49,0x52,0x51,  /* 00001388    "`....IRQ" */
-+    0x57,0x00,0x7B,0x60,0x0A,0x7F,0x60,0x76,  /* 00001390    "W.{`..`v" */
-+    0x60,0xA1,0x06,0x7D,0x60,0x0A,0x80,0x60,  /* 00001398    "`..}`..`" */
-+    0x70,0x60,0x50,0x49,0x52,0x48,0x5B,0x82,  /* 000013A0    "p`PIRH[." */
-+    0x42,0x06,0x52,0x54,0x43,0x5F,0x08,0x5F,  /* 000013A8    "B.RTC_._" */
-+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00,  /* 000013B0    "HID.A..." */
-+    0x08,0x42,0x55,0x46,0x30,0x11,0x15,0x0A,  /* 000013B8    ".BUF0..." */
-+    0x12,0x47,0x01,0x70,0x00,0x70,0x00,0x01,  /* 000013C0    ".G.p.p.." */
-+    0x04,0x47,0x01,0x74,0x00,0x74,0x00,0x01,  /* 000013C8    ".G.t.t.." */
-+    0x04,0x79,0x00,0x08,0x42,0x55,0x46,0x31,  /* 000013D0    ".y..BUF1" */
-+    0x11,0x18,0x0A,0x15,0x47,0x01,0x70,0x00,  /* 000013D8    "....G.p." */
-+    0x70,0x00,0x01,0x04,0x47,0x01,0x74,0x00,  /* 000013E0    "p...G.t." */
-+    0x74,0x00,0x01,0x04,0x22,0x00,0x01,0x79,  /* 000013E8    "t..."..y" */
-+    0x00,0x14,0x18,0x5F,0x43,0x52,0x53,0x08,  /* 000013F0    "..._CRS." */
-+    0xA0,0x0A,0x48,0x50,0x45,0x41,0xA4,0x42,  /* 000013F8    "..HPEA.B" */
-+    0x55,0x46,0x30,0xA1,0x06,0xA4,0x42,0x55,  /* 00001400    "UF0...BU" */
-+    0x46,0x31,0x5B,0x82,0x30,0x50,0x49,0x43,  /* 00001408    "F1[.0PIC" */
-+    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41,  /* 00001410    "_._HID.A" */
-+    0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x1D,  /* 00001418    ".._CRS.." */
-+    0x0A,0x1A,0x47,0x01,0x20,0x00,0x20,0x00,  /* 00001420    "..G. . ." */
-+    0x01,0x1E,0x47,0x01,0xA0,0x00,0xA0,0x00,  /* 00001428    "..G....." */
-+    0x01,0x1E,0x47,0x01,0xD0,0x04,0xD0,0x04,  /* 00001430    "..G....." */
-+    0x01,0x02,0x79,0x00,0x5B,0x82,0x42,0x06,  /* 00001438    "..y.[.B." */
-+    0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49,  /* 00001440    "TMR_._HI" */
-+    0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x42,  /* 00001448    "D.A....B" */
-+    0x55,0x46,0x30,0x11,0x15,0x0A,0x12,0x47,  /* 00001450    "UF0....G" */
-+    0x01,0x40,0x00,0x40,0x00,0x01,0x04,0x47,  /* 00001458    ".@.@...G" */
-+    0x01,0x50,0x00,0x50,0x00,0x01,0x04,0x79,  /* 00001460    ".P.P...y" */
-+    0x00,0x08,0x42,0x55,0x46,0x31,0x11,0x18,  /* 00001468    "..BUF1.." */
-+    0x0A,0x15,0x47,0x01,0x40,0x00,0x40,0x00,  /* 00001470    "..G.@.@." */
-+    0x01,0x04,0x47,0x01,0x50,0x00,0x50,0x00,  /* 00001478    "..G.P.P." */
-+    0x01,0x04,0x22,0x01,0x00,0x79,0x00,0x14,  /* 00001480    ".."..y.." */
-+    0x18,0x5F,0x43,0x52,0x53,0x08,0xA0,0x0A,  /* 00001488    "._CRS..." */
-+    0x48,0x50,0x45,0x41,0xA4,0x42,0x55,0x46,  /* 00001490    "HPEA.BUF" */
-+    0x30,0xA1,0x06,0xA4,0x42,0x55,0x46,0x31,  /* 00001498    "0...BUF1" */
-+    0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,0x08,  /* 000014A0    "[."SPKR." */
-+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x08,  /* 000014A8    "_HID.A.." */
-+    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x0D,  /* 000014B0    ".._CRS.." */
-+    0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,0x00,  /* 000014B8    "..G.a.a." */
-+    0x01,0x01,0x79,0x00,0x5B,0x82,0x49,0x19,  /* 000014C0    "..y.[.I." */
-+    0x58,0x54,0x52,0x41,0x08,0x5F,0x48,0x49,  /* 000014C8    "XTRA._HI" */
-+    0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08,0x43,  /* 000014D0    "D.A....C" */
-+    0x52,0x53,0x5F,0x11,0x46,0x08,0x0A,0x82,  /* 000014D8    "RS_.F..." */
-+    0x47,0x01,0x2E,0x00,0x2E,0x00,0x01,0x02,  /* 000014E0    "G......." */
-+    0x47,0x01,0x4E,0x00,0x2E,0x00,0x01,0x02,  /* 000014E8    "G.N....." */
-+    0x47,0x01,0x63,0x00,0x61,0x00,0x01,0x01,  /* 000014F0    "G.c.a..." */
-+    0x47,0x01,0x65,0x00,0x61,0x00,0x01,0x01,  /* 000014F8    "G.e.a..." */
-+    0x47,0x01,0x67,0x00,0x61,0x00,0x01,0x01,  /* 00001500    "G.g.a..." */
-+    0x47,0x01,0x80,0x00,0x80,0x00,0x01,0x01,  /* 00001508    "G......." */
-+    0x47,0x01,0x84,0x00,0x84,0x00,0x01,0x04,  /* 00001510    "G......." */
-+    0x47,0x01,0x88,0x00,0x88,0x00,0x01,0x01,  /* 00001518    "G......." */
-+    0x47,0x01,0x8C,0x00,0x8C,0x00,0x01,0x03,  /* 00001520    "G......." */
-+    0x47,0x01,0x92,0x00,0x92,0x00,0x01,0x01,  /* 00001528    "G......." */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x10,  /* 00001530    "G......." */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x10,  /* 00001538    "G......." */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x40,  /* 00001540    "G......@" */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x40,  /* 00001548    "G......@" */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x40,  /* 00001550    "G......@" */
-+    0x47,0x01,0x00,0x00,0x00,0x00,0x01,0x40,  /* 00001558    "G......@" */
-+    0x79,0x00,0x14,0x4C,0x0F,0x5F,0x43,0x52,  /* 00001560    "y..L._CR" */
-+    0x53,0x00,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 00001568    "S..CRS_." */
-+    0x52,0x4D,0x42,0x52,0x30,0x70,0x50,0x31,  /* 00001570    "RMBR0pP1" */
-+    0x42,0x42,0x4D,0x42,0x52,0x30,0x8B,0x43,  /* 00001578    "BBMBR0.C" */
-+    0x52,0x53,0x5F,0x0A,0x54,0x4D,0x42,0x52,  /* 00001580    "RS_.TMBR" */
-+    0x31,0x70,0x50,0x31,0x42,0x42,0x4D,0x42,  /* 00001588    "1pP1BBMB" */
-+    0x52,0x31,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 00001590    "R1.CRS_." */
-+    0x5A,0x4D,0x42,0x52,0x32,0x70,0x50,0x42,  /* 00001598    "ZMBR2pPB" */
-+    0x41,0x42,0x4D,0x42,0x52,0x32,0x8B,0x43,  /* 000015A0    "ABMBR2.C" */
-+    0x52,0x53,0x5F,0x0A,0x5C,0x4D,0x42,0x52,  /* 000015A8    "RS_.\MBR" */
-+    0x33,0x70,0x50,0x42,0x41,0x42,0x4D,0x42,  /* 000015B0    "3pPBABMB" */
-+    0x52,0x33,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 000015B8    "R3.CRS_." */
-+    0x62,0x4D,0x42,0x52,0x34,0x70,0x47,0x50,  /* 000015C0    "bMBR4pGP" */
-+    0x30,0x42,0x4D,0x42,0x52,0x34,0x8B,0x43,  /* 000015C8    "0BMBR4.C" */
-+    0x52,0x53,0x5F,0x0A,0x64,0x4D,0x42,0x52,  /* 000015D0    "RS_.dMBR" */
-+    0x35,0x70,0x47,0x50,0x30,0x42,0x4D,0x42,  /* 000015D8    "5pGP0BMB" */
-+    0x52,0x35,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 000015E0    "R5.CRS_." */
-+    0x6A,0x4D,0x42,0x52,0x36,0x70,0x47,0x50,  /* 000015E8    "jMBR6pGP" */
-+    0x41,0x42,0x4D,0x42,0x52,0x36,0x8B,0x43,  /* 000015F0    "ABMBR6.C" */
-+    0x52,0x53,0x5F,0x0A,0x6C,0x4D,0x42,0x52,  /* 000015F8    "RS_.lMBR" */
-+    0x37,0x70,0x47,0x50,0x41,0x42,0x4D,0x42,  /* 00001600    "7pGPABMB" */
-+    0x52,0x37,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 00001608    "R7.CRS_." */
-+    0x72,0x4D,0x42,0x52,0x38,0x70,0x53,0x4D,  /* 00001610    "rMBR8pSM" */
-+    0x42,0x42,0x4D,0x42,0x52,0x38,0x8B,0x43,  /* 00001618    "BBMBR8.C" */
-+    0x52,0x53,0x5F,0x0A,0x74,0x4D,0x42,0x52,  /* 00001620    "RS_.tMBR" */
-+    0x39,0x70,0x53,0x4D,0x42,0x42,0x4D,0x42,  /* 00001628    "9pSMBBMB" */
-+    0x52,0x39,0x8B,0x43,0x52,0x53,0x5F,0x0A,  /* 00001630    "R9.CRS_." */
-+    0x7A,0x4D,0x42,0x52,0x41,0x70,0x57,0x44,  /* 00001638    "zMBRApWD" */
-+    0x54,0x42,0x4D,0x42,0x52,0x41,0x8B,0x43,  /* 00001640    "TBMBRA.C" */
-+    0x52,0x53,0x5F,0x0A,0x7C,0x4D,0x42,0x52,  /* 00001648    "RS_.|MBR" */
-+    0x42,0x70,0x57,0x44,0x54,0x42,0x4D,0x42,  /* 00001650    "BpWDTBMB" */
-+    0x52,0x42,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 00001658    "RB.CRS_[" */
-+    0x82,0x47,0x08,0x48,0x50,0x45,0x54,0x08,  /* 00001660    ".G.HPET." */
-+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01,  /* 00001668    "_HID.A.." */
-+    0x03,0x08,0x42,0x55,0x46,0x30,0x11,0x17,  /* 00001670    "..BUF0.." */
-+    0x0A,0x14,0x22,0x01,0x00,0x22,0x00,0x01,  /* 00001678    ".."..".." */
-+    0x86,0x09,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00001680    "........" */
-+    0x00,0x00,0x00,0x00,0x79,0x00,0x14,0x25,  /* 00001688    "....y..%" */
-+    0x5F,0x53,0x54,0x41,0x00,0xA0,0x11,0x92,  /* 00001690    "_STA...." */
-+    0x95,0x4F,0x53,0x54,0x50,0x01,0xA0,0x08,  /* 00001698    ".OSTP..." */
-+    0x48,0x50,0x45,0x41,0xA4,0x0A,0x0F,0xA1,  /* 000016A0    "HPEA...." */
-+    0x0A,0xA0,0x08,0x48,0x50,0x45,0x41,0xA4,  /* 000016A8    "...HPEA." */
-+    0x0A,0x0B,0xA4,0x00,0x14,0x33,0x5F,0x43,  /* 000016B0    ".....3_C" */
-+    0x52,0x53,0x08,0x8A,0x42,0x55,0x46,0x30,  /* 000016B8    "RS..BUF0" */
-+    0x0A,0x0A,0x4D,0x42,0x52,0x30,0x70,0x48,  /* 000016C0    "..MBR0pH" */
-+    0x50,0x54,0x42,0x4D,0x42,0x52,0x30,0x8A,  /* 000016C8    "PTBMBR0." */
-+    0x42,0x55,0x46,0x30,0x0A,0x0E,0x4D,0x42,  /* 000016D0    "BUF0..MB" */
-+    0x52,0x31,0x70,0x48,0x50,0x54,0x53,0x4D,  /* 000016D8    "R1pHPTSM" */
-+    0x42,0x52,0x31,0xA4,0x42,0x55,0x46,0x30,  /* 000016E0    "BR1.BUF0" */
-+    0x5B,0x82,0x4B,0x05,0x41,0x50,0x49,0x43,  /* 000016E8    "[.K.APIC" */
-+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000016F0    "._HID.A." */
-+    0x00,0x03,0x08,0x43,0x52,0x53,0x5F,0x11,  /* 000016F8    "...CRS_." */
-+    0x11,0x0A,0x0E,0x86,0x09,0x00,0x00,0x00,  /* 00001700    "........" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,  /* 00001708    ".......y" */
-+    0x00,0x14,0x33,0x5F,0x43,0x52,0x53,0x00,  /* 00001710    "..3_CRS." */
-+    0x8A,0x43,0x52,0x53,0x5F,0x0A,0x04,0x4D,  /* 00001718    ".CRS_..M" */
-+    0x42,0x52,0x30,0x70,0x41,0x50,0x43,0x42,  /* 00001720    "BR0pAPCB" */
-+    0x4D,0x42,0x52,0x30,0x8A,0x43,0x52,0x53,  /* 00001728    "MBR0.CRS" */
-+    0x5F,0x0A,0x08,0x4D,0x42,0x52,0x31,0x70,  /* 00001730    "_..MBR1p" */
-+    0x41,0x50,0x43,0x53,0x4D,0x42,0x52,0x31,  /* 00001738    "APCSMBR1" */
-+    0xA4,0x43,0x52,0x53,0x5F,0x5B,0x82,0x47,  /* 00001740    ".CRS_[.G" */
-+    0x0B,0x54,0x50,0x4D,0x5F,0x08,0x5F,0x48,  /* 00001748    ".TPM_._H" */
-+    0x49,0x44,0x0C,0x25,0xD4,0x34,0x93,0x08,  /* 00001750    "ID.%.4.." */
-+    0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00001758    "_CID.A.." */
-+    0x31,0x08,0x5F,0x53,0x54,0x52,0x11,0x42,  /* 00001760    "1._STR.B" */
-+    0x05,0x0A,0x4E,0x49,0x00,0x6E,0x00,0x66,  /* 00001768    "..NI.n.f" */
-+    0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x6F,  /* 00001770    ".i.n.e.o" */
-+    0x00,0x6E,0x00,0x20,0x00,0x54,0x00,0x50,  /* 00001778    ".n. .T.P" */
-+    0x00,0x4D,0x00,0x20,0x00,0x31,0x00,0x2E,  /* 00001780    ".M. .1.." */
-+    0x00,0x32,0x00,0x20,0x00,0x44,0x00,0x65,  /* 00001788    ".2. .D.e" */
-+    0x00,0x76,0x00,0x69,0x00,0x63,0x00,0x65,  /* 00001790    ".v.i.c.e" */
-+    0x00,0x20,0x00,0x28,0x00,0x53,0x00,0x4C,  /* 00001798    ". .(.S.L" */
-+    0x00,0x42,0x00,0x39,0x00,0x36,0x00,0x34,  /* 000017A0    ".B.9.6.4" */
-+    0x00,0x35,0x00,0x54,0x00,0x54,0x00,0x31,  /* 000017A8    ".5.T.T.1" */
-+    0x00,0x2E,0x00,0x32,0x00,0x29,0x00,0x00,  /* 000017B0    "...2.).." */
-+    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x2B,  /* 000017B8    ".._CRS.+" */
-+    0x0A,0x28,0x8E,0x23,0x00,0x01,0x00,0x01,  /* 000017C0    ".(.#...." */
-+    0x02,0x00,0x00,0x01,0x06,0x00,0x80,0x1A,  /* 000017C8    "........" */
-+    0x06,0x00,0x20,0x00,0x5C,0x5F,0x53,0x42,  /* 000017D0    ".. .\_SB" */
-+    0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,0x49,  /* 000017D8    ".PCI0.GI" */
-+    0x50,0x30,0x2E,0x49,0x32,0x43,0x5F,0x00,  /* 000017E0    "P0.I2C_." */
-+    0x79,0x00,0x14,0x13,0x5F,0x53,0x54,0x41,  /* 000017E8    "y..._STA" */
-+    0x00,0xA0,0x09,0x93,0x54,0x50,0x4D,0x50,  /* 000017F0    "....TPMP" */
-+    0x00,0xA4,0x00,0xA4,0x0A,0x0F,0x5B,0x82,  /* 000017F8    "......[." */
-+    0x45,0x0C,0x43,0x59,0x38,0x43,0x08,0x5F,  /* 00001800    "E.CY8C._" */
-+    0x48,0x49,0x44,0x0D,0x49,0x4E,0x54,0x33,  /* 00001808    "HID.INT3" */
-+    0x34,0x39,0x30,0x00,0x08,0x5F,0x43,0x49,  /* 00001810    "490.._CI" */
-+    0x44,0x0D,0x49,0x4E,0x54,0x33,0x34,0x39,  /* 00001818    "D.INT349" */
-+    0x30,0x00,0x08,0x52,0x42,0x55,0x46,0x11,  /* 00001820    "0..RBUF." */
-+    0x48,0x05,0x0A,0x54,0x8E,0x23,0x00,0x01,  /* 00001828    "H..T.#.." */
-+    0x00,0x01,0x02,0x00,0x00,0x01,0x06,0x00,  /* 00001830    "........" */
-+    0xA0,0x86,0x01,0x00,0x20,0x00,0x5C,0x5F,  /* 00001838    ".... .\_" */
-+    0x53,0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,  /* 00001840    "SB.PCI0." */
-+    0x47,0x49,0x50,0x30,0x2E,0x49,0x32,0x43,  /* 00001848    "GIP0.I2C" */
-+    0x5F,0x00,0x8C,0x29,0x00,0x01,0x00,0x01,  /* 00001850    "_..)...." */
-+    0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00001858    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x2C,0x00,0x00,  /* 00001860    ".....,.." */
-+    0x00,0x0D,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00001868    "...\_SB." */
-+    0x50,0x43,0x49,0x30,0x2E,0x47,0x49,0x50,  /* 00001870    "PCI0.GIP" */
-+    0x30,0x2E,0x47,0x50,0x4F,0x00,0x79,0x00,  /* 00001878    "0.GPO.y." */
-+    0x14,0x2E,0x5F,0x43,0x52,0x53,0x00,0x8C,  /* 00001880    ".._CRS.." */
-+    0x52,0x42,0x55,0x46,0x0A,0x10,0x4F,0x42,  /* 00001888    "RBUF..OB" */
-+    0x31,0x5F,0xA0,0x0E,0x93,0x41,0x4C,0x54,  /* 00001890    "1_...ALT" */
-+    0x53,0x00,0x70,0x0A,0x20,0x4F,0x42,0x31,  /* 00001898    "S.p. OB1" */
-+    0x5F,0xA1,0x08,0x70,0x0A,0x21,0x4F,0x42,  /* 000018A0    "_..p.!OB" */
-+    0x31,0x5F,0xA4,0x52,0x42,0x55,0x46,0x14,  /* 000018A8    "1_.RBUF." */
-+    0x15,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0B,  /* 000018B0    "._STA..." */
-+    0x92,0x93,0x50,0x54,0x59,0x50,0x0A,0x06,  /* 000018B8    "..PTYP.." */
-+    0xA4,0x00,0xA4,0x0A,0x0F,0x5B,0x82,0x4B,  /* 000018C0    ".....[.K" */
-+    0x07,0x4E,0x49,0x4F,0x31,0x08,0x5F,0x48,  /* 000018C8    ".NIO1._H" */
-+    0x49,0x44,0x0D,0x49,0x4E,0x54,0x33,0x34,  /* 000018D0    "ID.INT34" */
-+    0x39,0x31,0x00,0x08,0x5F,0x43,0x49,0x44,  /* 000018D8    "91.._CID" */
-+    0x0D,0x49,0x4E,0x54,0x33,0x34,0x39,0x31,  /* 000018E0    ".INT3491" */
-+    0x00,0x08,0x5F,0x55,0x49,0x44,0x01,0x08,  /* 000018E8    ".._UID.." */
-+    0x52,0x42,0x55,0x46,0x11,0x2B,0x0A,0x28,  /* 000018F0    "RBUF.+.(" */
-+    0x8E,0x23,0x00,0x01,0x00,0x01,0x02,0x00,  /* 000018F8    ".#......" */
-+    0x00,0x01,0x06,0x00,0x80,0x1A,0x06,0x00,  /* 00001900    "........" */
-+    0x25,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,  /* 00001908    "%.\_SB.P" */
-+    0x43,0x49,0x30,0x2E,0x47,0x49,0x50,0x30,  /* 00001910    "CI0.GIP0" */
-+    0x2E,0x49,0x32,0x43,0x5F,0x00,0x79,0x00,  /* 00001918    ".I2C_.y." */
-+    0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,  /* 00001920    ".._CRS.." */
-+    0x52,0x42,0x55,0x46,0x14,0x15,0x5F,0x53,  /* 00001928    "RBUF.._S" */
-+    0x54,0x41,0x00,0xA0,0x0B,0x92,0x93,0x50,  /* 00001930    "TA.....P" */
-+    0x54,0x59,0x50,0x0A,0x08,0xA4,0x00,0xA4,  /* 00001938    "TYP....." */
-+    0x0A,0x0F,0x5B,0x82,0x4C,0x07,0x4E,0x49,  /* 00001940    "..[.L.NI" */
-+    0x4F,0x32,0x08,0x5F,0x48,0x49,0x44,0x0D,  /* 00001948    "O2._HID." */
-+    0x49,0x4E,0x54,0x33,0x34,0x39,0x31,0x00,  /* 00001950    "INT3491." */
-+    0x08,0x5F,0x43,0x49,0x44,0x0D,0x49,0x4E,  /* 00001958    "._CID.IN" */
-+    0x54,0x33,0x34,0x39,0x31,0x00,0x08,0x5F,  /* 00001960    "T3491.._" */
-+    0x55,0x49,0x44,0x0A,0x02,0x08,0x52,0x42,  /* 00001968    "UID...RB" */
-+    0x55,0x46,0x11,0x2B,0x0A,0x28,0x8E,0x23,  /* 00001970    "UF.+.(.#" */
-+    0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x01,  /* 00001978    "........" */
-+    0x06,0x00,0x80,0x1A,0x06,0x00,0x26,0x00,  /* 00001980    "......&." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,  /* 00001988    "\_SB.PCI" */
-+    0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,0x49,  /* 00001990    "0.GIP0.I" */
-+    0x32,0x43,0x5F,0x00,0x79,0x00,0x14,0x0B,  /* 00001998    "2C_.y..." */
-+    0x5F,0x43,0x52,0x53,0x00,0xA4,0x52,0x42,  /* 000019A0    "_CRS..RB" */
-+    0x55,0x46,0x14,0x15,0x5F,0x53,0x54,0x41,  /* 000019A8    "UF.._STA" */
-+    0x00,0xA0,0x0B,0x92,0x93,0x50,0x54,0x59,  /* 000019B0    ".....PTY" */
-+    0x50,0x0A,0x08,0xA4,0x00,0xA4,0x0A,0x0F,  /* 000019B8    "P......." */
-+    0x5B,0x82,0x49,0x0A,0x4E,0x49,0x4F,0x33,  /* 000019C0    "[.I.NIO3" */
-+    0x08,0x5F,0x48,0x49,0x44,0x0D,0x49,0x4E,  /* 000019C8    "._HID.IN" */
-+    0x54,0x33,0x34,0x39,0x31,0x00,0x08,0x5F,  /* 000019D0    "T3491.._" */
-+    0x43,0x49,0x44,0x0D,0x49,0x4E,0x54,0x33,  /* 000019D8    "CID.INT3" */
-+    0x34,0x39,0x31,0x00,0x08,0x5F,0x55,0x49,  /* 000019E0    "491.._UI" */
-+    0x44,0x0A,0x03,0x08,0x52,0x42,0x55,0x46,  /* 000019E8    "D...RBUF" */
-+    0x11,0x48,0x05,0x0A,0x54,0x8E,0x23,0x00,  /* 000019F0    ".H..T.#." */
-+    0x01,0x00,0x01,0x02,0x00,0x00,0x01,0x06,  /* 000019F8    "........" */
-+    0x00,0x80,0x1A,0x06,0x00,0x27,0x00,0x5C,  /* 00001A00    ".....'.\" */
-+    0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,0x30,  /* 00001A08    "_SB.PCI0" */
-+    0x2E,0x47,0x49,0x50,0x30,0x2E,0x49,0x32,  /* 00001A10    ".GIP0.I2" */
-+    0x43,0x5F,0x00,0x8C,0x29,0x00,0x01,0x00,  /* 00001A18    "C_..)..." */
-+    0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,  /* 00001A20    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x2C,0x00,  /* 00001A28    "......,." */
-+    0x00,0x00,0x01,0x00,0x5C,0x5F,0x53,0x42,  /* 00001A30    "....\_SB" */
-+    0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,0x49,  /* 00001A38    ".PCI0.GI" */
-+    0x50,0x30,0x2E,0x47,0x50,0x4F,0x00,0x79,  /* 00001A40    "P0.GPO.y" */
-+    0x00,0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,  /* 00001A48    "..._CRS." */
-+    0xA4,0x52,0x42,0x55,0x46,0x14,0x15,0x5F,  /* 00001A50    ".RBUF.._" */
-+    0x53,0x54,0x41,0x00,0xA0,0x0B,0x92,0x93,  /* 00001A58    "STA....." */
-+    0x50,0x54,0x59,0x50,0x0A,0x08,0xA4,0x00,  /* 00001A60    "PTYP...." */
-+    0xA4,0x0A,0x0F,0x5B,0x82,0x45,0x07,0x50,  /* 00001A68    "...[.E.P" */
-+    0x57,0x4D,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00001A70    "WM1._HID" */
-+    0x0D,0x49,0x4E,0x54,0x33,0x34,0x39,0x32,  /* 00001A78    ".INT3492" */
-+    0x00,0x08,0x5F,0x43,0x49,0x44,0x0D,0x49,  /* 00001A80    ".._CID.I" */
-+    0x4E,0x54,0x33,0x34,0x39,0x32,0x00,0x08,  /* 00001A88    "NT3492.." */
-+    0x52,0x42,0x55,0x46,0x11,0x2B,0x0A,0x28,  /* 00001A90    "RBUF.+.(" */
-+    0x8E,0x23,0x00,0x01,0x00,0x01,0x02,0x00,  /* 00001A98    ".#......" */
-+    0x00,0x01,0x06,0x00,0x80,0x1A,0x06,0x00,  /* 00001AA0    "........" */
-+    0x47,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,  /* 00001AA8    "G.\_SB.P" */
-+    0x43,0x49,0x30,0x2E,0x47,0x49,0x50,0x30,  /* 00001AB0    "CI0.GIP0" */
-+    0x2E,0x49,0x32,0x43,0x5F,0x00,0x79,0x00,  /* 00001AB8    ".I2C_.y." */
-+    0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,  /* 00001AC0    ".._CRS.." */
-+    0x52,0x42,0x55,0x46,0x14,0x15,0x5F,0x53,  /* 00001AC8    "RBUF.._S" */
-+    0x54,0x41,0x00,0xA0,0x0B,0x92,0x93,0x50,  /* 00001AD0    "TA.....P" */
-+    0x54,0x59,0x50,0x0A,0x08,0xA4,0x00,0xA4,  /* 00001AD8    "TYP....." */
-+    0x0A,0x0F,0x5B,0x82,0x45,0x07,0x45,0x45,  /* 00001AE0    "..[.E.EE" */
-+    0x50,0x32,0x08,0x5F,0x48,0x49,0x44,0x0D,  /* 00001AE8    "P2._HID." */
-+    0x49,0x4E,0x54,0x33,0x34,0x39,0x39,0x00,  /* 00001AF0    "INT3499." */
-+    0x08,0x5F,0x43,0x49,0x44,0x0D,0x49,0x4E,  /* 00001AF8    "._CID.IN" */
-+    0x54,0x33,0x34,0x39,0x39,0x00,0x08,0x52,  /* 00001B00    "T3499..R" */
-+    0x42,0x55,0x46,0x11,0x2B,0x0A,0x28,0x8E,  /* 00001B08    "BUF.+.(." */
-+    0x23,0x00,0x01,0x00,0x01,0x02,0x00,0x00,  /* 00001B10    "#......." */
-+    0x01,0x06,0x00,0x80,0x1A,0x06,0x00,0x54,  /* 00001B18    ".......T" */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,  /* 00001B20    ".\_SB.PC" */
-+    0x49,0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,  /* 00001B28    "I0.GIP0." */
-+    0x49,0x32,0x43,0x5F,0x00,0x79,0x00,0x14,  /* 00001B30    "I2C_.y.." */
-+    0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,0x52,  /* 00001B38    "._CRS..R" */
-+    0x42,0x55,0x46,0x14,0x15,0x5F,0x53,0x54,  /* 00001B40    "BUF.._ST" */
-+    0x41,0x00,0xA0,0x0B,0x92,0x93,0x50,0x54,  /* 00001B48    "A.....PT" */
-+    0x59,0x50,0x0A,0x08,0xA4,0x00,0xA4,0x0A,  /* 00001B50    "YP......" */
-+    0x0F,0x5B,0x82,0x4A,0x89,0x47,0x50,0x4F,  /* 00001B58    ".[.J.GPO" */
-+    0x54,0x08,0x5F,0x48,0x49,0x44,0x0D,0x49,  /* 00001B60    "T._HID.I" */
-+    0x4E,0x54,0x33,0x34,0x39,0x41,0x00,0x08,  /* 00001B68    "NT349A.." */
-+    0x5F,0x43,0x49,0x44,0x0D,0x49,0x4E,0x54,  /* 00001B70    "_CID.INT" */
-+    0x33,0x34,0x39,0x41,0x00,0x14,0x41,0x86,  /* 00001B78    "349A..A." */
-+    0x5F,0x43,0x52,0x53,0x00,0x08,0x52,0x42,  /* 00001B80    "_CRS..RB" */
-+    0x55,0x46,0x11,0x4F,0x84,0x0B,0x4A,0x08,  /* 00001B88    "UF.O..J." */
-+    0x8C,0x2A,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00001B90    ".*......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00001B98    "........" */
-+    0x00,0x19,0x00,0x2D,0x00,0x00,0x00,0x00,  /* 00001BA0    "...-...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,  /* 00001BA8    ".\_SB.PC" */
-+    0x49,0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,  /* 00001BB0    "I0.GIP0." */
-+    0x47,0x50,0x4F,0x5F,0x00,0x8C,0x2A,0x00,  /* 00001BB8    "GPO_..*." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00001BC0    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00001BC8    "........" */
-+    0x2D,0x00,0x00,0x00,0x01,0x00,0x5C,0x5F,  /* 00001BD0    "-.....\_" */
-+    0x53,0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,  /* 00001BD8    "SB.PCI0." */
-+    0x47,0x49,0x50,0x30,0x2E,0x47,0x50,0x4F,  /* 00001BE0    "GIP0.GPO" */
-+    0x5F,0x00,0x8C,0x2A,0x00,0x01,0x01,0x01,  /* 00001BE8    "_..*...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00001BF0    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x2D,0x00,0x00,  /* 00001BF8    ".....-.." */
-+    0x00,0x02,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00001C00    "...\_SB." */
-+    0x50,0x43,0x49,0x30,0x2E,0x47,0x49,0x50,  /* 00001C08    "PCI0.GIP" */
-+    0x30,0x2E,0x47,0x50,0x4F,0x5F,0x00,0x8C,  /* 00001C10    "0.GPO_.." */
-+    0x2A,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00001C18    "*......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00001C20    "........" */
-+    0x19,0x00,0x2D,0x00,0x00,0x00,0x03,0x00,  /* 00001C28    "..-....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,  /* 00001C30    "\_SB.PCI" */
-+    0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,0x47,  /* 00001C38    "0.GIP0.G" */
-+    0x50,0x4F,0x5F,0x00,0x8C,0x2A,0x00,0x01,  /* 00001C40    "PO_..*.." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00001C48    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x2D,  /* 00001C50    ".......-" */
-+    0x00,0x00,0x00,0x04,0x00,0x5C,0x5F,0x53,  /* 00001C58    ".....\_S" */
-+    0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,  /* 00001C60    "B.PCI0.G" */
-+    0x49,0x50,0x30,0x2E,0x47,0x50,0x4F,0x5F,  /* 00001C68    "IP0.GPO_" */
-+    0x00,0x8C,0x2A,0x00,0x01,0x01,0x01,0x00,  /* 00001C70    "..*....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00001C78    "........" */
-+    0x00,0x00,0x19,0x00,0x2D,0x00,0x00,0x00,  /* 00001C80    "....-..." */
-+    0x05,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,  /* 00001C88    "..\_SB.P" */
-+    0x43,0x49,0x30,0x2E,0x47,0x49,0x50,0x30,  /* 00001C90    "CI0.GIP0" */
-+    0x2E,0x47,0x50,0x4F,0x5F,0x00,0x8C,0x2A,  /* 00001C98    ".GPO_..*" */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 00001CA0    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 00001CA8    "........" */
-+    0x00,0x2D,0x00,0x00,0x00,0x06,0x00,0x5C,  /* 00001CB0    ".-.....\" */
-+    0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,0x30,  /* 00001CB8    "_SB.PCI0" */
-+    0x2E,0x47,0x49,0x50,0x30,0x2E,0x47,0x50,  /* 00001CC0    ".GIP0.GP" */
-+    0x4F,0x5F,0x00,0x8C,0x2A,0x00,0x01,0x01,  /* 00001CC8    "O_..*..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 00001CD0    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x2D,0x00,  /* 00001CD8    "......-." */
-+    0x00,0x00,0x07,0x00,0x5C,0x5F,0x53,0x42,  /* 00001CE0    "....\_SB" */
-+    0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,0x49,  /* 00001CE8    ".PCI0.GI" */
-+    0x50,0x30,0x2E,0x47,0x50,0x4F,0x5F,0x00,  /* 00001CF0    "P0.GPO_." */
-+    0x8C,0x2A,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00001CF8    ".*......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00001D00    "........" */
-+    0x00,0x19,0x00,0x2D,0x00,0x00,0x00,0x08,  /* 00001D08    "...-...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,  /* 00001D10    ".\_SB.PC" */
-+    0x49,0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,  /* 00001D18    "I0.GIP0." */
-+    0x47,0x50,0x4F,0x5F,0x00,0x8C,0x2A,0x00,  /* 00001D20    "GPO_..*." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00001D28    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00001D30    "........" */
-+    0x2D,0x00,0x00,0x00,0x09,0x00,0x5C,0x5F,  /* 00001D38    "-.....\_" */
-+    0x53,0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,  /* 00001D40    "SB.PCI0." */
-+    0x47,0x49,0x50,0x30,0x2E,0x47,0x50,0x4F,  /* 00001D48    "GIP0.GPO" */
-+    0x5F,0x00,0x8C,0x2A,0x00,0x01,0x01,0x01,  /* 00001D50    "_..*...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00001D58    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x2D,0x00,0x00,  /* 00001D60    ".....-.." */
-+    0x00,0x0A,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00001D68    "...\_SB." */
-+    0x50,0x43,0x49,0x30,0x2E,0x47,0x49,0x50,  /* 00001D70    "PCI0.GIP" */
-+    0x30,0x2E,0x47,0x50,0x4F,0x5F,0x00,0x8C,  /* 00001D78    "0.GPO_.." */
-+    0x2A,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00001D80    "*......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00001D88    "........" */
-+    0x19,0x00,0x2D,0x00,0x00,0x00,0x0B,0x00,  /* 00001D90    "..-....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,  /* 00001D98    "\_SB.PCI" */
-+    0x30,0x2E,0x47,0x49,0x50,0x30,0x2E,0x47,  /* 00001DA0    "0.GIP0.G" */
-+    0x50,0x4F,0x5F,0x00,0x8C,0x2A,0x00,0x01,  /* 00001DA8    "PO_..*.." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00001DB0    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x2D,  /* 00001DB8    ".......-" */
-+    0x00,0x00,0x00,0x0C,0x00,0x5C,0x5F,0x53,  /* 00001DC0    ".....\_S" */
-+    0x42,0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,  /* 00001DC8    "B.PCI0.G" */
-+    0x49,0x50,0x30,0x2E,0x47,0x50,0x4F,0x5F,  /* 00001DD0    "IP0.GPO_" */
-+    0x00,0x8C,0x2A,0x00,0x01,0x01,0x01,0x00,  /* 00001DD8    "..*....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00001DE0    "........" */
-+    0x00,0x00,0x19,0x00,0x2D,0x00,0x00,0x00,  /* 00001DE8    "....-..." */
-+    0x0D,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x50,  /* 00001DF0    "..\_SB.P" */
-+    0x43,0x49,0x30,0x2E,0x47,0x49,0x50,0x30,  /* 00001DF8    "CI0.GIP0" */
-+    0x2E,0x47,0x50,0x4F,0x5F,0x00,0x8C,0x2A,  /* 00001E00    ".GPO_..*" */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 00001E08    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 00001E10    "........" */
-+    0x00,0x2D,0x00,0x00,0x00,0x0E,0x00,0x5C,  /* 00001E18    ".-.....\" */
-+    0x5F,0x53,0x42,0x2E,0x50,0x43,0x49,0x30,  /* 00001E20    "_SB.PCI0" */
-+    0x2E,0x47,0x49,0x50,0x30,0x2E,0x47,0x50,  /* 00001E28    ".GIP0.GP" */
-+    0x4F,0x5F,0x00,0x8C,0x2A,0x00,0x01,0x01,  /* 00001E30    "O_..*..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 00001E38    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x2D,0x00,  /* 00001E40    "......-." */
-+    0x00,0x00,0x0F,0x00,0x5C,0x5F,0x53,0x42,  /* 00001E48    "....\_SB" */
-+    0x2E,0x50,0x43,0x49,0x30,0x2E,0x47,0x49,  /* 00001E50    ".PCI0.GI" */
-+    0x50,0x30,0x2E,0x47,0x50,0x4F,0x5F,0x00,  /* 00001E58    "P0.GPO_." */
-+    0x8C,0x20,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00001E60    ". ......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00001E68    "........" */
-+    0x00,0x19,0x00,0x23,0x00,0x00,0x00,0x00,  /* 00001E70    "...#...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,  /* 00001E78    ".\_SB.CY" */
-+    0x38,0x43,0x00,0x8C,0x20,0x00,0x01,0x01,  /* 00001E80    "8C.. ..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 00001E88    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x23,0x00,  /* 00001E90    "......#." */
-+    0x00,0x00,0x01,0x00,0x5C,0x5F,0x53,0x42,  /* 00001E98    "....\_SB" */
-+    0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,0x20,  /* 00001EA0    ".CY8C.. " */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 00001EA8    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 00001EB0    "........" */
-+    0x00,0x23,0x00,0x00,0x00,0x02,0x00,0x5C,  /* 00001EB8    ".#.....\" */
-+    0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,0x43,  /* 00001EC0    "_SB.CY8C" */
-+    0x00,0x8C,0x20,0x00,0x01,0x01,0x01,0x00,  /* 00001EC8    ".. ....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00001ED0    "........" */
-+    0x00,0x00,0x19,0x00,0x23,0x00,0x00,0x00,  /* 00001ED8    "....#..." */
-+    0x03,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,  /* 00001EE0    "..\_SB.C" */
-+    0x59,0x38,0x43,0x00,0x8C,0x20,0x00,0x01,  /* 00001EE8    "Y8C.. .." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00001EF0    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x23,  /* 00001EF8    ".......#" */
-+    0x00,0x00,0x00,0x04,0x00,0x5C,0x5F,0x53,  /* 00001F00    ".....\_S" */
-+    0x42,0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,  /* 00001F08    "B.CY8C.." */
-+    0x20,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00001F10    " ......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00001F18    "........" */
-+    0x19,0x00,0x23,0x00,0x00,0x00,0x05,0x00,  /* 00001F20    "..#....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,  /* 00001F28    "\_SB.CY8" */
-+    0x43,0x00,0x8C,0x20,0x00,0x01,0x01,0x01,  /* 00001F30    "C.. ...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00001F38    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x23,0x00,0x00,  /* 00001F40    ".....#.." */
-+    0x00,0x06,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00001F48    "...\_SB." */
-+    0x43,0x59,0x38,0x43,0x00,0x8C,0x20,0x00,  /* 00001F50    "CY8C.. ." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00001F58    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00001F60    "........" */
-+    0x23,0x00,0x00,0x00,0x07,0x00,0x5C,0x5F,  /* 00001F68    "#.....\_" */
-+    0x53,0x42,0x2E,0x43,0x59,0x38,0x43,0x00,  /* 00001F70    "SB.CY8C." */
-+    0x8C,0x20,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00001F78    ". ......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00001F80    "........" */
-+    0x00,0x19,0x00,0x23,0x00,0x00,0x00,0x08,  /* 00001F88    "...#...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,  /* 00001F90    ".\_SB.CY" */
-+    0x38,0x43,0x00,0x8C,0x20,0x00,0x01,0x01,  /* 00001F98    "8C.. ..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 00001FA0    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x23,0x00,  /* 00001FA8    "......#." */
-+    0x00,0x00,0x09,0x00,0x5C,0x5F,0x53,0x42,  /* 00001FB0    "....\_SB" */
-+    0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,0x20,  /* 00001FB8    ".CY8C.. " */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 00001FC0    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 00001FC8    "........" */
-+    0x00,0x23,0x00,0x00,0x00,0x0A,0x00,0x5C,  /* 00001FD0    ".#.....\" */
-+    0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,0x43,  /* 00001FD8    "_SB.CY8C" */
-+    0x00,0x8C,0x20,0x00,0x01,0x01,0x01,0x00,  /* 00001FE0    ".. ....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00001FE8    "........" */
-+    0x00,0x00,0x19,0x00,0x23,0x00,0x00,0x00,  /* 00001FF0    "....#..." */
-+    0x0B,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,  /* 00001FF8    "..\_SB.C" */
-+    0x59,0x38,0x43,0x00,0x8C,0x20,0x00,0x01,  /* 00002000    "Y8C.. .." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00002008    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x23,  /* 00002010    ".......#" */
-+    0x00,0x00,0x00,0x0C,0x00,0x5C,0x5F,0x53,  /* 00002018    ".....\_S" */
-+    0x42,0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,  /* 00002020    "B.CY8C.." */
-+    0x20,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00002028    " ......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00002030    "........" */
-+    0x19,0x00,0x23,0x00,0x00,0x00,0x0D,0x00,  /* 00002038    "..#....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,  /* 00002040    "\_SB.CY8" */
-+    0x43,0x00,0x8C,0x20,0x00,0x01,0x01,0x01,  /* 00002048    "C.. ...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00002050    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x23,0x00,0x00,  /* 00002058    ".....#.." */
-+    0x00,0x0E,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00002060    "...\_SB." */
-+    0x43,0x59,0x38,0x43,0x00,0x8C,0x20,0x00,  /* 00002068    "CY8C.. ." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00002070    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00002078    "........" */
-+    0x23,0x00,0x00,0x00,0x0F,0x00,0x5C,0x5F,  /* 00002080    "#.....\_" */
-+    0x53,0x42,0x2E,0x43,0x59,0x38,0x43,0x00,  /* 00002088    "SB.CY8C." */
-+    0x8C,0x20,0x00,0x01,0x01,0x01,0x00,0x08,  /* 00002090    ". ......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 00002098    "........" */
-+    0x00,0x19,0x00,0x23,0x00,0x00,0x00,0x10,  /* 000020A0    "...#...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,  /* 000020A8    ".\_SB.CY" */
-+    0x38,0x43,0x00,0x8C,0x20,0x00,0x01,0x01,  /* 000020B0    "8C.. ..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 000020B8    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x23,0x00,  /* 000020C0    "......#." */
-+    0x00,0x00,0x11,0x00,0x5C,0x5F,0x53,0x42,  /* 000020C8    "....\_SB" */
-+    0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,0x20,  /* 000020D0    ".CY8C.. " */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 000020D8    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 000020E0    "........" */
-+    0x00,0x23,0x00,0x00,0x00,0x12,0x00,0x5C,  /* 000020E8    ".#.....\" */
-+    0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,0x43,  /* 000020F0    "_SB.CY8C" */
-+    0x00,0x8C,0x20,0x00,0x01,0x01,0x01,0x00,  /* 000020F8    ".. ....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00002100    "........" */
-+    0x00,0x00,0x19,0x00,0x23,0x00,0x00,0x00,  /* 00002108    "....#..." */
-+    0x13,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,  /* 00002110    "..\_SB.C" */
-+    0x59,0x38,0x43,0x00,0x8C,0x20,0x00,0x01,  /* 00002118    "Y8C.. .." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00002120    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x23,  /* 00002128    ".......#" */
-+    0x00,0x00,0x00,0x14,0x00,0x5C,0x5F,0x53,  /* 00002130    ".....\_S" */
-+    0x42,0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,  /* 00002138    "B.CY8C.." */
-+    0x20,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00002140    " ......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00002148    "........" */
-+    0x19,0x00,0x23,0x00,0x00,0x00,0x15,0x00,  /* 00002150    "..#....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,  /* 00002158    "\_SB.CY8" */
-+    0x43,0x00,0x8C,0x20,0x00,0x01,0x01,0x01,  /* 00002160    "C.. ...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00002168    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x23,0x00,0x00,  /* 00002170    ".....#.." */
-+    0x00,0x16,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00002178    "...\_SB." */
-+    0x43,0x59,0x38,0x43,0x00,0x8C,0x20,0x00,  /* 00002180    "CY8C.. ." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 00002188    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 00002190    "........" */
-+    0x23,0x00,0x00,0x00,0x17,0x00,0x5C,0x5F,  /* 00002198    "#.....\_" */
-+    0x53,0x42,0x2E,0x43,0x59,0x38,0x43,0x00,  /* 000021A0    "SB.CY8C." */
-+    0x8C,0x20,0x00,0x01,0x01,0x01,0x00,0x08,  /* 000021A8    ". ......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 000021B0    "........" */
-+    0x00,0x19,0x00,0x23,0x00,0x00,0x00,0x18,  /* 000021B8    "...#...." */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,  /* 000021C0    ".\_SB.CY" */
-+    0x38,0x43,0x00,0x8C,0x20,0x00,0x01,0x01,  /* 000021C8    "8C.. ..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 000021D0    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x23,0x00,  /* 000021D8    "......#." */
-+    0x00,0x00,0x19,0x00,0x5C,0x5F,0x53,0x42,  /* 000021E0    "....\_SB" */
-+    0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,0x20,  /* 000021E8    ".CY8C.. " */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 000021F0    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 000021F8    "........" */
-+    0x00,0x23,0x00,0x00,0x00,0x1A,0x00,0x5C,  /* 00002200    ".#.....\" */
-+    0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,0x43,  /* 00002208    "_SB.CY8C" */
-+    0x00,0x8C,0x20,0x00,0x01,0x01,0x01,0x00,  /* 00002210    ".. ....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00002218    "........" */
-+    0x00,0x00,0x19,0x00,0x23,0x00,0x00,0x00,  /* 00002220    "....#..." */
-+    0x1B,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,  /* 00002228    "..\_SB.C" */
-+    0x59,0x38,0x43,0x00,0x8C,0x20,0x00,0x01,  /* 00002230    "Y8C.. .." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00002238    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x23,  /* 00002240    ".......#" */
-+    0x00,0x00,0x00,0x1C,0x00,0x5C,0x5F,0x53,  /* 00002248    ".....\_S" */
-+    0x42,0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,  /* 00002250    "B.CY8C.." */
-+    0x20,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00002258    " ......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00002260    "........" */
-+    0x19,0x00,0x23,0x00,0x00,0x00,0x1D,0x00,  /* 00002268    "..#....." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,  /* 00002270    "\_SB.CY8" */
-+    0x43,0x00,0x8C,0x20,0x00,0x01,0x01,0x01,  /* 00002278    "C.. ...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00002280    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x23,0x00,0x00,  /* 00002288    ".....#.." */
-+    0x00,0x1E,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 00002290    "...\_SB." */
-+    0x43,0x59,0x38,0x43,0x00,0x8C,0x20,0x00,  /* 00002298    "CY8C.. ." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 000022A0    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 000022A8    "........" */
-+    0x23,0x00,0x00,0x00,0x1F,0x00,0x5C,0x5F,  /* 000022B0    "#.....\_" */
-+    0x53,0x42,0x2E,0x43,0x59,0x38,0x43,0x00,  /* 000022B8    "SB.CY8C." */
-+    0x8C,0x20,0x00,0x01,0x01,0x01,0x00,0x08,  /* 000022C0    ". ......" */
-+    0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,  /* 000022C8    "........" */
-+    0x00,0x19,0x00,0x23,0x00,0x00,0x00,0x20,  /* 000022D0    "...#... " */
-+    0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,  /* 000022D8    ".\_SB.CY" */
-+    0x38,0x43,0x00,0x8C,0x20,0x00,0x01,0x01,  /* 000022E0    "8C.. ..." */
-+    0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,  /* 000022E8    "........" */
-+    0x00,0x17,0x00,0x00,0x19,0x00,0x23,0x00,  /* 000022F0    "......#." */
-+    0x00,0x00,0x21,0x00,0x5C,0x5F,0x53,0x42,  /* 000022F8    "..!.\_SB" */
-+    0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,0x20,  /* 00002300    ".CY8C.. " */
-+    0x00,0x01,0x01,0x01,0x00,0x08,0x00,0x00,  /* 00002308    "........" */
-+    0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x19,  /* 00002310    "........" */
-+    0x00,0x23,0x00,0x00,0x00,0x22,0x00,0x5C,  /* 00002318    ".#...".\" */
-+    0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,0x43,  /* 00002320    "_SB.CY8C" */
-+    0x00,0x8C,0x20,0x00,0x01,0x01,0x01,0x00,  /* 00002328    ".. ....." */
-+    0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x17,  /* 00002330    "........" */
-+    0x00,0x00,0x19,0x00,0x23,0x00,0x00,0x00,  /* 00002338    "....#..." */
-+    0x23,0x00,0x5C,0x5F,0x53,0x42,0x2E,0x43,  /* 00002340    "#.\_SB.C" */
-+    0x59,0x38,0x43,0x00,0x8C,0x20,0x00,0x01,  /* 00002348    "Y8C.. .." */
-+    0x01,0x01,0x00,0x08,0x00,0x00,0x00,0x00,  /* 00002350    "........" */
-+    0x00,0x00,0x17,0x00,0x00,0x19,0x00,0x23,  /* 00002358    ".......#" */
-+    0x00,0x00,0x00,0x24,0x00,0x5C,0x5F,0x53,  /* 00002360    "...$.\_S" */
-+    0x42,0x2E,0x43,0x59,0x38,0x43,0x00,0x8C,  /* 00002368    "B.CY8C.." */
-+    0x20,0x00,0x01,0x01,0x01,0x00,0x08,0x00,  /* 00002370    " ......." */
-+    0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,  /* 00002378    "........" */
-+    0x19,0x00,0x23,0x00,0x00,0x00,0x25,0x00,  /* 00002380    "..#...%." */
-+    0x5C,0x5F,0x53,0x42,0x2E,0x43,0x59,0x38,  /* 00002388    "\_SB.CY8" */
-+    0x43,0x00,0x8C,0x20,0x00,0x01,0x01,0x01,  /* 00002390    "C.. ...." */
-+    0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00002398    "........" */
-+    0x17,0x00,0x00,0x19,0x00,0x23,0x00,0x00,  /* 000023A0    ".....#.." */
-+    0x00,0x26,0x00,0x5C,0x5F,0x53,0x42,0x2E,  /* 000023A8    ".&.\_SB." */
-+    0x43,0x59,0x38,0x43,0x00,0x8C,0x20,0x00,  /* 000023B0    "CY8C.. ." */
-+    0x01,0x01,0x01,0x00,0x08,0x00,0x00,0x00,  /* 000023B8    "........" */
-+    0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x00,  /* 000023C0    "........" */
-+    0x23,0x00,0x00,0x00,0x27,0x00,0x5C,0x5F,  /* 000023C8    "#...'.\_" */
-+    0x53,0x42,0x2E,0x43,0x59,0x38,0x43,0x00,  /* 000023D0    "SB.CY8C." */
-+    0x79,0x00,0xA4,0x52,0x42,0x55,0x46,0x14,  /* 000023D8    "y..RBUF." */
-+    0x15,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0B,  /* 000023E0    "._STA..." */
-+    0x92,0x93,0x50,0x54,0x59,0x50,0x0A,0x06,  /* 000023E8    "..PTYP.." */
-+    0xA4,0x00,0xA4,0x0A,0x0F                  /* 000023F0    "....."    */
-+};
--- 
-2.5.0
-

+ 0 - 90
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch

@@ -1,90 +0,0 @@
-From 2ca48f47b659edbd5cf4c4e55c420ef40712ce9b Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:57 +0200
-Subject: [PATCH 01/18] stmmac: pci: Make stmmac_pci_info structure constant
-
-Commit c5d5287ef0f763e836bf94659b3a6080358373f1 upstream.
-
-By removing the PCI device reference from the structure and passing it
-as parameters to the interested functions, we can make quark_pci_info
-const.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 3491e98bffc5..828d276748e3 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,17 +42,17 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	struct pci_dev *pdev;
--	int (*setup)(struct plat_stmmacenet_data *plat,
--		     struct stmmac_pci_info *info);
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
-+		     const struct stmmac_pci_info *info);
- 	struct stmmac_pci_dmi_data *dmi;
- };
- 
--static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
-+static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
-+				    const struct stmmac_pci_info *info)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(info->pdev->devfn);
-+	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
- 	/*
-@@ -96,17 +96,17 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 	plat->unicast_filter_entries = 1;
- }
- 
--static int quark_default_data(struct plat_stmmacenet_data *plat,
--			      struct stmmac_pci_info *info)
-+static int quark_default_data(struct pci_dev *pdev,
-+			      struct plat_stmmacenet_data *plat,
-+			      const struct stmmac_pci_info *info)
- {
--	struct pci_dev *pdev = info->pdev;
- 	int ret;
- 
- 	/*
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(info);
-+	ret = stmmac_pci_find_phy_addr(pdev, info);
- 	if (ret < 0)
- 		return ret;
- 
-@@ -165,7 +165,7 @@ static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
- 	{}
- };
- 
--static struct stmmac_pci_info quark_pci_info = {
-+static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
- 	.dmi = quark_pci_dmi_data,
- };
-@@ -227,9 +227,8 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 	pci_set_master(pdev);
- 
- 	if (info) {
--		info->pdev = pdev;
- 		if (info->setup) {
--			ret = info->setup(plat, info);
-+			ret = info->setup(pdev, plat, info);
- 			if (ret)
- 				return ret;
- 		}
--- 
-2.16.4
-

+ 0 - 95
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch

@@ -1,95 +0,0 @@
-From 5222a576c02eed33b0499a7e632a56680742a885 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:58 +0200
-Subject: [PATCH 02/18] stmmac: pci: Use stmmac_pci_info for all devices
-
-Commit b6a4c8f013ea2dd1ead7ee14b44712189a7bc6c6 upstream.
-
-Make stmmac_default_data compatible with stmmac_pci_info.setup and use
-an info structure for all devices. This allows to make the probing more
-regular.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 36 +++++++++++++++---------
- 1 file changed, 23 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 828d276748e3..a60059032dc6 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -74,7 +74,9 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	return -ENODEV;
- }
- 
--static void stmmac_default_data(struct plat_stmmacenet_data *plat)
-+static int stmmac_default_data(struct pci_dev *pdev,
-+			       struct plat_stmmacenet_data *plat,
-+			       const struct stmmac_pci_info *info)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -94,8 +96,14 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 
- 	/* Set default value for unicast filter entries */
- 	plat->unicast_filter_entries = 1;
-+
-+	return 0;
- }
- 
-+static const struct stmmac_pci_info stmmac_pci_info = {
-+	.setup = stmmac_default_data,
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
- 			      struct plat_stmmacenet_data *plat,
- 			      const struct stmmac_pci_info *info)
-@@ -226,14 +234,9 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	if (info) {
--		if (info->setup) {
--			ret = info->setup(pdev, plat, info);
--			if (ret)
--				return ret;
--		}
--	} else
--		stmmac_default_data(plat);
-+	ret = info->setup(pdev, plat, info);
-+	if (ret)
-+		return ret;
- 
- 	pci_enable_msi(pdev);
- 
-@@ -279,14 +282,21 @@ static int stmmac_pci_resume(struct device *dev)
- 
- static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
- 
--#define STMMAC_VENDOR_ID 0x700
-+/* synthetic ID, no official vendor */
-+#define PCI_VENDOR_ID_STMMAC 0x700
-+
- #define STMMAC_QUARK_ID  0x0937
- #define STMMAC_DEVICE_ID 0x1108
- 
-+#define STMMAC_DEVICE(vendor_id, dev_id, info)	{	\
-+	PCI_VDEVICE(vendor_id, dev_id),			\
-+	.driver_data = (kernel_ulong_t)&info		\
-+	}
-+
- static const struct pci_device_id stmmac_id_table[] = {
--	{PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)},
--	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)},
--	{PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info},
-+	STMMAC_DEVICE(STMMAC, STMMAC_DEVICE_ID, stmmac_pci_info),
-+	STMMAC_DEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_MAC, stmmac_pci_info),
-+	STMMAC_DEVICE(INTEL, STMMAC_QUARK_ID, quark_pci_info),
- 	{}
- };
- 
--- 
-2.16.4
-

+ 0 - 61
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch

@@ -1,61 +0,0 @@
-From d9478f26f2c620cf284f5022d3d852c47227e8da Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:59 +0200
-Subject: [PATCH 03/18] stmmac: pci: Make stmmac_pci_find_phy_addr truly
- generic
-
-Commit c5f657e49c878756f21349f9e4b0f1c9631d5352 upstream.
-
-Move the special case for the early Galileo firmware into
-quark_default_setup. This allows to use stmmac_pci_find_phy_addr for
-non-quark cases.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 20 +++++++++++++-------
- 1 file changed, 13 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index a60059032dc6..19cf9607618a 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -55,12 +55,8 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
--	/*
--	 * Galileo boards with old firmware don't support DMI. We always return
--	 * 1 here, so at least first found MAC controller would be probed.
--	 */
- 	if (!name)
--		return 1;
-+		return -ENODEV;
- 
- 	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
-@@ -115,8 +111,18 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * does not connect to any PHY interface.
- 	 */
- 	ret = stmmac_pci_find_phy_addr(pdev, info);
--	if (ret < 0)
--		return ret;
-+	if (ret < 0) {
-+		/* Return error to the caller on DMI enabled boards. */
-+		if (dmi_get_system_info(DMI_BOARD_NAME))
-+			return ret;
-+
-+		/*
-+		 * Galileo boards with old firmware don't support DMI. We always
-+		 * use 1 here as PHY address, so at least the first found MAC
-+		 * controller would be probed.
-+		 */
-+		ret = 1;
-+	}
- 
- 	plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
- 	plat->phy_addr = ret;
--- 
-2.16.4
-

+ 0 - 165
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch

@@ -1,165 +0,0 @@
-From 0747f34d4be27952be866461c97d386c29000817 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:00 +0200
-Subject: [PATCH 04/18] stmmac: pci: Select quark_pci_dmi_data from
- quark_default_data
-
-Commit 7bc519b3ea04026877242328d2fe73cc8e6102bd upsteam.
-
-No need to carry this reference in stmmac_pci_info - the Quark-specific
-setup handler knows that it needs to use the Quark-specific DMI table.
-This also allows to drop the stmmac_pci_info reference from the setup
-handler parameter list.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 83 +++++++++++-------------
- 1 file changed, 39 insertions(+), 44 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 19cf9607618a..9fe6368738ec 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,13 +42,11 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
--		     const struct stmmac_pci_info *info);
--	struct stmmac_pci_dmi_data *dmi;
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    const struct stmmac_pci_info *info)
-+				    struct stmmac_pci_dmi_data *dmi_data)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
-@@ -58,7 +56,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	if (!name)
- 		return -ENODEV;
- 
--	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
-+	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
- 			/* If asset tag is provided, match on it as well. */
- 			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
-@@ -71,8 +69,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- }
- 
- static int stmmac_default_data(struct pci_dev *pdev,
--			       struct plat_stmmacenet_data *plat,
--			       const struct stmmac_pci_info *info)
-+			       struct plat_stmmacenet_data *plat)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -100,9 +97,40 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
-+static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+	{
-+		.name = "Galileo",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "GalileoGen2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-0YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 7,
-+		.phy_addr = 1,
-+	},
-+	{}
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
--			      struct plat_stmmacenet_data *plat,
--			      const struct stmmac_pci_info *info)
-+			      struct plat_stmmacenet_data *plat)
- {
- 	int ret;
- 
-@@ -110,7 +138,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, info);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
-@@ -147,41 +175,8 @@ static int quark_default_data(struct pci_dev *pdev,
- 	return 0;
- }
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
--	{
--		.name = "Galileo",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "GalileoGen2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
--	},
--	{}
--};
--
- static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
--	.dmi = quark_pci_dmi_data,
- };
- 
- /**
-@@ -240,7 +235,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	ret = info->setup(pdev, plat, info);
-+	ret = info->setup(pdev, plat);
- 	if (ret)
- 		return ret;
- 
--- 
-2.16.4
-

+ 0 - 167
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch

@@ -1,167 +0,0 @@
-From 1b2894107ad2d9de45402ecc4ffe14f075a08bbc Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:01 +0200
-Subject: [PATCH 05/18] stmmac: pci: Use dmi_system_id table for retrieving PHY
- addresses
-
-Commit 8d78b69091845386b6096f3adae98f28b9bf96ed upstream.
-
-Avoids reimplementation of DMI matching in stmmac_pci_find_phy_addr.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 97 ++++++++++++++++--------
- 1 file changed, 64 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 9fe6368738ec..279a1355d75f 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -34,36 +34,39 @@
-  * negative value of the address means that MAC controller is not connected
-  * with PHY.
-  */
--struct stmmac_pci_dmi_data {
--	const char *name;
--	const char *asset_tag;
-+struct stmmac_pci_func_data {
- 	unsigned int func;
- 	int phy_addr;
- };
- 
-+struct stmmac_pci_dmi_data {
-+	const struct stmmac_pci_func_data *func;
-+	size_t nfuncs;
-+};
-+
- struct stmmac_pci_info {
- 	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    struct stmmac_pci_dmi_data *dmi_data)
-+				    const struct dmi_system_id *dmi_list)
- {
--	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
--	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(pdev->devfn);
--	struct stmmac_pci_dmi_data *dmi;
--
--	if (!name)
-+	const struct stmmac_pci_func_data *func_data;
-+	const struct stmmac_pci_dmi_data *dmi_data;
-+	const struct dmi_system_id *dmi_id;
-+	int func = PCI_FUNC(pdev->devfn);
-+	size_t n;
-+
-+	dmi_id = dmi_first_match(dmi_list);
-+	if (!dmi_id)
- 		return -ENODEV;
- 
--	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
--		if (!strcmp(dmi->name, name) && dmi->func == func) {
--			/* If asset tag is provided, match on it as well. */
--			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
--				continue;
--			return dmi->phy_addr;
--		}
--	}
-+	dmi_data = dmi_id->driver_data;
-+	func_data = dmi_data->func;
-+
-+	for (n = 0; n < dmi_data->nfuncs; n++, func_data++)
-+		if (func_data->func == func)
-+			return func_data->phy_addr;
- 
- 	return -ENODEV;
- }
-@@ -97,34 +100,62 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
- 	{
--		.name = "Galileo",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = {
-+	.func = galileo_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(galileo_stmmac_func_data),
-+};
-+
-+static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = {
- 	{
--		.name = "GalileoGen2",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
-+		.func = 7,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = {
-+	.func = iot2040_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data),
-+};
-+
-+static const struct dmi_system_id quark_pci_dmi[] = {
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-0YA2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-1YA2"),
-+		},
-+		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
- 	{}
- };
-@@ -138,7 +169,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
--- 
-2.16.4
-

+ 0 - 47
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch

@@ -1,47 +0,0 @@
-From e3ba8c4f83c6c206a20e4645a37612b1e10580c6 Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:08:11 +0200
-Subject: [PATCH 06/18] stmmac: pci: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. The IOT2020 is identified by its unique
-asset tag. Match on it first. If we then match on the board name only,
-we will catch all IOT2040 variants. In the future there will be no other
-devices with the "SIMATIC IOT2000" DMI board name but different
-hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 279a1355d75f..ac733d4d3ed4 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -149,11 +149,15 @@ static const struct dmi_system_id quark_pci_dmi[] = {
- 		},
- 		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
-+	/*
-+	 * There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040.
-+	 * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which
-+	 * has only one pci network device while other asset tags are
-+	 * for IOT2040 which has two.
-+	 */
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
--- 
-2.16.4
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch

@@ -1,44 +0,0 @@
-From df74e188ffc38176d4caba969e104d2ab2e4e609 Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:12:37 +0200
-Subject: [PATCH 07/18] serial: 8250_exar: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-As only the IOT2040 variants have the Exar chip on board, matching on
-their board name is enough. In the future there will be no other devices
-with the "SIMATIC IOT2000" DMI board name but different hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/tty/serial/8250/8250_exar.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
-index be82707d6cb8..3eb3a7674a0f 100644
---- a/drivers/tty/serial/8250/8250_exar.c
-+++ b/drivers/tty/serial/8250/8250_exar.c
-@@ -338,12 +338,15 @@ static const struct exar8250_platform iot2040_platform = {
- 	.register_gpio = iot2040_register_gpio,
- };
- 
-+/*
-+ * For SIMATIC IOT2000, only IOT2040 and its variants have the Exar device,
-+ * IOT2020 doesn't have. Therefore it is sufficient to match on the common
-+ * board name after the device was found.
-+ */
- static const struct dmi_system_id exar_platforms[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_platform,
- 	},
--- 
-2.16.4
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch

@@ -1,45 +0,0 @@
-From 6e378b789ebcfcdc4ae957b25f1ac6eb2ef64edc Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:05:07 +0200
-Subject: [PATCH 08/18] mfd: intel_quark_i2c_gpio: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. Both are identical regarding the
-intel_quark_i2c_gpio. In the future there will be no other devices with
-the "SIMATIC IOT2000" DMI board name but different hardware. So remove
-the asset tag matching from this driver.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/mfd/intel_quark_i2c_gpio.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
-index 1c09604978d3..ad70a058bea8 100644
---- a/drivers/mfd/intel_quark_i2c_gpio.c
-+++ b/drivers/mfd/intel_quark_i2c_gpio.c
-@@ -76,16 +76,6 @@ static const struct dmi_system_id dmi_platform_info[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-0YA2"),
--		},
--		.driver_data = (void *)400000,
--	},
--	{
--		.matches = {
--			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)400000,
- 	},
--- 
-2.16.4
-

+ 0 - 86
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch

@@ -1,86 +0,0 @@
-From cf3d1330c71d47c4cdb9268f68d2ee5931890d93 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Dec 2015 14:21:49 +0100
-Subject: [PATCH 09/18] gpio: sch: use gpiochip data pointer
-
-This makes the driver use the data pointer added to the gpio_chip
-to store a pointer to the state container instead of relying on
-container_of().
-
-Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index b72906f5b999..23907fc080a3 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -41,8 +41,6 @@ struct sch_gpio {
- 	unsigned short resume_base;
- };
- 
--#define to_sch_gpio(gc)	container_of(gc, struct sch_gpio, chip)
--
- static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
- 				unsigned reg)
- {
-@@ -65,7 +63,7 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
- 
- static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -80,7 +78,7 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 			     int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -97,7 +95,7 @@ static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 
- static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
-@@ -112,7 +110,7 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- 
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GLV, val);
-@@ -122,7 +120,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 				  int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
-@@ -217,7 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return gpiochip_add(&sch->chip);
-+	return gpiochip_add_data(&sch->chip, sch);
- }
- 
- static int sch_gpio_remove(struct platform_device *pdev)
--- 
-2.16.4
-

+ 0 - 46
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0010-gpio-sch-Use-devm_gpiochip_add_data-for-gpio-registr.patch

@@ -1,46 +0,0 @@
-From 6a930e4d040061edcaf0c3e3e43a10acdc20f09c Mon Sep 17 00:00:00 2001
-From: Laxman Dewangan <ldewangan@nvidia.com>
-Date: Mon, 22 Feb 2016 17:43:28 +0530
-Subject: [PATCH 10/18] gpio: sch: Use devm_gpiochip_add_data() for gpio
- registration
-
-Use devm_gpiochip_add_data() for GPIO registration and remove the
-need of driver callback .remove.
-
-Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
----
- drivers/gpio/gpio-sch.c | 11 +----------
- 1 file changed, 1 insertion(+), 10 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 23907fc080a3..bbf9b2a34da8 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -215,15 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return gpiochip_add_data(&sch->chip, sch);
--}
--
--static int sch_gpio_remove(struct platform_device *pdev)
--{
--	struct sch_gpio *sch = platform_get_drvdata(pdev);
--
--	gpiochip_remove(&sch->chip);
--	return 0;
-+	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
- }
- 
- static struct platform_driver sch_gpio_driver = {
-@@ -231,7 +223,6 @@ static struct platform_driver sch_gpio_driver = {
- 		.name = "sch_gpio",
- 	},
- 	.probe		= sch_gpio_probe,
--	.remove		= sch_gpio_remove,
- };
- 
- module_platform_driver(sch_gpio_driver);
--- 
-2.16.4
-

+ 0 - 114
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0011-gpio-sch-Fix-Oops-on-module-load-on-Asus-Eee-PC-1201.patch

@@ -1,114 +0,0 @@
-From 9fd1991d762b6092f462f3cc551b2d7df3009b52 Mon Sep 17 00:00:00 2001
-From: Colin Pitrat <colin.pitrat@gmail.com>
-Date: Sat, 18 Jun 2016 19:05:04 +0100
-Subject: [PATCH 11/18] gpio: sch: Fix Oops on module load on Asus Eee PC 1201
-
-This fixes the issue descirbe in bug 117531
-(https://bugzilla.kernel.org/show_bug.cgi?id=117531).
-It's a regression introduced in linux 4.5 that causes a Oops at load of
-gpio_sch and prevents powering off the computer.
-
-The issue is that sch_gpio_reg_set is called in sch_gpio_probe before
-gpio_chip data is initialized with the pointer to the sch_gpio struct. As
-sch_gpio_reg_set calls gpiochip_get_data, it returns NULL which causes
-the Oops.
-
-The patch follows Mika's advice (https://lkml.org/lkml/2016/5/9/61) and
-consists in modifying sch_gpio_reg_get and sch_gpio_reg_set to take a
-sch_gpio struct directly instead of a gpio_chip, which avoids the call to
-gpiochip_get_data.
-
-Thanks Mika for your patience with me :-)
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Colin Pitrat <colin.pitrat@gmail.com>
-Acked-by: Alexandre Courbot <acourbot@nvidia.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 21 ++++++++++-----------
- 1 file changed, 10 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index bbf9b2a34da8..5f72b177fc80 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -61,9 +61,8 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
- 	return gpio % 8;
- }
- 
--static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
-+static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned gpio, unsigned reg)
- {
--	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -75,10 +74,9 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- 	return reg_val;
- }
- 
--static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
-+static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
- 			     int val)
- {
--	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -98,14 +96,15 @@ static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
-+	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
- 	spin_unlock(&sch->lock);
- 	return 0;
- }
- 
- static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- {
--	return sch_gpio_reg_get(gc, gpio_num, GLV);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	return sch_gpio_reg_get(sch, gpio_num, GLV);
- }
- 
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
-@@ -113,7 +112,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GLV, val);
-+	sch_gpio_reg_set(sch, gpio_num, GLV, val);
- 	spin_unlock(&sch->lock);
- }
- 
-@@ -123,7 +122,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
--	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
-+	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
- 	spin_unlock(&sch->lock);
- 
- 	/*
-@@ -182,13 +181,13 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 		 * GPIO7 is configured by the CMC as SLPIOVR
- 		 * Enable GPIO[9:8] core powered gpios explicitly
- 		 */
--		sch_gpio_reg_set(&sch->chip, 8, GEN, 1);
--		sch_gpio_reg_set(&sch->chip, 9, GEN, 1);
-+		sch_gpio_reg_set(sch, 8, GEN, 1);
-+		sch_gpio_reg_set(sch, 9, GEN, 1);
- 		/*
- 		 * SUS_GPIO[2:0] enabled by default
- 		 * Enable SUS_GPIO3 resume powered gpio explicitly
- 		 */
--		sch_gpio_reg_set(&sch->chip, 13, GEN, 1);
-+		sch_gpio_reg_set(sch, 13, GEN, 1);
- 		break;
- 
- 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
--- 
-2.16.4
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0012-gpio-sch-Implement-.get_direction.patch

@@ -1,45 +0,0 @@
-From 8fec046f568e2b946abd55a82d5417717a115b21 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 27 Jun 2018 10:39:31 +0200
-Subject: [PATCH 12/18] gpio: sch: Implement .get_direction()
-
-It's pretty simple to implement the .get_direction() for this
-chip, so let's just do it.
-
-Cc: Denis Turischev <denis.turischev@compulab.co.il>
-Cc: Daniel Krueger <daniel.krueger@systec-electronic.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 5f72b177fc80..6715828c3940 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -138,6 +138,13 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 	return 0;
- }
- 
-+static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned gpio_num)
-+{
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
-+
-+	return sch_gpio_reg_get(sch, gpio_num, GIO);
-+}
-+
- static struct gpio_chip sch_gpio_chip = {
- 	.label			= "sch_gpio",
- 	.owner			= THIS_MODULE,
-@@ -145,6 +152,7 @@ static struct gpio_chip sch_gpio_chip = {
- 	.get			= sch_gpio_get,
- 	.direction_output	= sch_gpio_direction_out,
- 	.set			= sch_gpio_set,
-+	.get_direction		= sch_gpio_get_direction,
- };
- 
- static int sch_gpio_probe(struct platform_device *pdev)
--- 
-2.16.4
-

+ 0 - 230
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0013-gpio-sch-Add-interrupt-support.patch

@@ -1,230 +0,0 @@
-From 53c90b014f54743b5a2180f90b90b1f198535583 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Wed, 17 Apr 2019 22:26:22 +0200
-Subject: [PATCH 13/18] gpio: sch: Add interrupt support
-
-Validated on the Quark platform, this adds interrupt support on rising
-and/or falling edges.
-
-Backported from upstream, skipping clean roll-back or errors due to some
-missing devm_* services.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-sch.c | 140 +++++++++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 133 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index 6715828c3940..1d1dadebc8c1 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -32,6 +32,10 @@
- #define GEN	0x00
- #define GIO	0x04
- #define GLV	0x08
-+#define GTPE	0x0c
-+#define GTNE	0x10
-+#define GGPE	0x14
-+#define GTS	0x1c
- 
- struct sch_gpio {
- 	struct gpio_chip chip;
-@@ -39,6 +43,7 @@ struct sch_gpio {
- 	unsigned short iobase;
- 	unsigned short core_base;
- 	unsigned short resume_base;
-+	int irq_base;
- };
- 
- static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
-@@ -94,10 +99,11 @@ static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
- static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- 	return 0;
- }
- 
-@@ -110,20 +116,22 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GLV, val);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- }
- 
- static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 				  int val)
- {
- 	struct sch_gpio *sch = gpiochip_get_data(gc);
-+	unsigned long flags;
- 
--	spin_lock(&sch->lock);
-+	spin_lock_irqsave(&sch->lock, flags);
- 	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
--	spin_unlock(&sch->lock);
-+	spin_unlock_irqrestore(&sch->lock, flags);
- 
- 	/*
- 	 * according to the datasheet, writing to the level register has no
-@@ -145,6 +153,12 @@ static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned gpio_num)
- 	return sch_gpio_reg_get(sch, gpio_num, GIO);
- }
- 
-+static int sch_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset)
-+{
-+	struct sch_gpio *sch = gpiochip_get_data(gpio);
-+	return sch->irq_base + offset;
-+}
-+
- static struct gpio_chip sch_gpio_chip = {
- 	.label			= "sch_gpio",
- 	.owner			= THIS_MODULE,
-@@ -153,12 +167,96 @@ static struct gpio_chip sch_gpio_chip = {
- 	.direction_output	= sch_gpio_direction_out,
- 	.set			= sch_gpio_set,
- 	.get_direction		= sch_gpio_get_direction,
-+	.to_irq			= sch_gpio_to_irq,
- };
- 
-+static u32 sch_sci_handler(void *context)
-+{
-+	struct sch_gpio *sch = context;
-+	unsigned long core_status, resume_status;
-+	unsigned int resume_gpios, offset;
-+
-+	core_status = inl(sch->iobase + GTS);
-+	resume_status = inl(sch->iobase + GTS + 0x20);
-+
-+	if (core_status == 0 && resume_status == 0)
-+		return ACPI_INTERRUPT_NOT_HANDLED;
-+
-+	for_each_set_bit(offset, &core_status, sch->resume_base)
-+		generic_handle_irq(sch->irq_base + offset);
-+
-+	resume_gpios = sch->chip.ngpio - sch->resume_base;
-+	for_each_set_bit(offset, &resume_status, resume_gpios)
-+		generic_handle_irq(sch->irq_base + sch->resume_base + offset);
-+
-+	outl(core_status, sch->iobase + GTS);
-+	outl(resume_status, sch->iobase + GTS + 0x20);
-+
-+	return ACPI_INTERRUPT_HANDLED;
-+}
-+
-+static int sch_irq_type(struct irq_data *d, unsigned int type)
-+{
-+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-+	struct sch_gpio *sch = gc->private;
-+	unsigned int gpio_num = d->irq - sch->irq_base;
-+	unsigned long flags;
-+	int rising = 0;
-+	int falling = 0;
-+
-+	switch (type & IRQ_TYPE_SENSE_MASK) {
-+	case IRQ_TYPE_EDGE_RISING:
-+		rising = 1;
-+		break;
-+	case IRQ_TYPE_EDGE_FALLING:
-+		falling = 1;
-+		break;
-+	case IRQ_TYPE_EDGE_BOTH:
-+		rising = 1;
-+		falling = 1;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	spin_lock_irqsave(&sch->lock, flags);
-+	sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
-+	sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
-+	spin_unlock_irqrestore(&sch->lock, flags);
-+
-+	return 0;
-+}
-+
-+static void sch_irq_set_enable(struct irq_data *d, int val)
-+{
-+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-+	struct sch_gpio *sch = gc->private;
-+	unsigned int gpio_num = d->irq - sch->irq_base;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&sch->lock, flags);
-+	sch_gpio_reg_set(sch, gpio_num, GGPE, val);
-+	spin_unlock_irqrestore(&sch->lock, flags);
-+}
-+
-+static void sch_irq_mask(struct irq_data *d)
-+{
-+	sch_irq_set_enable(d, 0);
-+}
-+
-+static void sch_irq_unmask(struct irq_data *d)
-+{
-+	sch_irq_set_enable(d, 1);
-+}
-+
- static int sch_gpio_probe(struct platform_device *pdev)
- {
-+	struct irq_chip_generic *gc;
-+	struct irq_chip_type *ct;
- 	struct sch_gpio *sch;
- 	struct resource *res;
-+	acpi_status status;
-+	int irq_base, ret;
- 
- 	sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL);
- 	if (!sch)
-@@ -222,7 +320,35 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
-+	ret = devm_gpiochip_add_data(&pdev->dev, &sch->chip, sch);
-+	if (ret)
-+		return ret;
-+
-+	irq_base = irq_alloc_descs(-1, 0, sch->chip.ngpio, NUMA_NO_NODE);
-+	if (irq_base < 0)
-+		return irq_base;
-+	sch->irq_base = irq_base;
-+
-+	gc = irq_alloc_generic_chip("sch_gpio", 1, irq_base,
-+				    NULL, handle_simple_irq);
-+	if (!gc)
-+		return -ENOMEM;
-+
-+	gc->private = sch;
-+	ct = gc->chip_types;
-+
-+	ct->chip.irq_mask = sch_irq_mask;
-+	ct->chip.irq_unmask = sch_irq_unmask;
-+	ct->chip.irq_set_type = sch_irq_type;
-+
-+	irq_setup_generic_chip(gc, IRQ_MSK(sch->chip.ngpio),
-+			       0, IRQ_NOREQUEST | IRQ_NOPROBE, 0);
-+
-+	status = acpi_install_sci_handler(sch_sci_handler, sch);
-+	if (ACPI_FAILURE(status))
-+		return -EINVAL;
-+
-+	return 0;
- }
- 
- static struct platform_driver sch_gpio_driver = {
--- 
-2.16.4
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0014-iot2000-hack-Work-around-DSDT-mistake.patch

@@ -1,44 +0,0 @@
-From f43a54ec8a8b5f070d4b1b59f3d47dc03f74ad32 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 25 May 2017 11:09:42 +0200
-Subject: [PATCH 14/18] iot2000-hack: Work around DSDT mistake
-
-Until we have a new firmware revision, fix up the incorrect GPIO
-interrupt pin in software.
-
-Nothing for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpiolib-acpi.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
-index 16a7b6816744..304855b3ecb8 100644
---- a/drivers/gpio/gpiolib-acpi.c
-+++ b/drivers/gpio/gpiolib-acpi.c
-@@ -10,6 +10,7 @@
-  * published by the Free Software Foundation.
-  */
- 
-+#include <linux/dmi.h>
- #include <linux/errno.h>
- #include <linux/gpio.h>
- #include <linux/gpio/consumer.h>
-@@ -408,6 +409,13 @@ static int acpi_find_gpio(struct acpi_resource *ares, void *data)
- 		if (pin_index >= agpio->pin_table_length)
- 			return 1;
- 
-+		if (!strcmp(dmi_get_system_info(DMI_BOARD_NAME),
-+			    "SIMATIC IOT2000") &&
-+		    !strcmp(agpio->resource_source.string_ptr,
-+			    "\\_SB.PCI0.GIP0.GPO") &&
-+		    agpio->pin_table[pin_index] == 9)
-+			agpio->pin_table[pin_index] = 1;
-+
- 		lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
- 					      agpio->pin_table[pin_index]);
- 		lookup->info.gpioint =
--- 
-2.16.4
-

+ 0 - 42
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0015-iot2000-hack-Adjust-pca9685-gpio-base-for-legacy-com.patch

@@ -1,42 +0,0 @@
-From 88f2d0ccdee1f1890af0d049c60fe24f6c6eb048 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 25 May 2017 13:05:12 +0200
-Subject: [PATCH 15/18] iot2000-hack: Adjust pca9685-gpio base for legacy
- compatibility
-
-mraa and the Arduino runtime expect this.
-
-Not for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/pwm/pwm-pca9685.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
-index d2b92e940e38..611b9263a896 100644
---- a/drivers/pwm/pwm-pca9685.c
-+++ b/drivers/pwm/pwm-pca9685.c
-@@ -19,6 +19,7 @@
-  * this program.  If not, see <http://www.gnu.org/licenses/>.
-  */
- 
-+#include <linux/dmi.h>
- #include <linux/acpi.h>
- #include <linux/gpio/driver.h>
- #include <linux/i2c.h>
-@@ -222,7 +223,10 @@ static int pca9685_pwm_gpio_probe(struct pca9685 *pca)
- 	pca->gpio.direction_output = pca9685_pwm_gpio_direction_output;
- 	pca->gpio.get = pca9685_pwm_gpio_get;
- 	pca->gpio.set = pca9685_pwm_gpio_set;
--	pca->gpio.base = -1;
-+	if (!strcmp(dmi_get_system_info(DMI_BOARD_NAME), "SIMATIC IOT2000"))
-+		pca->gpio.base = 64;
-+	else
-+		pca->gpio.base = -1;
- 	pca->gpio.ngpio = PCA9685_MAXCHAN;
- 	pca->gpio.can_sleep = true;
- 
--- 
-2.16.4
-

+ 0 - 99
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0016-iot2000-hack-gpio-pca953x-provide-GPIO-base-based-on.patch

@@ -1,99 +0,0 @@
-From 5c102aea3f4ffea811eec719edd638fc7888e9c3 Mon Sep 17 00:00:00 2001
-From: Yong Li <sdliyong@gmail.com>
-Date: Thu, 31 Mar 2016 15:33:08 +0800
-Subject: [PATCH 16/18] iot2000-hack: gpio: pca953x: provide GPIO base based on
- _UID
-
-Custom kernel for Intel Galileo Gen2 provides and moreover libmraa relies on
-the continuous GPIO space. To do such we have to configure GPIO base per each
-GPIO expander. The only value we can use is the ACPI _UID.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-
-Upstream-status: Inappropriate, custom code for legacy userspace
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Yong Li <sdliyong@gmail.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-pca953x.c | 44 +++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 37 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index b45ba6be69ef..8b467c0db1cb 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -82,12 +82,6 @@ static const struct i2c_device_id pca953x_id[] = {
- };
- MODULE_DEVICE_TABLE(i2c, pca953x_id);
- 
--static const struct acpi_device_id pca953x_acpi_ids[] = {
--	{ "INT3491", 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
--	{ }
--};
--MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
--
- #define MAX_BANK 5
- #define BANK_SZ 8
- 
-@@ -119,6 +113,35 @@ static inline struct pca953x_chip *to_pca(struct gpio_chip *gc)
- 	return container_of(gc, struct pca953x_chip, gpio_chip);
- }
- 
-+struct pca953x_info {
-+	kernel_ulong_t driver_data;
-+	void (*setup)(struct pca953x_chip *chip);
-+};
-+
-+static void pca953x_setup_int3491(struct pca953x_chip *chip)
-+{
-+	struct acpi_device *adev = ACPI_COMPANION(&chip->client->dev);
-+	unsigned int uid;
-+
-+	if (kstrtouint(acpi_device_uid(adev), 0, &uid) || !uid--)
-+		return;
-+
-+	chip->gpio_start = 8 /* sch_gpio */ +
-+			   8 /* gpio-dwapb */ +
-+			  16 /* pca9535 */ * uid;
-+}
-+
-+static const struct pca953x_info pca953x_info_int3491 = {
-+	.driver_data = 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL,
-+	.setup = pca953x_setup_int3491,
-+};
-+
-+static const struct acpi_device_id pca953x_acpi_ids[] = {
-+	{ "INT3491",  (kernel_ulong_t)&pca953x_info_int3491 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
-+
- static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
- 				int off)
- {
-@@ -731,12 +754,19 @@ static int pca953x_probe(struct i2c_client *client,
- 		chip->driver_data = id->driver_data;
- 	} else {
- 		const struct acpi_device_id *id;
-+		const struct pca953x_info *info;
- 
- 		id = acpi_match_device(pca953x_acpi_ids, &client->dev);
- 		if (!id)
- 			return -ENODEV;
- 
--		chip->driver_data = id->driver_data;
-+		info = (struct pca953x_info *)id->driver_data;
-+		if (!info)
-+			return -ENODEV;
-+
-+		chip->driver_data = info->driver_data;
-+		if (info->setup)
-+			info->setup(chip);
- 	}
- 
- 	chip->chip_type = PCA_CHIP_TYPE(chip->driver_data);
--- 
-2.16.4
-

+ 0 - 334
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0017-iot2000-hack-gpio-pca953x-add-drive-property.patch

@@ -1,334 +0,0 @@
-From a66a980a3520859c1a01fc65f76c4f2abd2a2eed Mon Sep 17 00:00:00 2001
-From: Yong Li <sdliyong@gmail.com>
-Date: Thu, 31 Mar 2016 15:33:09 +0800
-Subject: [PATCH 17/18] iot2000-hack: gpio-pca953x: add "drive" property
-
-Galileo gen 2 has support for setting GPIO modes. Expose these
-properties through the GPIO sysfs interface. This approach is bit hacky,
-since it changes the interface semantics.
-
-The original patch was by Josef Ahmad <josef.ahmad@linux.intel.com> and
-made on top of kernel 3.8.
-
-Not for upstream.
-
-Signed-off-by: Ismo Puustinen <ismo.puustinen@intel.com>
-Signed-off-by: Jussi Laako <jussi.laako@linux.intel.com>
-Signed-off-by: Saul Wold <sgw@linux.intel.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Yong Li <sdliyong@gmail.com>
-Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/gpio/gpio-pca953x.c   | 42 +++++++++++++++++++++++
- drivers/gpio/gpiolib-sysfs.c  | 78 +++++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib.c        | 17 ++++++++++
- drivers/gpio/gpiolib.h        |  4 +++
- include/asm-generic/gpio.h    |  5 +++
- include/linux/gpio.h          | 10 ++++++
- include/linux/gpio/consumer.h | 11 ++++++
- include/linux/gpio/driver.h   |  2 ++
- 8 files changed, 169 insertions(+)
-
-diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
-index 8b467c0db1cb..ca1f6f4d6f59 100644
---- a/drivers/gpio/gpio-pca953x.c
-+++ b/drivers/gpio/gpio-pca953x.c
-@@ -40,6 +40,8 @@
- #define PCA957X_INTS		7
- 
- #define PCAL953X_IN_LATCH	34
-+#define PCAL953X_PUPD_EN	35
-+#define PCAL953X_PUPD_SEL	36
- #define PCAL953X_INT_MASK	37
- #define PCAL953X_INT_STAT	38
- 
-@@ -380,6 +382,43 @@ exit:
- 	mutex_unlock(&chip->i2c_lock);
- }
- 
-+static int pca953x_gpio_set_drive(struct gpio_chip *gc,
-+				 unsigned off, unsigned mode)
-+{
-+	struct pca953x_chip *chip;
-+	int ret = 0;
-+	int val;
-+
-+	chip = container_of(gc, struct pca953x_chip, gpio_chip);
-+
-+	if (!(chip->driver_data & PCA_PCAL))
-+		return -EINVAL;
-+
-+	mutex_lock(&chip->i2c_lock);
-+
-+	switch (mode) {
-+	case GPIOF_DRIVE_PULLUP:
-+		ret = pca953x_write_single(chip, PCAL953X_PUPD_EN, 1, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, 1, off);
-+		break;
-+	case GPIOF_DRIVE_PULLDOWN:
-+		ret = pca953x_write_single(chip, PCAL953X_PUPD_EN, 1, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, 0, off);
-+		break;
-+	case GPIOF_DRIVE_STRONG:
-+	case GPIOF_DRIVE_HIZ:
-+		ret = pca953x_read_single(chip, PCAL953X_PUPD_EN, &val, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_EN, 0, off) ||
-+			pca953x_write_single(chip, PCAL953X_PUPD_SEL, val, off);
-+		break;
-+	default:
-+		ret = -EINVAL;
-+	}
-+
-+	mutex_unlock(&chip->i2c_lock);
-+	return ret;
-+}
-+
- static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- {
- 	struct gpio_chip *gc;
-@@ -398,6 +437,9 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
- 	gc->dev = &chip->client->dev;
- 	gc->owner = THIS_MODULE;
- 	gc->names = chip->names;
-+
-+	if (chip->driver_data & PCA_PCAL)
-+		gc->set_drive = pca953x_gpio_set_drive;
- }
- 
- #ifdef CONFIG_GPIO_PCA953X_IRQ
-diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
-index b57ed8e55ab5..72a8647146fa 100644
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -7,6 +7,7 @@
- #include <linux/interrupt.h>
- #include <linux/kdev_t.h>
- #include <linux/slab.h>
-+#include <linux/gpio.h>
- 
- #include "gpiolib.h"
- 
-@@ -350,6 +351,82 @@ static ssize_t active_low_store(struct device *dev,
- }
- static DEVICE_ATTR_RW(active_low);
- 
-+
-+static ssize_t gpio_drive_show(struct device *dev,
-+		struct device_attribute *attr, char *buf)
-+{
-+	const struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
-+		status = -EIO;
-+	} else {
-+		if (test_bit(FLAG_PULLUP, &desc->flags))
-+			status = sprintf(buf, "pullup\n");
-+		else if (test_bit(FLAG_PULLDOWN, &desc->flags))
-+			status = sprintf(buf, "pulldown\n");
-+		else if (test_bit(FLAG_STRONG, &desc->flags))
-+			status = sprintf(buf, "strong\n");
-+		else if (test_bit(FLAG_HIZ, &desc->flags))
-+			status = sprintf(buf, "hiz\n");
-+		else
-+			status = -EINVAL;
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status;
-+}
-+
-+static ssize_t gpio_drive_store(struct device *dev,
-+		struct device_attribute *attr, const char *buf, size_t size)
-+{
-+	struct gpio_desc	*desc = dev_get_drvdata(dev);
-+	ssize_t			status;
-+
-+	mutex_lock(&sysfs_lock);
-+
-+	if (!test_bit(FLAG_EXPORT, &desc->flags))
-+		status = -EIO;
-+	else {
-+		clear_bit(FLAG_PULLUP, &desc->flags);
-+		clear_bit(FLAG_PULLDOWN, &desc->flags);
-+		clear_bit(FLAG_STRONG, &desc->flags);
-+		clear_bit(FLAG_HIZ, &desc->flags);
-+		if (sysfs_streq(buf, "pullup")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLUP);
-+			if (!status) {
-+				set_bit(FLAG_PULLUP, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "pulldown")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_PULLDOWN);
-+			if (!status) {
-+				set_bit(FLAG_PULLDOWN, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "strong")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_STRONG);
-+			if (!status) {
-+				set_bit(FLAG_STRONG, &desc->flags);
-+			}
-+		} else if (sysfs_streq(buf, "hiz")) {
-+			status = gpiod_set_drive(desc, GPIOF_DRIVE_HIZ);
-+			if (!status) {
-+				set_bit(FLAG_HIZ, &desc->flags);
-+			}
-+		} else {
-+			status = -EINVAL;
-+		}
-+	}
-+
-+	mutex_unlock(&sysfs_lock);
-+	return status ? : size;
-+}
-+
-+static DEVICE_ATTR(drive, 0644,
-+		gpio_drive_show, gpio_drive_store);
-+
-+
- static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
- 			       int n)
- {
-@@ -377,6 +454,7 @@ static struct attribute *gpio_attrs[] = {
- 	&dev_attr_edge.attr,
- 	&dev_attr_value.attr,
- 	&dev_attr_active_low.attr,
-+	&dev_attr_drive.attr,
- 	NULL,
- };
- 
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index 827510dbba30..d19928b9a311 100644
---- a/drivers/gpio/gpiolib.c
-+++ b/drivers/gpio/gpiolib.c
-@@ -1315,6 +1315,23 @@ int gpiod_is_active_low(const struct gpio_desc *desc)
- }
- EXPORT_SYMBOL_GPL(gpiod_is_active_low);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode)
-+{
-+	struct gpio_chip	*chip;
-+
-+	chip = desc->chip;
-+	if (!chip || !chip->set || !chip->set_drive)
-+		goto fail;
-+
-+	might_sleep_if(chip->can_sleep);
-+
-+	return chip->set_drive(chip, gpio_chip_hwgpio(desc), mode);
-+
-+fail:
-+	return -EINVAL;
-+}
-+EXPORT_SYMBOL_GPL(gpiod_set_drive);
-+
- /* I/O calls are only valid after configuration completed; the relevant
-  * "is this a valid GPIO" error checks should already have been done.
-  *
-diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
-index 07541c5670e6..cfa7406b10fd 100644
---- a/drivers/gpio/gpiolib.h
-+++ b/drivers/gpio/gpiolib.h
-@@ -96,6 +96,10 @@ struct gpio_desc {
- #define FLAG_OPEN_SOURCE 8	/* Gpio is open source type */
- #define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
- #define FLAG_IS_HOGGED	11	/* GPIO is hogged */
-+#define FLAG_PULLUP	12	/* Gpio drive is resistive pullup */
-+#define FLAG_PULLDOWN	13	/* Gpio drive is resistive pulldown */
-+#define FLAG_STRONG	14	/* Gpio drive is strong (fast output) */
-+#define FLAG_HIZ	15	/* Gpio drive is Hi-Z (input) */
- 
- 	/* Connection label */
- 	const char		*label;
-diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
-index 40ec1433f05d..519e8d458878 100644
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -76,6 +76,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return gpiod_set_debounce(gpio_to_desc(gpio), debounce);
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return gpiod_set_drive(gpio_to_desc(gpio), mode);
-+}
-+
- static inline int gpio_get_value_cansleep(unsigned gpio)
- {
- 	return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio));
-diff --git a/include/linux/gpio.h b/include/linux/gpio.h
-index d12b5d566e4b..344e62d27700 100644
---- a/include/linux/gpio.h
-+++ b/include/linux/gpio.h
-@@ -30,6 +30,11 @@
- #define GPIOF_EXPORT_DIR_FIXED	(GPIOF_EXPORT)
- #define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE)
- 
-+#define GPIOF_DRIVE_PULLUP	(1 << 7)
-+#define GPIOF_DRIVE_PULLDOWN	(1 << 8)
-+#define GPIOF_DRIVE_STRONG	(1 << 9)
-+#define GPIOF_DRIVE_HIZ		(1 << 10)
-+
- /**
-  * struct gpio - a structure describing a GPIO with configuration
-  * @gpio:	the GPIO number
-@@ -148,6 +153,11 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+static inline int gpio_set_drive(unsigned gpio, unsigned mode)
-+{
-+	return -ENOSYS;
-+}
-+
- static inline int gpio_get_value(unsigned gpio)
- {
- 	/* GPIO can never have been requested or set as {in,out}put */
-diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
-index fb0fde686cb1..17f5f187699b 100644
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -122,6 +122,8 @@ void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
- 
- int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
- 
-+int gpiod_set_drive(struct gpio_desc *desc, unsigned mode);
-+
- int gpiod_is_active_low(const struct gpio_desc *desc);
- int gpiod_cansleep(const struct gpio_desc *desc);
- 
-@@ -376,6 +378,15 @@ static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
- 	return -ENOSYS;
- }
- 
-+
-+static inline int gpiod_set_drive(unsigned gpio, unsigned mode)
-+{
-+	/* GPIO can never have been requested */
-+	WARN_ON(1);
-+	return -ENOSYS;
-+}
-+
-+
- static inline int gpiod_is_active_low(const struct gpio_desc *desc)
- {
- 	/* GPIO can never have been requested */
-diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
-index de502c7e4171..d59080ba9fec 100644
---- a/include/linux/gpio/driver.h
-+++ b/include/linux/gpio/driver.h
-@@ -116,6 +116,8 @@ struct gpio_chip {
- 	int			(*set_debounce)(struct gpio_chip *chip,
- 						unsigned offset,
- 						unsigned debounce);
-+	int			(*set_drive)(struct gpio_chip *chip,
-+						unsigned offset, unsigned mode);
- 
- 	int			(*to_irq)(struct gpio_chip *chip,
- 						unsigned offset);
--- 
-2.16.4
-

+ 0 - 105
board/PSG/iot2000/linux-4.4-patches_orig/linux-4.4-patches/0018-iot2000-hack-pwm-pca-9685-Provide-chip-level-pwm_per.patch

@@ -1,105 +0,0 @@
-From c25a8e605bcbb0ed2adde384587ffcfcf5783eef Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Fri, 17 Nov 2017 20:25:54 +0100
-Subject: [PATCH 18/18] iot2000-hack: pwm: pca-9685: Provide chip-level
- pwm_period attribute
-
-Arduino runtime relies on this path to program the PWM period, rather
-than doing this via the upstream kernel API which is per channel.
-
-Another one not for upstream.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/pwm/pwm-pca9685.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
-
-diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
-index 611b9263a896..ce765f903714 100644
---- a/drivers/pwm/pwm-pca9685.c
-+++ b/drivers/pwm/pwm-pca9685.c
-@@ -444,6 +444,54 @@ static const struct pwm_ops pca9685_pwm_ops = {
- 	.owner = THIS_MODULE,
- };
- 
-+static ssize_t pwm_period_show(struct device *parent,
-+			       struct device_attribute *attr,
-+			       char *buf)
-+{
-+	struct pwm_chip *chip = dev_get_drvdata(parent);
-+
-+	return sprintf(buf, "%u\n", to_pca(chip)->period_ns);
-+}
-+
-+static ssize_t pwm_period_store(struct device *parent,
-+				struct device_attribute *attr,
-+				const char *buf, size_t size)
-+{
-+	struct pwm_chip *chip = dev_get_drvdata(parent);
-+	struct pca9685 *pca = to_pca(chip);
-+	int old_period_ns = pca->period_ns;
-+	unsigned long long duty_scale, new_duty_ns;
-+	unsigned int val, channel;
-+	struct pwm_device *pwm;
-+	int ret;
-+
-+	ret = kstrtouint(buf, 0, &val);
-+	if (ret)
-+		return ret;
-+
-+	for (channel = 0; channel < PCA9685_MAXCHAN; channel++) {
-+		pwm = &chip->pwms[channel];
-+
-+		if (pca9685_pwm_is_gpio(pca, pwm))
-+			continue;
-+
-+		/* Scale the rise time to maintain duty cycle */
-+		duty_scale = val;
-+		duty_scale *= 1000000;
-+		do_div(duty_scale, old_period_ns);
-+		new_duty_ns = duty_scale * pwm_get_duty_cycle(pwm);
-+		do_div(new_duty_ns, 1000000);
-+		/* Update the duty_cycle */
-+		ret = pwm_config(pwm, (int)new_duty_ns, val);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return size;
-+}
-+
-+static DEVICE_ATTR_RW(pwm_period);
-+
- static const struct regmap_config pca9685_regmap_i2c_config = {
- 	.reg_bits = 8,
- 	.val_bits = 8,
-@@ -504,8 +552,17 @@ static int pca9685_pwm_probe(struct i2c_client *client,
- 	if (ret < 0)
- 		return ret;
- 
-+	ret = sysfs_create_file(&pca->chip.dev->kobj,
-+				&dev_attr_pwm_period.attr);
-+	if (ret < 0) {
-+		pwmchip_remove(&pca->chip);
-+		return ret;
-+	}
-+
- 	ret = pca9685_pwm_gpio_probe(pca);
- 	if (ret < 0) {
-+		sysfs_remove_file(&pca->chip.dev->kobj,
-+				  &dev_attr_pwm_period.attr);
- 		pwmchip_remove(&pca->chip);
- 		return ret;
- 	}
-@@ -526,6 +583,8 @@ static int pca9685_pwm_remove(struct i2c_client *client)
- 	struct pca9685 *pca = i2c_get_clientdata(client);
- 	int ret;
- 
-+	sysfs_remove_file(&pca->chip.dev->kobj, &dev_attr_pwm_period.attr);
-+
- 	ret = pwmchip_remove(&pca->chip);
- 	if (ret)
- 		return ret;
--- 
-2.16.4
-

+ 0 - 90
board/PSG/iot2000/linux-4.4-rt-patches/0001-stmmac-pci-Make-stmmac_pci_info-structure-constant.patch

@@ -1,90 +0,0 @@
-From 2ca48f47b659edbd5cf4c4e55c420ef40712ce9b Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:57 +0200
-Subject: [PATCH 01/18] stmmac: pci: Make stmmac_pci_info structure constant
-
-Commit c5d5287ef0f763e836bf94659b3a6080358373f1 upstream.
-
-By removing the PCI device reference from the structure and passing it
-as parameters to the interested functions, we can make quark_pci_info
-const.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 23 +++++++++++------------
- 1 file changed, 11 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 3491e98bffc5..828d276748e3 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,17 +42,17 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	struct pci_dev *pdev;
--	int (*setup)(struct plat_stmmacenet_data *plat,
--		     struct stmmac_pci_info *info);
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
-+		     const struct stmmac_pci_info *info);
- 	struct stmmac_pci_dmi_data *dmi;
- };
- 
--static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
-+static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
-+				    const struct stmmac_pci_info *info)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(info->pdev->devfn);
-+	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
- 	/*
-@@ -96,17 +96,17 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 	plat->unicast_filter_entries = 1;
- }
- 
--static int quark_default_data(struct plat_stmmacenet_data *plat,
--			      struct stmmac_pci_info *info)
-+static int quark_default_data(struct pci_dev *pdev,
-+			      struct plat_stmmacenet_data *plat,
-+			      const struct stmmac_pci_info *info)
- {
--	struct pci_dev *pdev = info->pdev;
- 	int ret;
- 
- 	/*
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(info);
-+	ret = stmmac_pci_find_phy_addr(pdev, info);
- 	if (ret < 0)
- 		return ret;
- 
-@@ -165,7 +165,7 @@ static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
- 	{}
- };
- 
--static struct stmmac_pci_info quark_pci_info = {
-+static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
- 	.dmi = quark_pci_dmi_data,
- };
-@@ -227,9 +227,8 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 	pci_set_master(pdev);
- 
- 	if (info) {
--		info->pdev = pdev;
- 		if (info->setup) {
--			ret = info->setup(plat, info);
-+			ret = info->setup(pdev, plat, info);
- 			if (ret)
- 				return ret;
- 		}
--- 
-2.16.4
-

+ 0 - 95
board/PSG/iot2000/linux-4.4-rt-patches/0002-stmmac-pci-Use-stmmac_pci_info-for-all-devices.patch

@@ -1,95 +0,0 @@
-From 5222a576c02eed33b0499a7e632a56680742a885 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:58 +0200
-Subject: [PATCH 02/18] stmmac: pci: Use stmmac_pci_info for all devices
-
-Commit b6a4c8f013ea2dd1ead7ee14b44712189a7bc6c6 upstream.
-
-Make stmmac_default_data compatible with stmmac_pci_info.setup and use
-an info structure for all devices. This allows to make the probing more
-regular.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 36 +++++++++++++++---------
- 1 file changed, 23 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 828d276748e3..a60059032dc6 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -74,7 +74,9 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	return -ENODEV;
- }
- 
--static void stmmac_default_data(struct plat_stmmacenet_data *plat)
-+static int stmmac_default_data(struct pci_dev *pdev,
-+			       struct plat_stmmacenet_data *plat,
-+			       const struct stmmac_pci_info *info)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -94,8 +96,14 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
- 
- 	/* Set default value for unicast filter entries */
- 	plat->unicast_filter_entries = 1;
-+
-+	return 0;
- }
- 
-+static const struct stmmac_pci_info stmmac_pci_info = {
-+	.setup = stmmac_default_data,
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
- 			      struct plat_stmmacenet_data *plat,
- 			      const struct stmmac_pci_info *info)
-@@ -226,14 +234,9 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	if (info) {
--		if (info->setup) {
--			ret = info->setup(pdev, plat, info);
--			if (ret)
--				return ret;
--		}
--	} else
--		stmmac_default_data(plat);
-+	ret = info->setup(pdev, plat, info);
-+	if (ret)
-+		return ret;
- 
- 	pci_enable_msi(pdev);
- 
-@@ -279,14 +282,21 @@ static int stmmac_pci_resume(struct device *dev)
- 
- static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
- 
--#define STMMAC_VENDOR_ID 0x700
-+/* synthetic ID, no official vendor */
-+#define PCI_VENDOR_ID_STMMAC 0x700
-+
- #define STMMAC_QUARK_ID  0x0937
- #define STMMAC_DEVICE_ID 0x1108
- 
-+#define STMMAC_DEVICE(vendor_id, dev_id, info)	{	\
-+	PCI_VDEVICE(vendor_id, dev_id),			\
-+	.driver_data = (kernel_ulong_t)&info		\
-+	}
-+
- static const struct pci_device_id stmmac_id_table[] = {
--	{PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)},
--	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)},
--	{PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info},
-+	STMMAC_DEVICE(STMMAC, STMMAC_DEVICE_ID, stmmac_pci_info),
-+	STMMAC_DEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_MAC, stmmac_pci_info),
-+	STMMAC_DEVICE(INTEL, STMMAC_QUARK_ID, quark_pci_info),
- 	{}
- };
- 
--- 
-2.16.4
-

+ 0 - 61
board/PSG/iot2000/linux-4.4-rt-patches/0003-stmmac-pci-Make-stmmac_pci_find_phy_addr-truly-gener.patch

@@ -1,61 +0,0 @@
-From d9478f26f2c620cf284f5022d3d852c47227e8da Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:17:59 +0200
-Subject: [PATCH 03/18] stmmac: pci: Make stmmac_pci_find_phy_addr truly
- generic
-
-Commit c5f657e49c878756f21349f9e4b0f1c9631d5352 upstream.
-
-Move the special case for the early Galileo firmware into
-quark_default_setup. This allows to use stmmac_pci_find_phy_addr for
-non-quark cases.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 20 +++++++++++++-------
- 1 file changed, 13 insertions(+), 7 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index a60059032dc6..19cf9607618a 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -55,12 +55,8 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	unsigned int func = PCI_FUNC(pdev->devfn);
- 	struct stmmac_pci_dmi_data *dmi;
- 
--	/*
--	 * Galileo boards with old firmware don't support DMI. We always return
--	 * 1 here, so at least first found MAC controller would be probed.
--	 */
- 	if (!name)
--		return 1;
-+		return -ENODEV;
- 
- 	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
-@@ -115,8 +111,18 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * does not connect to any PHY interface.
- 	 */
- 	ret = stmmac_pci_find_phy_addr(pdev, info);
--	if (ret < 0)
--		return ret;
-+	if (ret < 0) {
-+		/* Return error to the caller on DMI enabled boards. */
-+		if (dmi_get_system_info(DMI_BOARD_NAME))
-+			return ret;
-+
-+		/*
-+		 * Galileo boards with old firmware don't support DMI. We always
-+		 * use 1 here as PHY address, so at least the first found MAC
-+		 * controller would be probed.
-+		 */
-+		ret = 1;
-+	}
- 
- 	plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
- 	plat->phy_addr = ret;
--- 
-2.16.4
-

+ 0 - 165
board/PSG/iot2000/linux-4.4-rt-patches/0004-stmmac-pci-Select-quark_pci_dmi_data-from-quark_defa.patch

@@ -1,165 +0,0 @@
-From 0747f34d4be27952be866461c97d386c29000817 Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:00 +0200
-Subject: [PATCH 04/18] stmmac: pci: Select quark_pci_dmi_data from
- quark_default_data
-
-Commit 7bc519b3ea04026877242328d2fe73cc8e6102bd upsteam.
-
-No need to carry this reference in stmmac_pci_info - the Quark-specific
-setup handler knows that it needs to use the Quark-specific DMI table.
-This also allows to drop the stmmac_pci_info reference from the setup
-handler parameter list.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 83 +++++++++++-------------
- 1 file changed, 39 insertions(+), 44 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 19cf9607618a..9fe6368738ec 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -42,13 +42,11 @@ struct stmmac_pci_dmi_data {
- };
- 
- struct stmmac_pci_info {
--	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat,
--		     const struct stmmac_pci_info *info);
--	struct stmmac_pci_dmi_data *dmi;
-+	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    const struct stmmac_pci_info *info)
-+				    struct stmmac_pci_dmi_data *dmi_data)
- {
- 	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
- 	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
-@@ -58,7 +56,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- 	if (!name)
- 		return -ENODEV;
- 
--	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
-+	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
- 		if (!strcmp(dmi->name, name) && dmi->func == func) {
- 			/* If asset tag is provided, match on it as well. */
- 			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
-@@ -71,8 +69,7 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
- }
- 
- static int stmmac_default_data(struct pci_dev *pdev,
--			       struct plat_stmmacenet_data *plat,
--			       const struct stmmac_pci_info *info)
-+			       struct plat_stmmacenet_data *plat)
- {
- 	plat->bus_id = 1;
- 	plat->phy_addr = 0;
-@@ -100,9 +97,40 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
-+static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+	{
-+		.name = "Galileo",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "GalileoGen2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-0YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "SIMATIC IOT2000",
-+		.asset_tag = "6ES7647-0AA00-1YA2",
-+		.func = 7,
-+		.phy_addr = 1,
-+	},
-+	{}
-+};
-+
- static int quark_default_data(struct pci_dev *pdev,
--			      struct plat_stmmacenet_data *plat,
--			      const struct stmmac_pci_info *info)
-+			      struct plat_stmmacenet_data *plat)
- {
- 	int ret;
- 
-@@ -110,7 +138,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, info);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
-@@ -147,41 +175,8 @@ static int quark_default_data(struct pci_dev *pdev,
- 	return 0;
- }
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
--	{
--		.name = "Galileo",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "GalileoGen2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
--	},
--	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
--	},
--	{}
--};
--
- static const struct stmmac_pci_info quark_pci_info = {
- 	.setup = quark_default_data,
--	.dmi = quark_pci_dmi_data,
- };
- 
- /**
-@@ -240,7 +235,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	ret = info->setup(pdev, plat, info);
-+	ret = info->setup(pdev, plat);
- 	if (ret)
- 		return ret;
- 
--- 
-2.16.4
-

+ 0 - 167
board/PSG/iot2000/linux-4.4-rt-patches/0005-stmmac-pci-Use-dmi_system_id-table-for-retrieving-PH.patch

@@ -1,167 +0,0 @@
-From 1b2894107ad2d9de45402ecc4ffe14f075a08bbc Mon Sep 17 00:00:00 2001
-From: Jan Kiszka <jan.kiszka@siemens.com>
-Date: Thu, 22 Jun 2017 08:18:01 +0200
-Subject: [PATCH 05/18] stmmac: pci: Use dmi_system_id table for retrieving PHY
- addresses
-
-Commit 8d78b69091845386b6096f3adae98f28b9bf96ed upstream.
-
-Avoids reimplementation of DMI matching in stmmac_pci_find_phy_addr.
-
-Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 97 ++++++++++++++++--------
- 1 file changed, 64 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 9fe6368738ec..279a1355d75f 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -34,36 +34,39 @@
-  * negative value of the address means that MAC controller is not connected
-  * with PHY.
-  */
--struct stmmac_pci_dmi_data {
--	const char *name;
--	const char *asset_tag;
-+struct stmmac_pci_func_data {
- 	unsigned int func;
- 	int phy_addr;
- };
- 
-+struct stmmac_pci_dmi_data {
-+	const struct stmmac_pci_func_data *func;
-+	size_t nfuncs;
-+};
-+
- struct stmmac_pci_info {
- 	int (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);
- };
- 
- static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
--				    struct stmmac_pci_dmi_data *dmi_data)
-+				    const struct dmi_system_id *dmi_list)
- {
--	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
--	const char *asset_tag = dmi_get_system_info(DMI_BOARD_ASSET_TAG);
--	unsigned int func = PCI_FUNC(pdev->devfn);
--	struct stmmac_pci_dmi_data *dmi;
--
--	if (!name)
-+	const struct stmmac_pci_func_data *func_data;
-+	const struct stmmac_pci_dmi_data *dmi_data;
-+	const struct dmi_system_id *dmi_id;
-+	int func = PCI_FUNC(pdev->devfn);
-+	size_t n;
-+
-+	dmi_id = dmi_first_match(dmi_list);
-+	if (!dmi_id)
- 		return -ENODEV;
- 
--	for (dmi = dmi_data; dmi->name && *dmi->name; dmi++) {
--		if (!strcmp(dmi->name, name) && dmi->func == func) {
--			/* If asset tag is provided, match on it as well. */
--			if (dmi->asset_tag && strcmp(dmi->asset_tag, asset_tag))
--				continue;
--			return dmi->phy_addr;
--		}
--	}
-+	dmi_data = dmi_id->driver_data;
-+	func_data = dmi_data->func;
-+
-+	for (n = 0; n < dmi_data->nfuncs; n++, func_data++)
-+		if (func_data->func == func)
-+			return func_data->phy_addr;
- 
- 	return -ENODEV;
- }
-@@ -97,34 +100,62 @@ static const struct stmmac_pci_info stmmac_pci_info = {
- 	.setup = stmmac_default_data,
- };
- 
--static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {
- 	{
--		.name = "Galileo",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = {
-+	.func = galileo_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(galileo_stmmac_func_data),
-+};
-+
-+static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = {
- 	{
--		.name = "GalileoGen2",
- 		.func = 6,
- 		.phy_addr = 1,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-0YA2",
--		.func = 6,
-+		.func = 7,
- 		.phy_addr = 1,
- 	},
-+};
-+
-+static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = {
-+	.func = iot2040_stmmac_func_data,
-+	.nfuncs = ARRAY_SIZE(iot2040_stmmac_func_data),
-+};
-+
-+static const struct dmi_system_id quark_pci_dmi[] = {
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 6,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
- 	{
--		.name = "SIMATIC IOT2000",
--		.asset_tag = "6ES7647-0AA00-1YA2",
--		.func = 7,
--		.phy_addr = 1,
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-0YA2"),
-+		},
-+		.driver_data = (void *)&galileo_stmmac_dmi_data,
-+	},
-+	{
-+		.matches = {
-+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
-+			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
-+					"6ES7647-0AA00-1YA2"),
-+		},
-+		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
- 	{}
- };
-@@ -138,7 +169,7 @@ static int quark_default_data(struct pci_dev *pdev,
- 	 * Refuse to load the driver and register net device if MAC controller
- 	 * does not connect to any PHY interface.
- 	 */
--	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi_data);
-+	ret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi);
- 	if (ret < 0) {
- 		/* Return error to the caller on DMI enabled boards. */
- 		if (dmi_get_system_info(DMI_BOARD_NAME))
--- 
-2.16.4
-

+ 0 - 47
board/PSG/iot2000/linux-4.4-rt-patches/0006-stmmac-pci-Adjust-IOT2000-matching.patch

@@ -1,47 +0,0 @@
-From e3ba8c4f83c6c206a20e4645a37612b1e10580c6 Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:08:11 +0200
-Subject: [PATCH 06/18] stmmac: pci: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. The IOT2020 is identified by its unique
-asset tag. Match on it first. If we then match on the board name only,
-we will catch all IOT2040 variants. In the future there will be no other
-devices with the "SIMATIC IOT2000" DMI board name but different
-hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-index 279a1355d75f..ac733d4d3ed4 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -149,11 +149,15 @@ static const struct dmi_system_id quark_pci_dmi[] = {
- 		},
- 		.driver_data = (void *)&galileo_stmmac_dmi_data,
- 	},
-+	/*
-+	 * There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040.
-+	 * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which
-+	 * has only one pci network device while other asset tags are
-+	 * for IOT2040 which has two.
-+	 */
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_stmmac_dmi_data,
- 	},
--- 
-2.16.4
-

+ 0 - 44
board/PSG/iot2000/linux-4.4-rt-patches/0007-serial-8250_exar-Adjust-IOT2000-matching.patch

@@ -1,44 +0,0 @@
-From df74e188ffc38176d4caba969e104d2ab2e4e609 Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:12:37 +0200
-Subject: [PATCH 07/18] serial: 8250_exar: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-As only the IOT2040 variants have the Exar chip on board, matching on
-their board name is enough. In the future there will be no other devices
-with the "SIMATIC IOT2000" DMI board name but different hardware.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/tty/serial/8250/8250_exar.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
-index be82707d6cb8..3eb3a7674a0f 100644
---- a/drivers/tty/serial/8250/8250_exar.c
-+++ b/drivers/tty/serial/8250/8250_exar.c
-@@ -338,12 +338,15 @@ static const struct exar8250_platform iot2040_platform = {
- 	.register_gpio = iot2040_register_gpio,
- };
- 
-+/*
-+ * For SIMATIC IOT2000, only IOT2040 and its variants have the Exar device,
-+ * IOT2020 doesn't have. Therefore it is sufficient to match on the common
-+ * board name after the device was found.
-+ */
- static const struct dmi_system_id exar_platforms[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)&iot2040_platform,
- 	},
--- 
-2.16.4
-

+ 0 - 45
board/PSG/iot2000/linux-4.4-rt-patches/0008-mfd-intel_quark_i2c_gpio-Adjust-IOT2000-matching.patch

@@ -1,45 +0,0 @@
-From 6e378b789ebcfcdc4ae957b25f1ac6eb2ef64edc Mon Sep 17 00:00:00 2001
-From: Su Bao Cheng <baocheng.su@siemens.com>
-Date: Fri, 12 Oct 2018 15:05:07 +0200
-Subject: [PATCH 08/18] mfd: intel_quark_i2c_gpio: Adjust IOT2000 matching
-
-Since there are more IOT2040 variants with identical hardware but
-different asset tags, the asset tag matching should be adjusted to
-support them.
-
-For the board name "SIMATIC IOT2000", currently there are 2 types of
-hardware, IOT2020 and IOT2040. Both are identical regarding the
-intel_quark_i2c_gpio. In the future there will be no other devices with
-the "SIMATIC IOT2000" DMI board name but different hardware. So remove
-the asset tag matching from this driver.
-
-Signed-off-by: Su Bao Cheng <baocheng.su@siemens.com>
-Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
----
- drivers/mfd/intel_quark_i2c_gpio.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
-diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
-index 1c09604978d3..ad70a058bea8 100644
---- a/drivers/mfd/intel_quark_i2c_gpio.c
-+++ b/drivers/mfd/intel_quark_i2c_gpio.c
-@@ -76,16 +76,6 @@ static const struct dmi_system_id dmi_platform_info[] = {
- 	{
- 		.matches = {
- 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-0YA2"),
--		},
--		.driver_data = (void *)400000,
--	},
--	{
--		.matches = {
--			DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
--			DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
--					"6ES7647-0AA00-1YA2"),
- 		},
- 		.driver_data = (void *)400000,
- 	},
--- 
-2.16.4
-

+ 0 - 86
board/PSG/iot2000/linux-4.4-rt-patches/0009-gpio-sch-use-gpiochip-data-pointer.patch

@@ -1,86 +0,0 @@
-From cf3d1330c71d47c4cdb9268f68d2ee5931890d93 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Dec 2015 14:21:49 +0100
-Subject: [PATCH 09/18] gpio: sch: use gpiochip data pointer
-
-This makes the driver use the data pointer added to the gpio_chip
-to store a pointer to the state container instead of relying on
-container_of().
-
-Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
-Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/gpio/gpio-sch.c | 14 ++++++--------
- 1 file changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
-index b72906f5b999..23907fc080a3 100644
---- a/drivers/gpio/gpio-sch.c
-+++ b/drivers/gpio/gpio-sch.c
-@@ -41,8 +41,6 @@ struct sch_gpio {
- 	unsigned short resume_base;
- };
- 
--#define to_sch_gpio(gc)	container_of(gc, struct sch_gpio, chip)
--
- static unsigned sch_gpio_offset(struct sch_gpio *sch, unsigned gpio,
- 				unsigned reg)
- {
-@@ -65,7 +63,7 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
- 
- static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -80,7 +78,7 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
- static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 			     int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 	unsigned short offset, bit;
- 	u8 reg_val;
- 
-@@ -97,7 +95,7 @@ static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
- 
- static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
-@@ -112,7 +110,7 @@ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
- 
- static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GLV, val);
-@@ -122,7 +120,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
- static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
- 				  int val)
- {
--	struct sch_gpio *sch = to_sch_gpio(gc);
-+	struct sch_gpio *sch = gpiochip_get_data(gc);
- 
- 	spin_lock(&sch->lock);
- 	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
-@@ -217,7 +215,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
- 
- 	platform_set_drvdata(pdev, sch);
- 
--	return gpiochip_add(&sch->chip);
-+	return gpiochip_add_data(&sch->chip, sch);
- }
- 
- static int sch_gpio_remove(struct platform_device *pdev)
--- 
-2.16.4
-

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels