From 8d71762339135fabae57c394fa8acac032257ceb Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Sun, 8 Oct 2023 20:26:02 +0200 Subject: kernel 6.5.6 --- SOURCES/Patchlist.changelog | 12 + SOURCES/kernel-aarch64-16k-debug-fedora.config | 18 +- SOURCES/kernel-aarch64-16k-fedora.config | 18 +- SOURCES/kernel-aarch64-64k-debug-rhel.config | 2 +- SOURCES/kernel-aarch64-64k-rhel.config | 2 +- SOURCES/kernel-aarch64-debug-fedora.config | 18 +- SOURCES/kernel-aarch64-debug-rhel.config | 2 +- SOURCES/kernel-aarch64-fedora.config | 18 +- SOURCES/kernel-aarch64-rhel.config | 2 +- SOURCES/kernel-aarch64-rt-debug-rhel.config | 2 +- SOURCES/kernel-aarch64-rt-rhel.config | 2 +- SOURCES/kernel-ppc64le-debug-fedora.config | 1 - SOURCES/kernel-ppc64le-debug-rhel.config | 1 - SOURCES/kernel-ppc64le-fedora.config | 1 - SOURCES/kernel-ppc64le-rhel.config | 1 - SOURCES/kernel-s390x-debug-fedora.config | 1 - SOURCES/kernel-s390x-debug-rhel.config | 1 - SOURCES/kernel-s390x-fedora.config | 1 - SOURCES/kernel-s390x-rhel.config | 1 - SOURCES/kernel-s390x-zfcpdump-rhel.config | 1 - SOURCES/kernel-x86_64-debug-fedora.config | 1 - SOURCES/kernel-x86_64-debug-rhel.config | 1 - SOURCES/kernel-x86_64-fedora.config | 1 - SOURCES/kernel-x86_64-rhel.config | 1 - SOURCES/kernel-x86_64-rt-debug-rhel.config | 1 - SOURCES/kernel-x86_64-rt-rhel.config | 1 - SOURCES/linux-surface.patch | 5493 +++++++++++++++--------- SOURCES/patch-6.5-redhat.patch | 505 +-- SPECS/kernel.spec | 26 +- 29 files changed, 3620 insertions(+), 2515 deletions(-) diff --git a/SOURCES/Patchlist.changelog b/SOURCES/Patchlist.changelog index f6fc81e..cc876ad 100644 --- a/SOURCES/Patchlist.changelog +++ b/SOURCES/Patchlist.changelog @@ -1,3 +1,15 @@ +"https://gitlab.com/cki-project/kernel-ark/-/commit"/9ed1817997b0d2f283275cce33cd7043b220d990 + 9ed1817997b0d2f283275cce33cd7043b220d990 power: supply: core: Use blocking_notifier_call_chain to avoid RCU complaint + +"https://gitlab.com/cki-project/kernel-ark/-/commit"/a3359bb88c8debcf1ed9aeeab15090cff336c8fd + a3359bb88c8debcf1ed9aeeab15090cff336c8fd Revert "Add linux-next specific files for 20231004" + +"https://gitlab.com/cki-project/kernel-ark/-/commit"/4ef04c8ed25522fe1e4f917fe557716145c7361d + 4ef04c8ed25522fe1e4f917fe557716145c7361d Add linux-next specific files for 20231004 + +"https://gitlab.com/cki-project/kernel-ark/-/commit"/afdab9b20ab7455f752527125b57c92d24601c6e + afdab9b20ab7455f752527125b57c92d24601c6e drm/amdgpu: set completion status as preempted for the resubmission + "https://gitlab.com/cki-project/kernel-ark/-/commit"/fe8fa52d7059d2dd7b171a0ad1a53bd55c7d449a fe8fa52d7059d2dd7b171a0ad1a53bd55c7d449a iommu/apple-dart: Handle DMA_FQ domains in attach_dev() diff --git a/SOURCES/kernel-aarch64-16k-debug-fedora.config b/SOURCES/kernel-aarch64-16k-debug-fedora.config index 2091ea1..c19a4ca 100644 --- a/SOURCES/kernel-aarch64-16k-debug-fedora.config +++ b/SOURCES/kernel-aarch64-16k-debug-fedora.config @@ -3392,7 +3392,7 @@ CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_QCM2290=m # CONFIG_INTERCONNECT_QCOM_QCS404 is not set # CONFIG_INTERCONNECT_QCOM_QDU1000 is not set -# CONFIG_INTERCONNECT_QCOM_SA8775P is not set +CONFIG_INTERCONNECT_QCOM_SA8775P=m CONFIG_INTERCONNECT_QCOM_SC7180=y CONFIG_INTERCONNECT_QCOM_SC7280=m CONFIG_INTERCONNECT_QCOM_SC8180X=m @@ -5365,7 +5365,7 @@ CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_MESON_EFUSE=m CONFIG_NVMEM_MESON_MX_EFUSE=m CONFIG_NVMEM_QCOM_QFPROM=m -# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_REBOOT_MODE=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m CONFIG_NVMEM_ROCKCHIP_OTP=m @@ -5682,7 +5682,7 @@ CONFIG_PHY_QCOM_QMP_PCIE=m CONFIG_PHY_QCOM_QMP_UFS=m CONFIG_PHY_QCOM_QMP_USB=m CONFIG_PHY_QCOM_QUSB2=m -# CONFIG_PHY_QCOM_SGMII_ETH is not set +CONFIG_PHY_QCOM_SGMII_ETH=m CONFIG_PHY_QCOM_SNPS_EUSB2=m CONFIG_PHY_QCOM_USB_HS_28NM=m CONFIG_PHY_QCOM_USB_HSIC=m @@ -5788,7 +5788,7 @@ CONFIG_PINCTRL_QDF2XXX=m # CONFIG_PINCTRL_QDU1000 is not set CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_ROCKCHIP=y -# CONFIG_PINCTRL_SA8775P is not set +CONFIG_PINCTRL_SA8775P=m CONFIG_PINCTRL_SC7180=y CONFIG_PINCTRL_SC7280_LPASS_LPI=m CONFIG_PINCTRL_SC7280=m @@ -6642,8 +6642,8 @@ CONFIG_RXKAD=y CONFIG_S2IO=m # CONFIG_S390_KPROBES_SANITY_TEST is not set # CONFIG_S390_MODULES_SANITY_TEST is not set -# CONFIG_SA_GCC_8775P is not set -# CONFIG_SA_GPUCC_8775P is not set +CONFIG_SA_GCC_8775P=m +CONFIG_SA_GPUCC_8775P=m # CONFIG_SAMPLE_FPROBE is not set # CONFIG_SAMPLES is not set CONFIG_SATA_ACARD_AHCI=m @@ -8040,7 +8040,7 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_OMAP24XX=m CONFIG_SPI_ORION=m @@ -8461,11 +8461,11 @@ CONFIG_TIPC=m CONFIG_TIPC_MEDIA_UDP=y CONFIG_TI_PRUSS_INTC=m CONFIG_TI_PRUSS=m -CONFIG_TI_SCI_CLK=m # CONFIG_TI_SCI_CLK_PROBE_FROM_FW is not set +CONFIG_TI_SCI_CLK=y CONFIG_TI_SCI_INTA_IRQCHIP=y CONFIG_TI_SCI_INTR_IRQCHIP=y -CONFIG_TI_SCI_PM_DOMAINS=m +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_TI_SCI_PROTOCOL=y # CONFIG_TI_ST is not set CONFIG_TI_SYSCON_CLK=m diff --git a/SOURCES/kernel-aarch64-16k-fedora.config b/SOURCES/kernel-aarch64-16k-fedora.config index 9913a6f..f06302f 100644 --- a/SOURCES/kernel-aarch64-16k-fedora.config +++ b/SOURCES/kernel-aarch64-16k-fedora.config @@ -3375,7 +3375,7 @@ CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_QCM2290=m # CONFIG_INTERCONNECT_QCOM_QCS404 is not set # CONFIG_INTERCONNECT_QCOM_QDU1000 is not set -# CONFIG_INTERCONNECT_QCOM_SA8775P is not set +CONFIG_INTERCONNECT_QCOM_SA8775P=m CONFIG_INTERCONNECT_QCOM_SC7180=y CONFIG_INTERCONNECT_QCOM_SC7280=m CONFIG_INTERCONNECT_QCOM_SC8180X=m @@ -5339,7 +5339,7 @@ CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_MESON_EFUSE=m CONFIG_NVMEM_MESON_MX_EFUSE=m CONFIG_NVMEM_QCOM_QFPROM=m -# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_REBOOT_MODE=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m CONFIG_NVMEM_ROCKCHIP_OTP=m @@ -5655,7 +5655,7 @@ CONFIG_PHY_QCOM_QMP_PCIE=m CONFIG_PHY_QCOM_QMP_UFS=m CONFIG_PHY_QCOM_QMP_USB=m CONFIG_PHY_QCOM_QUSB2=m -# CONFIG_PHY_QCOM_SGMII_ETH is not set +CONFIG_PHY_QCOM_SGMII_ETH=m CONFIG_PHY_QCOM_SNPS_EUSB2=m CONFIG_PHY_QCOM_USB_HS_28NM=m CONFIG_PHY_QCOM_USB_HSIC=m @@ -5761,7 +5761,7 @@ CONFIG_PINCTRL_QDF2XXX=m # CONFIG_PINCTRL_QDU1000 is not set CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_ROCKCHIP=y -# CONFIG_PINCTRL_SA8775P is not set +CONFIG_PINCTRL_SA8775P=m CONFIG_PINCTRL_SC7180=y CONFIG_PINCTRL_SC7280_LPASS_LPI=m CONFIG_PINCTRL_SC7280=m @@ -6615,8 +6615,8 @@ CONFIG_RXKAD=y CONFIG_S2IO=m # CONFIG_S390_KPROBES_SANITY_TEST is not set # CONFIG_S390_MODULES_SANITY_TEST is not set -# CONFIG_SA_GCC_8775P is not set -# CONFIG_SA_GPUCC_8775P is not set +CONFIG_SA_GCC_8775P=m +CONFIG_SA_GPUCC_8775P=m # CONFIG_SAMPLE_FPROBE is not set # CONFIG_SAMPLES is not set CONFIG_SATA_ACARD_AHCI=m @@ -8011,7 +8011,7 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_OMAP24XX=m CONFIG_SPI_ORION=m @@ -8432,11 +8432,11 @@ CONFIG_TIPC=m CONFIG_TIPC_MEDIA_UDP=y CONFIG_TI_PRUSS_INTC=m CONFIG_TI_PRUSS=m -CONFIG_TI_SCI_CLK=m # CONFIG_TI_SCI_CLK_PROBE_FROM_FW is not set +CONFIG_TI_SCI_CLK=y CONFIG_TI_SCI_INTA_IRQCHIP=y CONFIG_TI_SCI_INTR_IRQCHIP=y -CONFIG_TI_SCI_PM_DOMAINS=m +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_TI_SCI_PROTOCOL=y # CONFIG_TI_ST is not set CONFIG_TI_SYSCON_CLK=m diff --git a/SOURCES/kernel-aarch64-64k-debug-rhel.config b/SOURCES/kernel-aarch64-64k-debug-rhel.config index ba9a7a8..9eaeacb 100644 --- a/SOURCES/kernel-aarch64-64k-debug-rhel.config +++ b/SOURCES/kernel-aarch64-64k-debug-rhel.config @@ -6551,7 +6551,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-aarch64-64k-rhel.config b/SOURCES/kernel-aarch64-64k-rhel.config index dea8884..d0a0ed9 100644 --- a/SOURCES/kernel-aarch64-64k-rhel.config +++ b/SOURCES/kernel-aarch64-64k-rhel.config @@ -6526,7 +6526,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-aarch64-debug-fedora.config b/SOURCES/kernel-aarch64-debug-fedora.config index efc4b07..728ebf9 100644 --- a/SOURCES/kernel-aarch64-debug-fedora.config +++ b/SOURCES/kernel-aarch64-debug-fedora.config @@ -3392,7 +3392,7 @@ CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_QCM2290=m # CONFIG_INTERCONNECT_QCOM_QCS404 is not set # CONFIG_INTERCONNECT_QCOM_QDU1000 is not set -# CONFIG_INTERCONNECT_QCOM_SA8775P is not set +CONFIG_INTERCONNECT_QCOM_SA8775P=m CONFIG_INTERCONNECT_QCOM_SC7180=y CONFIG_INTERCONNECT_QCOM_SC7280=m CONFIG_INTERCONNECT_QCOM_SC8180X=m @@ -5365,7 +5365,7 @@ CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_MESON_EFUSE=m CONFIG_NVMEM_MESON_MX_EFUSE=m CONFIG_NVMEM_QCOM_QFPROM=m -# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_REBOOT_MODE=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m CONFIG_NVMEM_ROCKCHIP_OTP=m @@ -5682,7 +5682,7 @@ CONFIG_PHY_QCOM_QMP_PCIE=m CONFIG_PHY_QCOM_QMP_UFS=m CONFIG_PHY_QCOM_QMP_USB=m CONFIG_PHY_QCOM_QUSB2=m -# CONFIG_PHY_QCOM_SGMII_ETH is not set +CONFIG_PHY_QCOM_SGMII_ETH=m CONFIG_PHY_QCOM_SNPS_EUSB2=m CONFIG_PHY_QCOM_USB_HS_28NM=m CONFIG_PHY_QCOM_USB_HSIC=m @@ -5788,7 +5788,7 @@ CONFIG_PINCTRL_QDF2XXX=m # CONFIG_PINCTRL_QDU1000 is not set CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_ROCKCHIP=y -# CONFIG_PINCTRL_SA8775P is not set +CONFIG_PINCTRL_SA8775P=m CONFIG_PINCTRL_SC7180=y CONFIG_PINCTRL_SC7280_LPASS_LPI=m CONFIG_PINCTRL_SC7280=m @@ -6642,8 +6642,8 @@ CONFIG_RXKAD=y CONFIG_S2IO=m # CONFIG_S390_KPROBES_SANITY_TEST is not set # CONFIG_S390_MODULES_SANITY_TEST is not set -# CONFIG_SA_GCC_8775P is not set -# CONFIG_SA_GPUCC_8775P is not set +CONFIG_SA_GCC_8775P=m +CONFIG_SA_GPUCC_8775P=m # CONFIG_SAMPLE_FPROBE is not set # CONFIG_SAMPLES is not set CONFIG_SATA_ACARD_AHCI=m @@ -8040,7 +8040,7 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_OMAP24XX=m CONFIG_SPI_ORION=m @@ -8461,11 +8461,11 @@ CONFIG_TIPC=m CONFIG_TIPC_MEDIA_UDP=y CONFIG_TI_PRUSS_INTC=m CONFIG_TI_PRUSS=m -CONFIG_TI_SCI_CLK=m # CONFIG_TI_SCI_CLK_PROBE_FROM_FW is not set +CONFIG_TI_SCI_CLK=y CONFIG_TI_SCI_INTA_IRQCHIP=y CONFIG_TI_SCI_INTR_IRQCHIP=y -CONFIG_TI_SCI_PM_DOMAINS=m +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_TI_SCI_PROTOCOL=y # CONFIG_TI_ST is not set CONFIG_TI_SYSCON_CLK=m diff --git a/SOURCES/kernel-aarch64-debug-rhel.config b/SOURCES/kernel-aarch64-debug-rhel.config index c9fdc48..6dff8d9 100644 --- a/SOURCES/kernel-aarch64-debug-rhel.config +++ b/SOURCES/kernel-aarch64-debug-rhel.config @@ -6547,7 +6547,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-aarch64-fedora.config b/SOURCES/kernel-aarch64-fedora.config index daf5323..7f4a877 100644 --- a/SOURCES/kernel-aarch64-fedora.config +++ b/SOURCES/kernel-aarch64-fedora.config @@ -3375,7 +3375,7 @@ CONFIG_INTERCONNECT_QCOM_OSM_L3=m CONFIG_INTERCONNECT_QCOM_QCM2290=m # CONFIG_INTERCONNECT_QCOM_QCS404 is not set # CONFIG_INTERCONNECT_QCOM_QDU1000 is not set -# CONFIG_INTERCONNECT_QCOM_SA8775P is not set +CONFIG_INTERCONNECT_QCOM_SA8775P=m CONFIG_INTERCONNECT_QCOM_SC7180=y CONFIG_INTERCONNECT_QCOM_SC7280=m CONFIG_INTERCONNECT_QCOM_SC8180X=m @@ -5339,7 +5339,7 @@ CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_MESON_EFUSE=m CONFIG_NVMEM_MESON_MX_EFUSE=m CONFIG_NVMEM_QCOM_QFPROM=m -# CONFIG_NVMEM_REBOOT_MODE is not set +CONFIG_NVMEM_REBOOT_MODE=m CONFIG_NVMEM_RMEM=m CONFIG_NVMEM_ROCKCHIP_EFUSE=m CONFIG_NVMEM_ROCKCHIP_OTP=m @@ -5655,7 +5655,7 @@ CONFIG_PHY_QCOM_QMP_PCIE=m CONFIG_PHY_QCOM_QMP_UFS=m CONFIG_PHY_QCOM_QMP_USB=m CONFIG_PHY_QCOM_QUSB2=m -# CONFIG_PHY_QCOM_SGMII_ETH is not set +CONFIG_PHY_QCOM_SGMII_ETH=m CONFIG_PHY_QCOM_SNPS_EUSB2=m CONFIG_PHY_QCOM_USB_HS_28NM=m CONFIG_PHY_QCOM_USB_HSIC=m @@ -5761,7 +5761,7 @@ CONFIG_PINCTRL_QDF2XXX=m # CONFIG_PINCTRL_QDU1000 is not set CONFIG_PINCTRL_RK805=m CONFIG_PINCTRL_ROCKCHIP=y -# CONFIG_PINCTRL_SA8775P is not set +CONFIG_PINCTRL_SA8775P=m CONFIG_PINCTRL_SC7180=y CONFIG_PINCTRL_SC7280_LPASS_LPI=m CONFIG_PINCTRL_SC7280=m @@ -6615,8 +6615,8 @@ CONFIG_RXKAD=y CONFIG_S2IO=m # CONFIG_S390_KPROBES_SANITY_TEST is not set # CONFIG_S390_MODULES_SANITY_TEST is not set -# CONFIG_SA_GCC_8775P is not set -# CONFIG_SA_GPUCC_8775P is not set +CONFIG_SA_GCC_8775P=m +CONFIG_SA_GPUCC_8775P=m # CONFIG_SAMPLE_FPROBE is not set # CONFIG_SAMPLES is not set CONFIG_SATA_ACARD_AHCI=m @@ -8011,7 +8011,7 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_OMAP24XX=m CONFIG_SPI_ORION=m @@ -8432,11 +8432,11 @@ CONFIG_TIPC=m CONFIG_TIPC_MEDIA_UDP=y CONFIG_TI_PRUSS_INTC=m CONFIG_TI_PRUSS=m -CONFIG_TI_SCI_CLK=m # CONFIG_TI_SCI_CLK_PROBE_FROM_FW is not set +CONFIG_TI_SCI_CLK=y CONFIG_TI_SCI_INTA_IRQCHIP=y CONFIG_TI_SCI_INTR_IRQCHIP=y -CONFIG_TI_SCI_PM_DOMAINS=m +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_TI_SCI_PROTOCOL=y # CONFIG_TI_ST is not set CONFIG_TI_SYSCON_CLK=m diff --git a/SOURCES/kernel-aarch64-rhel.config b/SOURCES/kernel-aarch64-rhel.config index efa40cb..a35ce99 100644 --- a/SOURCES/kernel-aarch64-rhel.config +++ b/SOURCES/kernel-aarch64-rhel.config @@ -6522,7 +6522,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-aarch64-rt-debug-rhel.config b/SOURCES/kernel-aarch64-rt-debug-rhel.config index 7c7abf4..b8acd89 100644 --- a/SOURCES/kernel-aarch64-rt-debug-rhel.config +++ b/SOURCES/kernel-aarch64-rt-debug-rhel.config @@ -6601,7 +6601,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-aarch64-rt-rhel.config b/SOURCES/kernel-aarch64-rt-rhel.config index 6baf7dc..166a798 100644 --- a/SOURCES/kernel-aarch64-rt-rhel.config +++ b/SOURCES/kernel-aarch64-rt-rhel.config @@ -6576,7 +6576,7 @@ CONFIG_SPI_MEM=y # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set +CONFIG_SPI_NXP_FLEXSPI=m # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PL022=m diff --git a/SOURCES/kernel-ppc64le-debug-fedora.config b/SOURCES/kernel-ppc64le-debug-fedora.config index 3427f20..65d5f1c 100644 --- a/SOURCES/kernel-ppc64le-debug-fedora.config +++ b/SOURCES/kernel-ppc64le-debug-fedora.config @@ -6746,7 +6746,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-ppc64le-debug-rhel.config b/SOURCES/kernel-ppc64le-debug-rhel.config index 4c46f59..786adae 100644 --- a/SOURCES/kernel-ppc64le-debug-rhel.config +++ b/SOURCES/kernel-ppc64le-debug-rhel.config @@ -6135,7 +6135,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-ppc64le-fedora.config b/SOURCES/kernel-ppc64le-fedora.config index eb203a7..e19935a 100644 --- a/SOURCES/kernel-ppc64le-fedora.config +++ b/SOURCES/kernel-ppc64le-fedora.config @@ -6715,7 +6715,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-ppc64le-rhel.config b/SOURCES/kernel-ppc64le-rhel.config index 6e3cf76..24c1248 100644 --- a/SOURCES/kernel-ppc64le-rhel.config +++ b/SOURCES/kernel-ppc64le-rhel.config @@ -6112,7 +6112,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-s390x-debug-fedora.config b/SOURCES/kernel-s390x-debug-fedora.config index f79d6f4..9ffc76b 100644 --- a/SOURCES/kernel-s390x-debug-fedora.config +++ b/SOURCES/kernel-s390x-debug-fedora.config @@ -6676,7 +6676,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-s390x-debug-rhel.config b/SOURCES/kernel-s390x-debug-rhel.config index f345b6b..7ca5c8e 100644 --- a/SOURCES/kernel-s390x-debug-rhel.config +++ b/SOURCES/kernel-s390x-debug-rhel.config @@ -6109,7 +6109,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-s390x-fedora.config b/SOURCES/kernel-s390x-fedora.config index c1070e2..b7c6726 100644 --- a/SOURCES/kernel-s390x-fedora.config +++ b/SOURCES/kernel-s390x-fedora.config @@ -6645,7 +6645,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-s390x-rhel.config b/SOURCES/kernel-s390x-rhel.config index 97c2265..580f09e 100644 --- a/SOURCES/kernel-s390x-rhel.config +++ b/SOURCES/kernel-s390x-rhel.config @@ -6086,7 +6086,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-s390x-zfcpdump-rhel.config b/SOURCES/kernel-s390x-zfcpdump-rhel.config index 118a749..ce89f0a 100644 --- a/SOURCES/kernel-s390x-zfcpdump-rhel.config +++ b/SOURCES/kernel-s390x-zfcpdump-rhel.config @@ -6103,7 +6103,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set diff --git a/SOURCES/kernel-x86_64-debug-fedora.config b/SOURCES/kernel-x86_64-debug-fedora.config index 6b22a45..68023cb 100644 --- a/SOURCES/kernel-x86_64-debug-fedora.config +++ b/SOURCES/kernel-x86_64-debug-fedora.config @@ -7154,7 +7154,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/kernel-x86_64-debug-rhel.config b/SOURCES/kernel-x86_64-debug-rhel.config index c6c5a60..645c2df 100644 --- a/SOURCES/kernel-x86_64-debug-rhel.config +++ b/SOURCES/kernel-x86_64-debug-rhel.config @@ -6358,7 +6358,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/kernel-x86_64-fedora.config b/SOURCES/kernel-x86_64-fedora.config index 5e674b4..f9dba7b 100644 --- a/SOURCES/kernel-x86_64-fedora.config +++ b/SOURCES/kernel-x86_64-fedora.config @@ -7124,7 +7124,6 @@ CONFIG_SPI_MICROCHIP_CORE=m CONFIG_SPI_MICROCHIP_CORE_QSPI=m CONFIG_SPI_MUX=m # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set CONFIG_SPI_PCI1XXXX=m CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/kernel-x86_64-rhel.config b/SOURCES/kernel-x86_64-rhel.config index 5f63098..aeb7bbc 100644 --- a/SOURCES/kernel-x86_64-rhel.config +++ b/SOURCES/kernel-x86_64-rhel.config @@ -6334,7 +6334,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/kernel-x86_64-rt-debug-rhel.config b/SOURCES/kernel-x86_64-rt-debug-rhel.config index 9e2c671..899e282 100644 --- a/SOURCES/kernel-x86_64-rt-debug-rhel.config +++ b/SOURCES/kernel-x86_64-rt-debug-rhel.config @@ -6412,7 +6412,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/kernel-x86_64-rt-rhel.config b/SOURCES/kernel-x86_64-rt-rhel.config index 69de7ee..8700078 100644 --- a/SOURCES/kernel-x86_64-rt-rhel.config +++ b/SOURCES/kernel-x86_64-rt-rhel.config @@ -6388,7 +6388,6 @@ CONFIG_SPI_FSL_LPSPI=m # CONFIG_SPI_MICROCHIP_CORE_QSPI is not set # CONFIG_SPI_MUX is not set # CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set # CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_PCI1XXXX is not set CONFIG_SPI_PXA2XX=m diff --git a/SOURCES/linux-surface.patch b/SOURCES/linux-surface.patch index 6d81170..b209613 100644 --- a/SOURCES/linux-surface.patch +++ b/SOURCES/linux-surface.patch @@ -1,294 +1,463 @@ -From 9916eca4bc0ff2ae5dc36de98b2377e5d839bc41 Mon Sep 17 00:00:00 2001 -From: GloriousEggroll -Date: Wed, 30 Aug 2023 20:24:03 -0600 -Subject: [PATCH 05/18] linux-surface +From d83d6478931989d4a211372e92c44b4020be48de Mon Sep 17 00:00:00 2001 +From: Tsuchiya Yuto +Date: Sun, 18 Oct 2020 16:42:44 +0900 +Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI + table +On some Surface 3, the DMI table gets corrupted for unknown reasons +and breaks existing DMI matching used for device-specific quirks. + +This commit adds the (broken) DMI data into dmi_system_id tables used +for quirks so that each driver can enable quirks even on the affected +systems. + +On affected systems, DMI data will look like this: + $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\ + chassis_vendor,product_name,sys_vendor} + /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc. + /sys/devices/virtual/dmi/id/board_name:OEMB + /sys/devices/virtual/dmi/id/board_vendor:OEMB + /sys/devices/virtual/dmi/id/chassis_vendor:OEMB + /sys/devices/virtual/dmi/id/product_name:OEMB + /sys/devices/virtual/dmi/id/sys_vendor:OEMB + +Expected: + $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\ + chassis_vendor,product_name,sys_vendor} + /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc. + /sys/devices/virtual/dmi/id/board_name:Surface 3 + /sys/devices/virtual/dmi/id/board_vendor:Microsoft Corporation + /sys/devices/virtual/dmi/id/chassis_vendor:Microsoft Corporation + /sys/devices/virtual/dmi/id/product_name:Surface 3 + /sys/devices/virtual/dmi/id/sys_vendor:Microsoft Corporation + +Signed-off-by: Tsuchiya Yuto +Patchset: surface3-oemb --- - MAINTAINERS | 7 + - arch/x86/kernel/acpi/boot.c | 24 + - drivers/acpi/acpi_tad.c | 35 +- - drivers/acpi/scan.c | 3 + - drivers/bluetooth/btusb.c | 15 + - drivers/hid/Kconfig | 4 + - drivers/hid/Makefile | 3 + - drivers/hid/hid-multitouch.c | 196 ++++++- - drivers/hid/ipts/Kconfig | 14 + - drivers/hid/ipts/Makefile | 16 + - drivers/hid/ipts/cmd.c | 61 ++ - drivers/hid/ipts/cmd.h | 60 ++ - drivers/hid/ipts/context.h | 52 ++ - drivers/hid/ipts/control.c | 486 ++++++++++++++++ - drivers/hid/ipts/control.h | 126 +++++ - drivers/hid/ipts/desc.h | 80 +++ - drivers/hid/ipts/eds1.c | 103 ++++ - drivers/hid/ipts/eds1.h | 35 ++ - drivers/hid/ipts/eds2.c | 144 +++++ - drivers/hid/ipts/eds2.h | 35 ++ - drivers/hid/ipts/hid.c | 225 ++++++++ - drivers/hid/ipts/hid.h | 24 + - drivers/hid/ipts/main.c | 126 +++++ - drivers/hid/ipts/mei.c | 188 ++++++ - drivers/hid/ipts/mei.h | 66 +++ - drivers/hid/ipts/receiver.c | 250 ++++++++ - drivers/hid/ipts/receiver.h | 16 + - drivers/hid/ipts/resources.c | 131 +++++ - drivers/hid/ipts/resources.h | 41 ++ - drivers/hid/ipts/spec-data.h | 100 ++++ - drivers/hid/ipts/spec-device.h | 290 ++++++++++ - drivers/hid/ipts/spec-hid.h | 34 ++ - drivers/hid/ipts/thread.c | 84 +++ - drivers/hid/ipts/thread.h | 59 ++ - drivers/hid/ithc/Kbuild | 6 + - drivers/hid/ithc/Kconfig | 12 + - drivers/hid/ithc/ithc-debug.c | 96 ++++ - drivers/hid/ithc/ithc-dma.c | 258 +++++++++ - drivers/hid/ithc/ithc-dma.h | 67 +++ - drivers/hid/ithc/ithc-main.c | 534 ++++++++++++++++++ - drivers/hid/ithc/ithc-regs.c | 64 +++ - drivers/hid/ithc/ithc-regs.h | 186 ++++++ - drivers/hid/ithc/ithc.h | 60 ++ - drivers/i2c/i2c-core-acpi.c | 35 ++ - drivers/input/misc/soc_button_array.c | 33 +- - drivers/iommu/intel/iommu.c | 54 ++ - drivers/iommu/intel/irq_remapping.c | 16 + - drivers/leds/Kconfig | 12 + - drivers/leds/Makefile | 1 + - drivers/leds/leds-tps68470.c | 185 ++++++ - drivers/media/i2c/Kconfig | 11 + - drivers/media/i2c/Makefile | 1 + - drivers/media/i2c/dw9719.c | 425 ++++++++++++++ - drivers/media/i2c/ov7251.c | 4 +- - drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 52 +- - drivers/media/v4l2-core/v4l2-async.c | 4 + - drivers/media/v4l2-core/v4l2-fwnode.c | 4 - - drivers/misc/mei/hw-me-regs.h | 1 + - drivers/misc/mei/pci-me.c | 1 + - drivers/net/wireless/ath/ath10k/core.c | 58 ++ - drivers/net/wireless/marvell/mwifiex/pcie.c | 19 + - .../wireless/marvell/mwifiex/pcie_quirks.c | 37 +- - .../wireless/marvell/mwifiex/pcie_quirks.h | 2 + - drivers/pci/pci-driver.c | 3 + - drivers/pci/quirks.c | 36 ++ - drivers/platform/surface/Kconfig | 7 + - drivers/platform/surface/Makefile | 1 + - drivers/platform/surface/surface3-wmi.c | 7 + - drivers/platform/surface/surface_gpe.c | 17 + - .../surface/surfacebook1_dgpu_switch.c | 162 ++++++ - drivers/platform/surface/surfacepro3_button.c | 30 +- - drivers/platform/x86/intel/int3472/discrete.c | 14 + - drivers/platform/x86/intel/int3472/tps68470.c | 12 +- - drivers/usb/core/quirks.c | 3 + - include/linux/mfd/tps68470.h | 5 + - include/linux/pci.h | 1 + - sound/soc/codecs/rt5645.c | 9 + - .../intel/common/soc-acpi-intel-cht-match.c | 8 + - 78 files changed, 5579 insertions(+), 107 deletions(-) - create mode 100644 drivers/hid/ipts/Kconfig - create mode 100644 drivers/hid/ipts/Makefile - create mode 100644 drivers/hid/ipts/cmd.c - create mode 100644 drivers/hid/ipts/cmd.h - create mode 100644 drivers/hid/ipts/context.h - create mode 100644 drivers/hid/ipts/control.c - create mode 100644 drivers/hid/ipts/control.h - create mode 100644 drivers/hid/ipts/desc.h - create mode 100644 drivers/hid/ipts/eds1.c - create mode 100644 drivers/hid/ipts/eds1.h - create mode 100644 drivers/hid/ipts/eds2.c - create mode 100644 drivers/hid/ipts/eds2.h - create mode 100644 drivers/hid/ipts/hid.c - create mode 100644 drivers/hid/ipts/hid.h - create mode 100644 drivers/hid/ipts/main.c - create mode 100644 drivers/hid/ipts/mei.c - create mode 100644 drivers/hid/ipts/mei.h - create mode 100644 drivers/hid/ipts/receiver.c - create mode 100644 drivers/hid/ipts/receiver.h - create mode 100644 drivers/hid/ipts/resources.c - create mode 100644 drivers/hid/ipts/resources.h - create mode 100644 drivers/hid/ipts/spec-data.h - create mode 100644 drivers/hid/ipts/spec-device.h - create mode 100644 drivers/hid/ipts/spec-hid.h - create mode 100644 drivers/hid/ipts/thread.c - create mode 100644 drivers/hid/ipts/thread.h - create mode 100644 drivers/hid/ithc/Kbuild - create mode 100644 drivers/hid/ithc/Kconfig - create mode 100644 drivers/hid/ithc/ithc-debug.c - create mode 100644 drivers/hid/ithc/ithc-dma.c - create mode 100644 drivers/hid/ithc/ithc-dma.h - create mode 100644 drivers/hid/ithc/ithc-main.c - create mode 100644 drivers/hid/ithc/ithc-regs.c - create mode 100644 drivers/hid/ithc/ithc-regs.h - create mode 100644 drivers/hid/ithc/ithc.h - create mode 100644 drivers/leds/leds-tps68470.c - create mode 100644 drivers/media/i2c/dw9719.c - create mode 100644 drivers/platform/surface/surfacebook1_dgpu_switch.c + drivers/platform/surface/surface3-wmi.c | 7 +++++++ + sound/soc/codecs/rt5645.c | 9 +++++++++ + sound/soc/intel/common/soc-acpi-intel-cht-match.c | 8 ++++++++ + 3 files changed, 24 insertions(+) -diff --git a/MAINTAINERS b/MAINTAINERS -index 4cc6bf79f..439cf523b 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6251,6 +6251,13 @@ T: git git://linuxtv.org/media_tree.git - F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml - F: drivers/media/i2c/dw9714.c - -+DONGWOON DW9719 LENS VOICE COIL DRIVER -+M: Daniel Scally -+L: linux-media@vger.kernel.org -+S: Maintained -+T: git git://linuxtv.org/media_tree.git -+F: drivers/media/i2c/dw9719.c -+ - DONGWOON DW9768 LENS VOICE COIL DRIVER - M: Dongchun Zhu - L: linux-media@vger.kernel.org -diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c -index 53369c577..a7d40015e 100644 ---- a/arch/x86/kernel/acpi/boot.c -+++ b/arch/x86/kernel/acpi/boot.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1256,6 +1257,24 @@ static void __init mp_config_acpi_legacy_irqs(void) - } - } - -+static const struct dmi_system_id surface_quirk[] __initconst = { +diff --git a/drivers/platform/surface/surface3-wmi.c b/drivers/platform/surface/surface3-wmi.c +index ca4602bcc7de..490b9731068a 100644 +--- a/drivers/platform/surface/surface3-wmi.c ++++ b/drivers/platform/surface/surface3-wmi.c +@@ -37,6 +37,13 @@ static const struct dmi_system_id surface3_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), + }, + }, + { -+ .ident = "Microsoft Surface Laptop 4 (AMD 15\")", + .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953") ++ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), ++ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), + }, + }, + #endif + { } + }; +diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c +index a506d940a2ea..2766484b8d2c 100644 +--- a/sound/soc/codecs/rt5645.c ++++ b/sound/soc/codecs/rt5645.c +@@ -3717,6 +3717,15 @@ static const struct dmi_system_id dmi_platform_data[] = { + }, + .driver_data = (void *)&intel_braswell_platform_data, + }, + { -+ .ident = "Microsoft Surface Laptop 4 (AMD 13\")", ++ .ident = "Microsoft Surface 3", + .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1958:1959") ++ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), ++ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), + }, ++ .driver_data = (void *)&intel_braswell_platform_data, + }, -+ {} -+}; -+ - /* - * Parse IOAPIC related entries in MADT - * returns 0 on success, < 0 on error -@@ -1311,6 +1330,11 @@ static int __init acpi_parse_madt_ioapic_entries(void) - acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0, - acpi_gbl_FADT.sci_interrupt); - -+ if (dmi_check_system(surface_quirk)) { -+ pr_warn("Surface hack: Override irq 7\n"); -+ mp_override_legacy_irq(7, 3, 3, 7); -+ } -+ - /* Fill in identity legacy mappings where no override */ - mp_config_acpi_legacy_irqs(); - -diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c -index e9b8e8305..944276934 100644 ---- a/drivers/acpi/acpi_tad.c -+++ b/drivers/acpi/acpi_tad.c -@@ -432,6 +432,14 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, - - static DEVICE_ATTR_RO(caps); - -+static struct attribute *acpi_tad_attrs[] = { -+ &dev_attr_caps.attr, -+ NULL, -+}; -+static const struct attribute_group acpi_tad_attr_group = { -+ .attrs = acpi_tad_attrs, -+}; -+ - static ssize_t ac_alarm_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { -@@ -480,15 +488,14 @@ static ssize_t ac_status_show(struct device *dev, struct device_attribute *attr, - - static DEVICE_ATTR_RW(ac_status); - --static struct attribute *acpi_tad_attrs[] = { -- &dev_attr_caps.attr, -+static struct attribute *acpi_tad_ac_attrs[] = { - &dev_attr_ac_alarm.attr, - &dev_attr_ac_policy.attr, - &dev_attr_ac_status.attr, - NULL, - }; --static const struct attribute_group acpi_tad_attr_group = { -- .attrs = acpi_tad_attrs, -+static const struct attribute_group acpi_tad_ac_attr_group = { -+ .attrs = acpi_tad_ac_attrs, + { + /* + * Match for the GPDwin which unfortunately uses somewhat +diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c +index cdcbf04b8832..958305779b12 100644 +--- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c ++++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c +@@ -27,6 +27,14 @@ static const struct dmi_system_id cht_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), + }, + }, ++ { ++ .callback = cht_surface_quirk_cb, ++ .matches = { ++ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), ++ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), ++ }, ++ }, + { } }; - static ssize_t dc_alarm_store(struct device *dev, struct device_attribute *attr, -@@ -563,13 +570,18 @@ static int acpi_tad_remove(struct platform_device *pdev) - - pm_runtime_get_sync(dev); - -+ if (dd->capabilities & ACPI_TAD_AC_WAKE) -+ sysfs_remove_group(&dev->kobj, &acpi_tad_ac_attr_group); -+ - if (dd->capabilities & ACPI_TAD_DC_WAKE) - sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group); - - sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group); - -- acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER); -- acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER); -+ if (dd->capabilities & ACPI_TAD_AC_WAKE) { -+ acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER); -+ acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER); -+ } - if (dd->capabilities & ACPI_TAD_DC_WAKE) { - acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER); - acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER); -@@ -604,11 +616,6 @@ static int acpi_tad_probe(struct platform_device *pdev) - return -ENODEV; - } - -- if (!acpi_has_method(handle, "_PRW")) { -- dev_info(dev, "Missing _PRW\n"); -- return -ENODEV; -- } -- - dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL); - if (!dd) - return -ENOMEM; -@@ -637,6 +644,12 @@ static int acpi_tad_probe(struct platform_device *pdev) - if (ret) - goto fail; +-- +2.42.0 + +From 8f3df38a8fb044dc63d15d1aa7eeec13a0ec4cfd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= +Date: Tue, 3 Nov 2020 13:28:04 +0100 +Subject: [PATCH] mwifiex: Add quirk resetting the PCI bridge on MS Surface + devices + +The most recent firmware of the 88W8897 card reports a hardcoded LTR +value to the system during initialization, probably as an (unsuccessful) +attempt of the developers to fix firmware crashes. This LTR value +prevents most of the Microsoft Surface devices from entering deep +powersaving states (either platform C-State 10 or S0ix state), because +the exit latency of that state would be higher than what the card can +tolerate. + +Turns out the card works just the same (including the firmware crashes) +no matter if that hardcoded LTR value is reported or not, so it's kind +of useless and only prevents us from saving power. + +To get rid of those hardcoded LTR reports, it's possible to reset the +PCI bridge device after initializing the cards firmware. I'm not exactly +sure why that works, maybe the power management subsystem of the PCH +resets its stored LTR values when doing a function level reset of the +bridge device. Doing the reset once after starting the wifi firmware +works very well, probably because the firmware only reports that LTR +value a single time during firmware startup. + +Patchset: mwifiex +--- + drivers/net/wireless/marvell/mwifiex/pcie.c | 12 +++++++++ + .../wireless/marvell/mwifiex/pcie_quirks.c | 26 +++++++++++++------ + .../wireless/marvell/mwifiex/pcie_quirks.h | 1 + + 3 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c +index 6697132ecc97..f06b4ebc5bd8 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c +@@ -1771,9 +1771,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) + static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) + { + struct pcie_service_card *card = adapter->card; ++ struct pci_dev *pdev = card->dev; ++ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask; -+ if (caps & ACPI_TAD_AC_WAKE) { -+ ret = sysfs_create_group(&dev->kobj, &acpi_tad_ac_attr_group); -+ if (ret) -+ goto fail; -+ } ++ /* Trigger a function level reset of the PCI bridge device, this makes ++ * the firmware of PCIe 88W8897 cards stop reporting a fixed LTR value ++ * that prevents the system from entering package C10 and S0ix powersaving ++ * states. ++ * We need to do it here because it must happen after firmware ++ * initialization and this function is called after that is done. ++ */ ++ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE) ++ pci_reset_function(parent_pdev); + - if (caps & ACPI_TAD_DC_WAKE) { - ret = sysfs_create_group(&dev->kobj, &acpi_tad_dc_attr_group); - if (ret) -diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 7e9de6e3e..50ceddfe7 100644 ---- a/drivers/acpi/scan.c -+++ b/drivers/acpi/scan.c -@@ -2114,6 +2114,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used, - - static void acpi_default_enumeration(struct acpi_device *device) - { -+ if (!acpi_dev_ready_for_enumeration(device)) -+ return; + /* Write the RX ring read pointer in to reg->rx_rdptr */ + if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr | + tx_wrap)) { +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +index dd6d21f1dbfd..f46b06f8d643 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +@@ -13,7 +13,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Pro 5", +@@ -22,7 +23,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Pro 5 (LTE)", +@@ -31,7 +33,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Pro 6", +@@ -39,7 +42,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Book 1", +@@ -47,7 +51,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Book 2", +@@ -55,7 +60,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Laptop 1", +@@ -63,7 +69,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + { + .ident = "Surface Laptop 2", +@@ -71,7 +78,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"), + }, +- .driver_data = (void *)QUIRK_FW_RST_D3COLD, ++ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | ++ QUIRK_DO_FLR_ON_BRIDGE), + }, + {} + }; +@@ -89,6 +97,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) + dev_info(&pdev->dev, "no quirks enabled\n"); + if (card->quirks & QUIRK_FW_RST_D3COLD) + dev_info(&pdev->dev, "quirk reset_d3cold enabled\n"); ++ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE) ++ dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n"); + } + + static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +index d6ff964aec5b..5d30ae39d65e 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h ++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +@@ -4,6 +4,7 @@ + #include "pcie.h" + + #define QUIRK_FW_RST_D3COLD BIT(0) ++#define QUIRK_DO_FLR_ON_BRIDGE BIT(1) + + void mwifiex_initialize_quirks(struct pcie_service_card *card); + int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); +-- +2.42.0 + +From 15d63e166f619c8a5baf139e376fe2285f4c2ff6 Mon Sep 17 00:00:00 2001 +From: Tsuchiya Yuto +Date: Sun, 4 Oct 2020 00:11:49 +0900 +Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+ + +Currently, mwifiex fw will crash after suspend on recent kernel series. +On Windows, it seems that the root port of wifi will never enter D3 state +(stay on D0 state). And on Linux, disabling the D3 state for the +bridge fixes fw crashing after suspend. + +This commit disables the D3 state of root port on driver initialization +and fixes fw crashing after suspend. + +Signed-off-by: Tsuchiya Yuto +Patchset: mwifiex +--- + drivers/net/wireless/marvell/mwifiex/pcie.c | 7 +++++ + .../wireless/marvell/mwifiex/pcie_quirks.c | 27 +++++++++++++------ + .../wireless/marvell/mwifiex/pcie_quirks.h | 1 + + 3 files changed, 27 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c +index f06b4ebc5bd8..07f13b52ddb9 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie.c +@@ -370,6 +370,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { + struct pcie_service_card *card; ++ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); + int ret; + + pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", +@@ -411,6 +412,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, + return -1; + } + ++ /* disable bridge_d3 for Surface gen4+ devices to fix fw crashing ++ * after suspend ++ */ ++ if (card->quirks & QUIRK_NO_BRIDGE_D3) ++ parent_pdev->bridge_d3 = false; + - /* - * Do not enumerate devices with enumeration_by_parent flag set as - * they will be enumerated by their respective parents. + return 0; + } + +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +index f46b06f8d643..99b024ecbade 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c ++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +@@ -14,7 +14,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Pro 5", +@@ -24,7 +25,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Pro 5 (LTE)", +@@ -34,7 +36,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Pro 6", +@@ -43,7 +46,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Book 1", +@@ -52,7 +56,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Book 2", +@@ -61,7 +66,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Laptop 1", +@@ -70,7 +76,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + { + .ident = "Surface Laptop 2", +@@ -79,7 +86,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"), + }, + .driver_data = (void *)(QUIRK_FW_RST_D3COLD | +- QUIRK_DO_FLR_ON_BRIDGE), ++ QUIRK_DO_FLR_ON_BRIDGE | ++ QUIRK_NO_BRIDGE_D3), + }, + {} + }; +@@ -99,6 +107,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) + dev_info(&pdev->dev, "quirk reset_d3cold enabled\n"); + if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE) + dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n"); ++ if (card->quirks & QUIRK_NO_BRIDGE_D3) ++ dev_info(&pdev->dev, ++ "quirk no_brigde_d3 enabled\n"); + } + + static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) +diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +index 5d30ae39d65e..c14eb56eb911 100644 +--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h ++++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +@@ -5,6 +5,7 @@ + + #define QUIRK_FW_RST_D3COLD BIT(0) + #define QUIRK_DO_FLR_ON_BRIDGE BIT(1) ++#define QUIRK_NO_BRIDGE_D3 BIT(2) + + void mwifiex_initialize_quirks(struct pcie_service_card *card); + int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); +-- +2.42.0 + +From d91266ba1b8afcdcc2a628e9f1bb400c86286bd8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= +Date: Thu, 25 Mar 2021 11:33:02 +0100 +Subject: [PATCH] Bluetooth: btusb: Lower passive lescan interval on Marvell + 88W8897 + +The Marvell 88W8897 combined wifi and bluetooth card (pcie+usb version) +is used in a lot of Microsoft Surface devices, and all those devices +suffer from very low 2.4GHz wifi connection speeds while bluetooth is +enabled. The reason for that is that the default passive scanning +interval for Bluetooth Low Energy devices is quite high in Linux +(interval of 60 msec and scan window of 30 msec, see hci_core.c), and +the Marvell chip is known for its bad bt+wifi coexisting performance. + +So decrease that passive scan interval and make the scan window shorter +on this particular device to allow for spending more time transmitting +wifi signals: The new scan interval is 250 msec (0x190 * 0.625 msec) and +the new scan window is 6.25 msec (0xa * 0,625 msec). + +This change has a very large impact on the 2.4GHz wifi speeds and gets +it up to performance comparable with the Windows driver, which seems to +apply a similar quirk. + +The interval and window length were tested and found to work very well +with a lot of Bluetooth Low Energy devices, including the Surface Pen, a +Bluetooth Speaker and two modern Bluetooth headphones. All devices were +discovered immediately after turning them on. Even lower values were +also tested, but they introduced longer delays until devices get +discovered. + +Patchset: mwifiex +--- + drivers/bluetooth/btusb.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index 764d176e9..cd6ee1f0f 100644 +index dfdfb72d350f..44ef02efba46 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -65,6 +65,7 @@ static struct usb_driver btusb_driver; @@ -307,7 +476,7 @@ index 764d176e9..cd6ee1f0f 100644 /* Intel Bluetooth devices */ { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED }, -@@ -4302,6 +4304,19 @@ static int btusb_probe(struct usb_interface *intf, +@@ -4317,6 +4319,19 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_MARVELL) hdev->set_bdaddr = btusb_set_bdaddr_marvell; @@ -327,400 +496,358 @@ index 764d176e9..cd6ee1f0f 100644 if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) && (id->driver_info & BTUSB_MEDIATEK)) { hdev->setup = btusb_mtk_setup; -diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig -index e11c1c803..0b58bd30a 100644 ---- a/drivers/hid/Kconfig -+++ b/drivers/hid/Kconfig -@@ -1334,4 +1334,8 @@ source "drivers/hid/amd-sfh-hid/Kconfig" - - source "drivers/hid/surface-hid/Kconfig" +-- +2.42.0 + +From a77ffb3a1080facd893088070bf6e5474fd9ee58 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sat, 27 Feb 2021 00:45:52 +0100 +Subject: [PATCH] ath10k: Add module parameters to override board files + +Some Surface devices, specifically the Surface Go and AMD version of the +Surface Laptop 3 (wich both come with QCA6174 WiFi chips), work better +with a different board file, as it seems that the firmeware included +upstream is buggy. + +As it is generally not a good idea to randomly overwrite files, let +alone doing so via packages, we add module parameters to override those +file names in the driver. This allows us to package/deploy the override +via a modprobe.d config. + +Signed-off-by: Maximilian Luz +Patchset: ath10k +--- + drivers/net/wireless/ath/ath10k/core.c | 58 ++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 6cdb225b7eac..19c036751fb1 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -38,6 +38,9 @@ static bool fw_diag_log; + /* frame mode values are mapped as per enum ath10k_hw_txrx_mode */ + unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI; -+source "drivers/hid/ipts/Kconfig" ++static char *override_board = ""; ++static char *override_board2 = ""; + -+source "drivers/hid/ithc/Kconfig" + unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) | + BIT(ATH10K_FW_CRASH_DUMP_CE_DATA); + +@@ -50,6 +53,9 @@ module_param(fw_diag_log, bool, 0644); + module_param_named(frame_mode, ath10k_frame_mode, uint, 0644); + module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444); + ++module_param(override_board, charp, 0644); ++module_param(override_board2, charp, 0644); + - endif # HID_SUPPORT -diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile -index 7a9e16015..656a0783c 100644 ---- a/drivers/hid/Makefile -+++ b/drivers/hid/Makefile -@@ -168,3 +168,6 @@ obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/ - obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + MODULE_PARM_DESC(debug_mask, "Debugging mask"); + MODULE_PARM_DESC(uart_print, "Uart target debugging"); + MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); +@@ -59,6 +65,9 @@ MODULE_PARM_DESC(frame_mode, + MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); + MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); - obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ ++MODULE_PARM_DESC(override_board, "Override for board.bin file"); ++MODULE_PARM_DESC(override_board2, "Override for board-2.bin file"); + -+obj-$(CONFIG_HID_IPTS) += ipts/ -+obj-$(CONFIG_HID_ITHC) += ithc/ -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index e31be0cb8..508a250ff 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -34,7 +34,10 @@ - #include - #include - #include -+#include - #include -+#include -+#include - #include - #include - #include -@@ -47,6 +50,7 @@ MODULE_DESCRIPTION("HID multitouch panels"); - MODULE_LICENSE("GPL"); + static const struct ath10k_hw_params ath10k_hw_params_list[] = { + { + .id = QCA988X_HW_2_0_VERSION, +@@ -911,6 +920,42 @@ static int ath10k_init_configure_target(struct ath10k *ar) + return 0; + } - #include "hid-ids.h" -+#include "usbhid/usbhid.h" ++static const char *ath10k_override_board_fw_file(struct ath10k *ar, ++ const char *file) ++{ ++ if (strcmp(file, "board.bin") == 0) { ++ if (strcmp(override_board, "") == 0) ++ return file; ++ ++ if (strcmp(override_board, "none") == 0) { ++ dev_info(ar->dev, "firmware override: pretending 'board.bin' does not exist\n"); ++ return NULL; ++ } ++ ++ dev_info(ar->dev, "firmware override: replacing 'board.bin' with '%s'\n", ++ override_board); ++ ++ return override_board; ++ } ++ ++ if (strcmp(file, "board-2.bin") == 0) { ++ if (strcmp(override_board2, "") == 0) ++ return file; ++ ++ if (strcmp(override_board2, "none") == 0) { ++ dev_info(ar->dev, "firmware override: pretending 'board-2.bin' does not exist\n"); ++ return NULL; ++ } ++ ++ dev_info(ar->dev, "firmware override: replacing 'board-2.bin' with '%s'\n", ++ override_board2); ++ ++ return override_board2; ++ } ++ ++ return file; ++} ++ + static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, + const char *dir, + const char *file) +@@ -925,6 +970,19 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, + if (dir == NULL) + dir = "."; - /* quirks to control the device */ - #define MT_QUIRK_NOT_SEEN_MEANS_UP BIT(0) -@@ -72,12 +76,18 @@ MODULE_LICENSE("GPL"); - #define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) - #define MT_QUIRK_DISABLE_WAKEUP BIT(21) - #define MT_QUIRK_ORIENTATION_INVERT BIT(22) -+#define MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT BIT(23) -+#define MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH BIT(24) ++ /* HACK: Override board.bin and board-2.bin files if specified. ++ * ++ * Some Surface devices perform better with a different board ++ * configuration. To this end, one would need to replace the board.bin ++ * file with the modified config and remove the board-2.bin file. ++ * Unfortunately, that's not a solution that we can easily package. So ++ * we add module options to perform these overrides here. ++ */ ++ ++ file = ath10k_override_board_fw_file(ar, file); ++ if (!file) ++ return ERR_PTR(-ENOENT); ++ + snprintf(filename, sizeof(filename), "%s/%s", dir, file); + ret = firmware_request_nowarn(&fw, filename, ar->dev); + ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n", +-- +2.42.0 + +From 45e0d4511653ae109942a4250ef05c2f3661ce18 Mon Sep 17 00:00:00 2001 +From: Dorian Stoll +Date: Thu, 30 Jul 2020 13:21:53 +0200 +Subject: [PATCH] misc: mei: Add missing IPTS device IDs + +Patchset: ipts +--- + drivers/misc/mei/hw-me-regs.h | 1 + + drivers/misc/mei/pci-me.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h +index bdc65d50b945..08723c01d727 100644 +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -92,6 +92,7 @@ + #define MEI_DEV_ID_CDF 0x18D3 /* Cedar Fork */ - #define MT_INPUTMODE_TOUCHSCREEN 0x02 - #define MT_INPUTMODE_TOUCHPAD 0x03 + #define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */ ++#define MEI_DEV_ID_ICP_LP_3 0x34E4 /* Ice Lake Point LP 3 (iTouch) */ + #define MEI_DEV_ID_ICP_N 0x38E0 /* Ice Lake Point N */ - #define MT_BUTTONTYPE_CLICKPAD 0 + #define MEI_DEV_ID_JSP_N 0x4DE0 /* Jasper Lake Point N */ +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 676d566f38dd..6b37dd1f8b2a 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -97,6 +97,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)}, -+#define MS_TYPE_COVER_FEATURE_REPORT_USAGE 0xff050086 -+#define MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE 0xff050072 -+#define MS_TYPE_COVER_APPLICATION 0xff050050 -+ - enum latency_mode { - HID_LATENCY_NORMAL = 0, - HID_LATENCY_HIGH = 1, -@@ -169,6 +179,8 @@ struct mt_device { + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, ++ {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP_3, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)}, - struct list_head applications; - struct list_head reports; -+ -+ struct notifier_block pm_notifier; - }; + {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, +-- +2.42.0 + +From 3a7f8d3d21d3b841607e8af4437b16fd677f5679 Mon Sep 17 00:00:00 2001 +From: Liban Hannan +Date: Tue, 12 Apr 2022 23:31:12 +0100 +Subject: [PATCH] iommu: ipts: use IOMMU passthrough mode for IPTS + +Adds a quirk so that IOMMU uses passthrough mode for the IPTS device. +Otherwise, when IOMMU is enabled, IPTS produces DMAR errors like: + +DMAR: [DMA Read NO_PASID] Request device [00:16.4] fault addr +0x104ea3000 [fault reason 0x06] PTE Read access is not set + +This is very similar to the bug described at: +https://bugs.launchpad.net/bugs/1958004 + +Fixed with the following patch which this patch basically copies: +https://launchpadlibrarian.net/586396847/43255ca.diff +Patchset: ipts +--- + drivers/iommu/intel/iommu.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index 5c8c5cdc36cf..fc4799415c3c 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -37,6 +37,8 @@ + #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) + #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB) + #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) ++#define IS_IPTS(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ ++ ((pdev)->device == 0x9d3e)) + #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) - static void mt_post_parse_default_settings(struct mt_device *td, -@@ -213,6 +225,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); - #define MT_CLS_GOOGLE 0x0111 - #define MT_CLS_RAZER_BLADE_STEALTH 0x0112 - #define MT_CLS_SMART_TECH 0x0113 -+#define MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER 0x0114 + #define IOAPIC_RANGE_START (0xfee00000) +@@ -287,12 +289,14 @@ int intel_iommu_enabled = 0; + EXPORT_SYMBOL_GPL(intel_iommu_enabled); - #define MT_DEFAULT_MAXCONTACT 10 - #define MT_MAX_MAXCONTACT 250 -@@ -397,6 +410,17 @@ static const struct mt_class mt_classes[] = { - MT_QUIRK_CONTACT_CNT_ACCURATE | - MT_QUIRK_SEPARATE_APP_REPORT, - }, -+ { .name = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER, -+ .quirks = MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT | -+ MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH | -+ MT_QUIRK_ALWAYS_VALID | -+ MT_QUIRK_IGNORE_DUPLICATES | -+ MT_QUIRK_HOVERING | -+ MT_QUIRK_CONTACT_CNT_ACCURATE | -+ MT_QUIRK_STICKY_FINGERS | -+ MT_QUIRK_WIN8_PTP_BUTTONS, -+ .export_all_inputs = true -+ }, - { } - }; + static int dmar_map_gfx = 1; ++static int dmar_map_ipts = 1; + static int intel_iommu_superpage = 1; + static int iommu_identity_mapping; + static int iommu_skip_te_disable; -@@ -1370,6 +1394,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, - field->application != HID_CP_CONSUMER_CONTROL && - field->application != HID_GD_WIRELESS_RADIO_CTLS && - field->application != HID_GD_SYSTEM_MULTIAXIS && -+ !(field->application == MS_TYPE_COVER_APPLICATION && -+ application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && -+ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) && - !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && - application->quirks & MT_QUIRK_ASUS_CUSTOM_UP)) - return -1; -@@ -1397,6 +1424,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, - return 1; - } + #define IDENTMAP_GFX 2 + #define IDENTMAP_AZALIA 4 ++#define IDENTMAP_IPTS 16 -+ /* -+ * The Microsoft Surface Pro Typecover has a non-standard HID -+ * tablet mode switch on a vendor specific usage page with vendor -+ * specific usage. -+ */ -+ if (field->application == MS_TYPE_COVER_APPLICATION && -+ application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && -+ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { -+ usage->type = EV_SW; -+ usage->code = SW_TABLET_MODE; -+ *max = SW_MAX; -+ *bit = hi->input->swbit; -+ return 1; -+ } -+ - if (rdata->is_mt_collection) - return mt_touch_input_mapping(hdev, hi, field, usage, bit, max, - application); -@@ -1418,6 +1460,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, - { - struct mt_device *td = hid_get_drvdata(hdev); - struct mt_report_data *rdata; -+ struct input_dev *input; + const struct iommu_ops intel_iommu_ops; - rdata = mt_find_report_data(td, field->report); - if (rdata && rdata->is_mt_collection) { -@@ -1425,6 +1468,19 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, - return -1; - } +@@ -2548,6 +2552,9 @@ static int device_def_domain_type(struct device *dev) -+ /* -+ * We own an input device which acts as a tablet mode switch for -+ * the Surface Pro Typecover. -+ */ -+ if (field->application == MS_TYPE_COVER_APPLICATION && -+ rdata->application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && -+ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { -+ input = hi->input; -+ input_set_capability(input, EV_SW, SW_TABLET_MODE); -+ input_report_switch(input, SW_TABLET_MODE, 0); -+ return -1; -+ } + if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) + return IOMMU_DOMAIN_IDENTITY; + - /* let hid-core decide for the others */ - return 0; - } -@@ -1434,11 +1490,21 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, - { - struct mt_device *td = hid_get_drvdata(hid); - struct mt_report_data *rdata; -+ struct input_dev *input; ++ if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev)) ++ return IOMMU_DOMAIN_IDENTITY; + } - rdata = mt_find_report_data(td, field->report); - if (rdata && rdata->is_mt_collection) - return mt_touch_event(hid, field, usage, value); + return 0; +@@ -2855,6 +2862,9 @@ static int __init init_dmars(void) + if (!dmar_map_gfx) + iommu_identity_mapping |= IDENTMAP_GFX; -+ if (field->application == MS_TYPE_COVER_APPLICATION && -+ rdata->application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && -+ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { -+ input = field->hidinput->input; -+ input_report_switch(input, SW_TABLET_MODE, (value & 0xFF) != 0x22); -+ input_sync(input); -+ return 1; -+ } ++ if (!dmar_map_ipts) ++ iommu_identity_mapping |= IDENTMAP_IPTS; + - return 0; - } + check_tylersburg_isoch(); -@@ -1591,6 +1657,42 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app) - app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; + ret = si_domain_init(hw_pass_through); +@@ -4771,6 +4781,17 @@ static void quirk_iommu_igfx(struct pci_dev *dev) + dmar_map_gfx = 0; } -+static int get_type_cover_field(struct hid_report_enum *rep_enum, -+ struct hid_field **field, int usage) -+{ -+ struct hid_report *rep; -+ struct hid_field *cur_field; -+ int i, j; -+ -+ list_for_each_entry(rep, &rep_enum->report_list, list) { -+ for (i = 0; i < rep->maxfield; i++) { -+ cur_field = rep->field[i]; -+ if (cur_field->application != MS_TYPE_COVER_APPLICATION) -+ continue; -+ for (j = 0; j < cur_field->maxusage; j++) { -+ if (cur_field->usage[j].hid == usage) { -+ *field = cur_field; -+ return true; -+ } -+ } -+ } -+ } -+ return false; -+} -+ -+static void request_type_cover_tablet_mode_switch(struct hid_device *hdev) -+{ -+ struct hid_field *field; -+ -+ if (get_type_cover_field(&hdev->report_enum[HID_INPUT_REPORT], -+ &field, -+ MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE)) { -+ hid_hw_request(hdev, field->report, HID_REQ_GET_REPORT); -+ } else { -+ hid_err(hdev, "couldn't find tablet mode field\n"); -+ } -+} -+ - static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) - { - struct mt_device *td = hid_get_drvdata(hdev); -@@ -1640,6 +1742,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) - /* force BTN_STYLUS to allow tablet matching in udev */ - __set_bit(BTN_STYLUS, hi->input->keybit); - break; -+ case MS_TYPE_COVER_APPLICATION: -+ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) { -+ suffix = "Tablet Mode Switch"; -+ request_type_cover_tablet_mode_switch(hdev); -+ break; -+ } -+ fallthrough; - default: - suffix = "UNKNOWN"; - break; -@@ -1728,6 +1837,46 @@ static void mt_expired_timeout(struct timer_list *t) - clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); - } - -+static void update_keyboard_backlight(struct hid_device *hdev, bool enabled) -+{ -+ struct usb_device *udev = hid_to_usb_dev(hdev); -+ struct hid_field *field = NULL; -+ -+ /* Wake up the device in case it's already suspended */ -+ pm_runtime_get_sync(&udev->dev); -+ -+ if (!get_type_cover_field(&hdev->report_enum[HID_FEATURE_REPORT], -+ &field, -+ MS_TYPE_COVER_FEATURE_REPORT_USAGE)) { -+ hid_err(hdev, "couldn't find backlight field\n"); -+ goto out; -+ } -+ -+ field->value[field->index] = enabled ? 0x01ff00ff : 0x00ff00ff; -+ hid_hw_request(hdev, field->report, HID_REQ_SET_REPORT); -+ -+out: -+ pm_runtime_put_sync(&udev->dev); -+} -+ -+static int mt_pm_notifier(struct notifier_block *notifier, -+ unsigned long pm_event, -+ void *unused) ++static void quirk_iommu_ipts(struct pci_dev *dev) +{ -+ struct mt_device *td = -+ container_of(notifier, struct mt_device, pm_notifier); -+ struct hid_device *hdev = td->hdev; ++ if (!IS_IPTS(dev)) ++ return; + -+ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT) { -+ if (pm_event == PM_SUSPEND_PREPARE) -+ update_keyboard_backlight(hdev, 0); -+ else if (pm_event == PM_POST_SUSPEND) -+ update_keyboard_backlight(hdev, 1); -+ } ++ if (risky_device(dev)) ++ return; + -+ return NOTIFY_DONE; ++ pci_info(dev, "Passthrough IOMMU for IPTS\n"); ++ dmar_map_ipts = 0; +} -+ - static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) - { - int ret, i; -@@ -1751,6 +1900,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) - td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; - hid_set_drvdata(hdev, td); - -+ td->pm_notifier.notifier_call = mt_pm_notifier; -+ register_pm_notifier(&td->pm_notifier); -+ - INIT_LIST_HEAD(&td->applications); - INIT_LIST_HEAD(&td->reports); - -@@ -1789,15 +1941,19 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) - timer_setup(&td->release_timer, mt_expired_timeout, 0); - - ret = hid_parse(hdev); -- if (ret != 0) -+ if (ret != 0) { -+ unregister_pm_notifier(&td->pm_notifier); - return ret; -+ } - - if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID) - mt_fix_const_fields(hdev, HID_DG_CONTACTID); - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); -- if (ret) -+ if (ret) { -+ unregister_pm_notifier(&td->pm_notifier); - return ret; -+ } - - ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); - if (ret) -@@ -1826,13 +1982,24 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state) + /* G4x/GM45 integrated gfx dmar support is totally busted. */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx); +@@ -4806,6 +4827,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); - static int mt_reset_resume(struct hid_device *hdev) - { -+ struct mt_device *td = hid_get_drvdata(hdev); -+ - mt_release_contacts(hdev); - mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); -+ -+ /* Request an update on the typecover folding state on resume -+ * after reset. -+ */ -+ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) -+ request_type_cover_tablet_mode_switch(hdev); ++/* disable IPTS dmar support */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9D3E, quirk_iommu_ipts); + - return 0; - } - - static int mt_resume(struct hid_device *hdev) + static void quirk_iommu_rwbf(struct pci_dev *dev) { -+ struct mt_device *td = hid_get_drvdata(hdev); -+ - /* Some Elan legacy devices require SET_IDLE to be set on resume. - * It should be safe to send it to other devices too. - * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ -@@ -1841,6 +2008,10 @@ static int mt_resume(struct hid_device *hdev) - - mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); + if (risky_device(dev)) +-- +2.42.0 + +From c504c6923f2b5239436f990f443e0af9d7462c4a Mon Sep 17 00:00:00 2001 +From: Dorian Stoll +Date: Sun, 11 Dec 2022 12:00:59 +0100 +Subject: [PATCH] hid: Add support for Intel Precise Touch and Stylus + +Based on linux-surface/intel-precise-touch@8abe268 + +Signed-off-by: Dorian Stoll +Patchset: ipts +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 2 + + drivers/hid/ipts/Kconfig | 14 + + drivers/hid/ipts/Makefile | 16 ++ + drivers/hid/ipts/cmd.c | 61 +++++ + drivers/hid/ipts/cmd.h | 60 ++++ + drivers/hid/ipts/context.h | 52 ++++ + drivers/hid/ipts/control.c | 486 +++++++++++++++++++++++++++++++++ + drivers/hid/ipts/control.h | 126 +++++++++ + drivers/hid/ipts/desc.h | 80 ++++++ + drivers/hid/ipts/eds1.c | 103 +++++++ + drivers/hid/ipts/eds1.h | 35 +++ + drivers/hid/ipts/eds2.c | 144 ++++++++++ + drivers/hid/ipts/eds2.h | 35 +++ + drivers/hid/ipts/hid.c | 225 +++++++++++++++ + drivers/hid/ipts/hid.h | 24 ++ + drivers/hid/ipts/main.c | 126 +++++++++ + drivers/hid/ipts/mei.c | 188 +++++++++++++ + drivers/hid/ipts/mei.h | 66 +++++ + drivers/hid/ipts/receiver.c | 250 +++++++++++++++++ + drivers/hid/ipts/receiver.h | 16 ++ + drivers/hid/ipts/resources.c | 131 +++++++++ + drivers/hid/ipts/resources.h | 41 +++ + drivers/hid/ipts/spec-data.h | 100 +++++++ + drivers/hid/ipts/spec-device.h | 290 ++++++++++++++++++++ + drivers/hid/ipts/spec-hid.h | 34 +++ + drivers/hid/ipts/thread.c | 84 ++++++ + drivers/hid/ipts/thread.h | 59 ++++ + 28 files changed, 2850 insertions(+) + create mode 100644 drivers/hid/ipts/Kconfig + create mode 100644 drivers/hid/ipts/Makefile + create mode 100644 drivers/hid/ipts/cmd.c + create mode 100644 drivers/hid/ipts/cmd.h + create mode 100644 drivers/hid/ipts/context.h + create mode 100644 drivers/hid/ipts/control.c + create mode 100644 drivers/hid/ipts/control.h + create mode 100644 drivers/hid/ipts/desc.h + create mode 100644 drivers/hid/ipts/eds1.c + create mode 100644 drivers/hid/ipts/eds1.h + create mode 100644 drivers/hid/ipts/eds2.c + create mode 100644 drivers/hid/ipts/eds2.h + create mode 100644 drivers/hid/ipts/hid.c + create mode 100644 drivers/hid/ipts/hid.h + create mode 100644 drivers/hid/ipts/main.c + create mode 100644 drivers/hid/ipts/mei.c + create mode 100644 drivers/hid/ipts/mei.h + create mode 100644 drivers/hid/ipts/receiver.c + create mode 100644 drivers/hid/ipts/receiver.h + create mode 100644 drivers/hid/ipts/resources.c + create mode 100644 drivers/hid/ipts/resources.h + create mode 100644 drivers/hid/ipts/spec-data.h + create mode 100644 drivers/hid/ipts/spec-device.h + create mode 100644 drivers/hid/ipts/spec-hid.h + create mode 100644 drivers/hid/ipts/thread.c + create mode 100644 drivers/hid/ipts/thread.h + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index e11c1c803676..54f45bdf663e 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1334,4 +1334,6 @@ source "drivers/hid/amd-sfh-hid/Kconfig" -+ /* Request an update on the typecover folding state on resume. */ -+ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) -+ request_type_cover_tablet_mode_switch(hdev); -+ - return 0; - } - #endif -@@ -1848,7 +2019,23 @@ static int mt_resume(struct hid_device *hdev) - static void mt_remove(struct hid_device *hdev) - { - struct mt_device *td = hid_get_drvdata(hdev); -+ struct hid_field *field; -+ struct input_dev *input; + source "drivers/hid/surface-hid/Kconfig" -+ /* Reset tablet mode switch on disconnect. */ -+ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) { -+ if (get_type_cover_field(&hdev->report_enum[HID_INPUT_REPORT], -+ &field, -+ MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE)) { -+ input = field->hidinput->input; -+ input_report_switch(input, SW_TABLET_MODE, 0); -+ input_sync(input); -+ } else { -+ hid_err(hdev, "couldn't find tablet mode field\n"); -+ } -+ } ++source "drivers/hid/ipts/Kconfig" + -+ unregister_pm_notifier(&td->pm_notifier); - del_timer_sync(&td->release_timer); - - sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); -@@ -2226,6 +2413,11 @@ static const struct hid_device_id mt_devices[] = { - MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, - USB_DEVICE_ID_XIROKU_CSR2) }, + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index 7a9e160158f7..f58610f27216 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -168,3 +168,5 @@ obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/ + obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ -+ /* Microsoft Surface type cover */ -+ { .driver_data = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER, -+ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, -+ USB_VENDOR_ID_MICROSOFT, 0x09c0) }, + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + - /* Google MT devices */ - { .driver_data = MT_CLS_GOOGLE, - HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, ++obj-$(CONFIG_HID_IPTS) += ipts/ diff --git a/drivers/hid/ipts/Kconfig b/drivers/hid/ipts/Kconfig new file mode 100644 -index 000000000..297401bd3 +index 000000000000..297401bd388d --- /dev/null +++ b/drivers/hid/ipts/Kconfig @@ -0,0 +1,14 @@ @@ -740,7 +867,7 @@ index 000000000..297401bd3 + module will be called ipts. diff --git a/drivers/hid/ipts/Makefile b/drivers/hid/ipts/Makefile new file mode 100644 -index 000000000..883896f68 +index 000000000000..883896f68e6a --- /dev/null +++ b/drivers/hid/ipts/Makefile @@ -0,0 +1,16 @@ @@ -762,7 +889,7 @@ index 000000000..883896f68 +ipts-objs += thread.o diff --git a/drivers/hid/ipts/cmd.c b/drivers/hid/ipts/cmd.c new file mode 100644 -index 000000000..63a4934bb +index 000000000000..63a4934bbc5f --- /dev/null +++ b/drivers/hid/ipts/cmd.c @@ -0,0 +1,61 @@ @@ -829,7 +956,7 @@ index 000000000..63a4934bb +} diff --git a/drivers/hid/ipts/cmd.h b/drivers/hid/ipts/cmd.h new file mode 100644 -index 000000000..2b4079075 +index 000000000000..2b4079075b64 --- /dev/null +++ b/drivers/hid/ipts/cmd.h @@ -0,0 +1,60 @@ @@ -895,7 +1022,7 @@ index 000000000..2b4079075 +#endif /* IPTS_CMD_H */ diff --git a/drivers/hid/ipts/context.h b/drivers/hid/ipts/context.h new file mode 100644 -index 000000000..ba33259f1 +index 000000000000..ba33259f1f7c --- /dev/null +++ b/drivers/hid/ipts/context.h @@ -0,0 +1,52 @@ @@ -953,7 +1080,7 @@ index 000000000..ba33259f1 +#endif /* IPTS_CONTEXT_H */ diff --git a/drivers/hid/ipts/control.c b/drivers/hid/ipts/control.c new file mode 100644 -index 000000000..5360842d2 +index 000000000000..5360842d260b --- /dev/null +++ b/drivers/hid/ipts/control.c @@ -0,0 +1,486 @@ @@ -1445,7 +1572,7 @@ index 000000000..5360842d2 +} diff --git a/drivers/hid/ipts/control.h b/drivers/hid/ipts/control.h new file mode 100644 -index 000000000..26629c514 +index 000000000000..26629c5144ed --- /dev/null +++ b/drivers/hid/ipts/control.h @@ -0,0 +1,126 @@ @@ -1577,7 +1704,7 @@ index 000000000..26629c514 +#endif /* IPTS_CONTROL_H */ diff --git a/drivers/hid/ipts/desc.h b/drivers/hid/ipts/desc.h new file mode 100644 -index 000000000..307438c7c +index 000000000000..307438c7c80c --- /dev/null +++ b/drivers/hid/ipts/desc.h @@ -0,0 +1,80 @@ @@ -1663,7 +1790,7 @@ index 000000000..307438c7c +#endif /* IPTS_DESC_H */ diff --git a/drivers/hid/ipts/eds1.c b/drivers/hid/ipts/eds1.c new file mode 100644 -index 000000000..ecbb3a8bd +index 000000000000..ecbb3a8bdaf6 --- /dev/null +++ b/drivers/hid/ipts/eds1.c @@ -0,0 +1,103 @@ @@ -1772,7 +1899,7 @@ index 000000000..ecbb3a8bd +} diff --git a/drivers/hid/ipts/eds1.h b/drivers/hid/ipts/eds1.h new file mode 100644 -index 000000000..eeeb6575e +index 000000000000..eeeb6575e3e8 --- /dev/null +++ b/drivers/hid/ipts/eds1.h @@ -0,0 +1,35 @@ @@ -1813,7 +1940,7 @@ index 000000000..eeeb6575e + enum hid_report_type report_type, enum hid_class_request request_type); diff --git a/drivers/hid/ipts/eds2.c b/drivers/hid/ipts/eds2.c new file mode 100644 -index 000000000..198dc65d7 +index 000000000000..198dc65d7887 --- /dev/null +++ b/drivers/hid/ipts/eds2.c @@ -0,0 +1,144 @@ @@ -1963,7 +2090,7 @@ index 000000000..198dc65d7 +} diff --git a/drivers/hid/ipts/eds2.h b/drivers/hid/ipts/eds2.h new file mode 100644 -index 000000000..064e37169 +index 000000000000..064e3716907a --- /dev/null +++ b/drivers/hid/ipts/eds2.h @@ -0,0 +1,35 @@ @@ -2004,7 +2131,7 @@ index 000000000..064e37169 + enum hid_report_type report_type, enum hid_class_request request_type); diff --git a/drivers/hid/ipts/hid.c b/drivers/hid/ipts/hid.c new file mode 100644 -index 000000000..e34a1a4f9 +index 000000000000..e34a1a4f9fa7 --- /dev/null +++ b/drivers/hid/ipts/hid.c @@ -0,0 +1,225 @@ @@ -2235,7 +2362,7 @@ index 000000000..e34a1a4f9 +} diff --git a/drivers/hid/ipts/hid.h b/drivers/hid/ipts/hid.h new file mode 100644 -index 000000000..1ebe77447 +index 000000000000..1ebe77447903 --- /dev/null +++ b/drivers/hid/ipts/hid.h @@ -0,0 +1,24 @@ @@ -2265,7 +2392,7 @@ index 000000000..1ebe77447 +#endif /* IPTS_HID_H */ diff --git a/drivers/hid/ipts/main.c b/drivers/hid/ipts/main.c new file mode 100644 -index 000000000..fb5b5c13e +index 000000000000..fb5b5c13ee3e --- /dev/null +++ b/drivers/hid/ipts/main.c @@ -0,0 +1,126 @@ @@ -2397,7 +2524,7 @@ index 000000000..fb5b5c13e +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/ipts/mei.c b/drivers/hid/ipts/mei.c new file mode 100644 -index 000000000..1e0395cea +index 000000000000..1e0395ceae4a --- /dev/null +++ b/drivers/hid/ipts/mei.c @@ -0,0 +1,188 @@ @@ -2591,7 +2718,7 @@ index 000000000..1e0395cea +} diff --git a/drivers/hid/ipts/mei.h b/drivers/hid/ipts/mei.h new file mode 100644 -index 000000000..973bade6b +index 000000000000..973bade6b0fd --- /dev/null +++ b/drivers/hid/ipts/mei.h @@ -0,0 +1,66 @@ @@ -2663,7 +2790,7 @@ index 000000000..973bade6b +#endif /* IPTS_MEI_H */ diff --git a/drivers/hid/ipts/receiver.c b/drivers/hid/ipts/receiver.c new file mode 100644 -index 000000000..ef66c3c9d +index 000000000000..ef66c3c9db80 --- /dev/null +++ b/drivers/hid/ipts/receiver.c @@ -0,0 +1,250 @@ @@ -2919,7 +3046,7 @@ index 000000000..ef66c3c9d +} diff --git a/drivers/hid/ipts/receiver.h b/drivers/hid/ipts/receiver.h new file mode 100644 -index 000000000..3de7da62d +index 000000000000..3de7da62d40c --- /dev/null +++ b/drivers/hid/ipts/receiver.h @@ -0,0 +1,16 @@ @@ -2941,7 +3068,7 @@ index 000000000..3de7da62d +#endif /* IPTS_RECEIVER_H */ diff --git a/drivers/hid/ipts/resources.c b/drivers/hid/ipts/resources.c new file mode 100644 -index 000000000..cc14653b2 +index 000000000000..cc14653b2a9f --- /dev/null +++ b/drivers/hid/ipts/resources.c @@ -0,0 +1,131 @@ @@ -3078,7 +3205,7 @@ index 000000000..cc14653b2 +} diff --git a/drivers/hid/ipts/resources.h b/drivers/hid/ipts/resources.h new file mode 100644 -index 000000000..2068e1328 +index 000000000000..2068e13285f0 --- /dev/null +++ b/drivers/hid/ipts/resources.h @@ -0,0 +1,41 @@ @@ -3125,7 +3252,7 @@ index 000000000..2068e1328 +#endif /* IPTS_RESOURCES_H */ diff --git a/drivers/hid/ipts/spec-data.h b/drivers/hid/ipts/spec-data.h new file mode 100644 -index 000000000..e8dd98895 +index 000000000000..e8dd98895a7e --- /dev/null +++ b/drivers/hid/ipts/spec-data.h @@ -0,0 +1,100 @@ @@ -3231,7 +3358,7 @@ index 000000000..e8dd98895 +#endif /* IPTS_SPEC_DATA_H */ diff --git a/drivers/hid/ipts/spec-device.h b/drivers/hid/ipts/spec-device.h new file mode 100644 -index 000000000..41845f9d9 +index 000000000000..41845f9d9025 --- /dev/null +++ b/drivers/hid/ipts/spec-device.h @@ -0,0 +1,290 @@ @@ -3527,7 +3654,7 @@ index 000000000..41845f9d9 +#endif /* IPTS_SPEC_DEVICE_H */ diff --git a/drivers/hid/ipts/spec-hid.h b/drivers/hid/ipts/spec-hid.h new file mode 100644 -index 000000000..5a58d4a0a +index 000000000000..5a58d4a0a610 --- /dev/null +++ b/drivers/hid/ipts/spec-hid.h @@ -0,0 +1,34 @@ @@ -3567,7 +3694,7 @@ index 000000000..5a58d4a0a +#endif /* IPTS_SPEC_HID_H */ diff --git a/drivers/hid/ipts/thread.c b/drivers/hid/ipts/thread.c new file mode 100644 -index 000000000..355e92bea +index 000000000000..355e92bea26f --- /dev/null +++ b/drivers/hid/ipts/thread.c @@ -0,0 +1,84 @@ @@ -3657,7 +3784,7 @@ index 000000000..355e92bea +} diff --git a/drivers/hid/ipts/thread.h b/drivers/hid/ipts/thread.h new file mode 100644 -index 000000000..1f966b8b3 +index 000000000000..1f966b8b32c4 --- /dev/null +++ b/drivers/hid/ipts/thread.h @@ -0,0 +1,59 @@ @@ -3720,21 +3847,117 @@ index 000000000..1f966b8b3 +int ipts_thread_stop(struct ipts_thread *thread); + +#endif /* IPTS_THREAD_H */ -diff --git a/drivers/hid/ithc/Kbuild b/drivers/hid/ithc/Kbuild -new file mode 100644 -index 000000000..aea83f2ac ---- /dev/null -+++ b/drivers/hid/ithc/Kbuild -@@ -0,0 +1,6 @@ -+obj-$(CONFIG_HID_ITHC) := ithc.o -+ -+ithc-objs := ithc-main.o ithc-regs.o ithc-dma.o ithc-debug.o -+ -+ccflags-y := -std=gnu11 -Wno-declaration-after-statement -+ -diff --git a/drivers/hid/ithc/Kconfig b/drivers/hid/ithc/Kconfig +-- +2.42.0 + +From 15bcb09157266ad8e90e5ee5f954a9760ac40e4f Mon Sep 17 00:00:00 2001 +From: Dorian Stoll +Date: Sun, 11 Dec 2022 12:03:38 +0100 +Subject: [PATCH] iommu: intel: Disable source id verification for ITHC + +Signed-off-by: Dorian Stoll +Patchset: ithc +--- + drivers/iommu/intel/irq_remapping.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c +index 08f56326e2f8..75218b38995c 100644 +--- a/drivers/iommu/intel/irq_remapping.c ++++ b/drivers/iommu/intel/irq_remapping.c +@@ -386,6 +386,22 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) + data.busmatch_count = 0; + pci_for_each_dma_alias(dev, set_msi_sid_cb, &data); + ++ /* ++ * The Intel Touch Host Controller is at 00:10.6, but for some reason ++ * the MSI interrupts have request id 01:05.0. ++ * Disable id verification to work around this. ++ * FIXME Find proper fix or turn this into a quirk. ++ */ ++ if (dev->vendor == PCI_VENDOR_ID_INTEL && (dev->class >> 8) == PCI_CLASS_INPUT_PEN) { ++ switch(dev->device) { ++ case 0x98d0: case 0x98d1: // LKF ++ case 0xa0d0: case 0xa0d1: // TGL LP ++ case 0x43d0: case 0x43d1: // TGL H ++ set_irte_sid(irte, SVT_NO_VERIFY, SQ_ALL_16, 0); ++ return 0; ++ } ++ } ++ + /* + * DMA alias provides us with a PCI device and alias. The only case + * where the it will return an alias on a different bus than the +-- +2.42.0 + +From 4d815045b207589057c1dfc6eba542d232e9654b Mon Sep 17 00:00:00 2001 +From: Dorian Stoll +Date: Sun, 11 Dec 2022 12:10:54 +0100 +Subject: [PATCH] hid: Add support for Intel Touch Host Controller + +Based on quo/ithc-linux@55803a2 + +Signed-off-by: Dorian Stoll +Patchset: ithc +--- + drivers/hid/Kconfig | 2 + + drivers/hid/Makefile | 1 + + drivers/hid/ithc/Kbuild | 6 + + drivers/hid/ithc/Kconfig | 12 + + drivers/hid/ithc/ithc-debug.c | 96 ++++++ + drivers/hid/ithc/ithc-dma.c | 258 ++++++++++++++++ + drivers/hid/ithc/ithc-dma.h | 67 +++++ + drivers/hid/ithc/ithc-main.c | 534 ++++++++++++++++++++++++++++++++++ + drivers/hid/ithc/ithc-regs.c | 64 ++++ + drivers/hid/ithc/ithc-regs.h | 186 ++++++++++++ + drivers/hid/ithc/ithc.h | 60 ++++ + 11 files changed, 1286 insertions(+) + create mode 100644 drivers/hid/ithc/Kbuild + create mode 100644 drivers/hid/ithc/Kconfig + create mode 100644 drivers/hid/ithc/ithc-debug.c + create mode 100644 drivers/hid/ithc/ithc-dma.c + create mode 100644 drivers/hid/ithc/ithc-dma.h + create mode 100644 drivers/hid/ithc/ithc-main.c + create mode 100644 drivers/hid/ithc/ithc-regs.c + create mode 100644 drivers/hid/ithc/ithc-regs.h + create mode 100644 drivers/hid/ithc/ithc.h + +diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig +index 54f45bdf663e..0b58bd30a22b 100644 +--- a/drivers/hid/Kconfig ++++ b/drivers/hid/Kconfig +@@ -1336,4 +1336,6 @@ source "drivers/hid/surface-hid/Kconfig" + + source "drivers/hid/ipts/Kconfig" + ++source "drivers/hid/ithc/Kconfig" ++ + endif # HID_SUPPORT +diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile +index f58610f27216..656a0783c709 100644 +--- a/drivers/hid/Makefile ++++ b/drivers/hid/Makefile +@@ -170,3 +170,4 @@ obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/ + obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/ + + obj-$(CONFIG_HID_IPTS) += ipts/ ++obj-$(CONFIG_HID_ITHC) += ithc/ +diff --git a/drivers/hid/ithc/Kbuild b/drivers/hid/ithc/Kbuild +new file mode 100644 +index 000000000000..aea83f2ac07b +--- /dev/null ++++ b/drivers/hid/ithc/Kbuild +@@ -0,0 +1,6 @@ ++obj-$(CONFIG_HID_ITHC) := ithc.o ++ ++ithc-objs := ithc-main.o ithc-regs.o ithc-dma.o ithc-debug.o ++ ++ccflags-y := -std=gnu11 -Wno-declaration-after-statement ++ +diff --git a/drivers/hid/ithc/Kconfig b/drivers/hid/ithc/Kconfig new file mode 100644 -index 000000000..ede713023 +index 000000000000..ede713023609 --- /dev/null +++ b/drivers/hid/ithc/Kconfig @@ -0,0 +1,12 @@ @@ -3752,7 +3975,7 @@ index 000000000..ede713023 + module will be called ithc. diff --git a/drivers/hid/ithc/ithc-debug.c b/drivers/hid/ithc/ithc-debug.c new file mode 100644 -index 000000000..57bf125c4 +index 000000000000..57bf125c45bd --- /dev/null +++ b/drivers/hid/ithc/ithc-debug.c @@ -0,0 +1,96 @@ @@ -3854,7 +4077,7 @@ index 000000000..57bf125c4 + diff --git a/drivers/hid/ithc/ithc-dma.c b/drivers/hid/ithc/ithc-dma.c new file mode 100644 -index 000000000..7e89b3496 +index 000000000000..7e89b3496918 --- /dev/null +++ b/drivers/hid/ithc/ithc-dma.c @@ -0,0 +1,258 @@ @@ -4118,7 +4341,7 @@ index 000000000..7e89b3496 + diff --git a/drivers/hid/ithc/ithc-dma.h b/drivers/hid/ithc/ithc-dma.h new file mode 100644 -index 000000000..d9f2c19a1 +index 000000000000..d9f2c19a13f3 --- /dev/null +++ b/drivers/hid/ithc/ithc-dma.h @@ -0,0 +1,67 @@ @@ -4191,7 +4414,7 @@ index 000000000..d9f2c19a1 + diff --git a/drivers/hid/ithc/ithc-main.c b/drivers/hid/ithc/ithc-main.c new file mode 100644 -index 000000000..09512b9cb +index 000000000000..09512b9cb4d3 --- /dev/null +++ b/drivers/hid/ithc/ithc-main.c @@ -0,0 +1,534 @@ @@ -4731,7 +4954,7 @@ index 000000000..09512b9cb + diff --git a/drivers/hid/ithc/ithc-regs.c b/drivers/hid/ithc/ithc-regs.c new file mode 100644 -index 000000000..85d567b05 +index 000000000000..85d567b05761 --- /dev/null +++ b/drivers/hid/ithc/ithc-regs.c @@ -0,0 +1,64 @@ @@ -4801,7 +5024,7 @@ index 000000000..85d567b05 + diff --git a/drivers/hid/ithc/ithc-regs.h b/drivers/hid/ithc/ithc-regs.h new file mode 100644 -index 000000000..1a96092ed +index 000000000000..1a96092ed7ee --- /dev/null +++ b/drivers/hid/ithc/ithc-regs.h @@ -0,0 +1,186 @@ @@ -4993,7 +5216,7 @@ index 000000000..1a96092ed + diff --git a/drivers/hid/ithc/ithc.h b/drivers/hid/ithc/ithc.h new file mode 100644 -index 000000000..6a9b0d480 +index 000000000000..6a9b0d480bc1 --- /dev/null +++ b/drivers/hid/ithc/ithc.h @@ -0,0 +1,60 @@ @@ -5057,8 +5280,121 @@ index 000000000..6a9b0d480 +int ithc_debug_init(struct ithc *ithc); +void ithc_log_regs(struct ithc *ithc); + +-- +2.42.0 + +From 89b8b8c121fe201862929709d451fecb24947676 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Thu, 5 Oct 2023 10:56:42 +0300 +Subject: [PATCH] serial: core: Fix checks for tx runtime PM state + +Maximilian reported that surface_serial_hub serdev tx does not work during +system suspend. During system suspend, runtime PM gets disabled in +__device_suspend_late(), and tx is unable to wake-up the serial core port +device that we use to check if tx is safe to start. Johan summarized the +regression noting that serdev tx no longer always works as earlier when the +serdev device is runtime PM active. + +The serdev device and the serial core controller devices are siblings of +the serial port hardware device. The runtime PM usage count from serdev +device does not propagate to the serial core device siblings, it only +propagates to the parent. + +In addition to the tx issue for suspend, testing for the serial core port +device can cause an unnecessary delay in enabling tx while waiting for the +serial core port device to wake-up. The serial core port device wake-up is +only needed to flush pending tx when the serial port hardware device was +in runtime PM suspended state. + +To fix the regression, we need to check the runtime PM state of the parent +serial port hardware device for tx instead of the serial core port device. + +As the serial port device drivers may or may not implement runtime PM, we +need to also add a check for pm_runtime_enabled(). + +Reported-by: Maximilian Luz +Fixes: 84a9582fd203 ("serial: core: Start managing serial controllers to enable runtime PM") +Signed-off-by: Tony Lindgren +Reviewed-by: Andy Shevchenko +Patchset: surface-sam +--- + drivers/tty/serial/serial_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index 831d033611e6..e429ac42a12e 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -157,7 +157,7 @@ static void __uart_start(struct tty_struct *tty) + * enabled, serial_port_runtime_resume() calls start_tx() again + * after enabling the device. + */ +- if (pm_runtime_active(&port_dev->dev)) ++ if (!pm_runtime_enabled(port->dev) || pm_runtime_active(port->dev)) + port->ops->start_tx(port); + pm_runtime_mark_last_busy(&port_dev->dev); + pm_runtime_put_autosuspend(&port_dev->dev); +-- +2.42.0 + +From ef087e2d75b52e727db2e413fdbdc596e2babadb Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sat, 25 Jul 2020 17:19:53 +0200 +Subject: [PATCH] i2c: acpi: Implement RawBytes read access + +Microsoft Surface Pro 4 and Book 1 devices access the MSHW0030 I2C +device via a generic serial bus operation region and RawBytes read +access. On the Surface Book 1, this access is required to turn on (and +off) the discrete GPU. + +Multiple things are to note here: + +a) The RawBytes access is device/driver dependent. The ACPI + specification states: + + > Raw accesses assume that the writer has knowledge of the bus that + > the access is made over and the device that is being accessed. The + > protocol may only ensure that the buffer is transmitted to the + > appropriate driver, but the driver must be able to interpret the + > buffer to communicate to a register. + + Thus this implementation may likely not work on other devices + accessing I2C via the RawBytes accessor type. + +b) The MSHW0030 I2C device is an HID-over-I2C device which seems to + serve multiple functions: + + 1. It is the main access point for the legacy-type Surface Aggregator + Module (also referred to as SAM-over-HID, as opposed to the newer + SAM-over-SSH/UART). It has currently not been determined on how + support for the legacy SAM should be implemented. Likely via a + custom HID driver. + + 2. It seems to serve as the HID device for the Integrated Sensor Hub. + This might complicate matters with regards to implementing a + SAM-over-HID driver required by legacy SAM. + +In light of this, the simplest approach has been chosen for now. +However, it may make more sense regarding breakage and compatibility to +either provide functionality for replacing or enhancing the default +operation region handler via some additional API functions, or even to +completely blacklist MSHW0030 from the I2C core and provide a custom +driver for it. + +Replacing/enhancing the default operation region handler would, however, +either require some sort of secondary driver and access point for it, +from which the new API functions would be called and the new handler +(part) would be installed, or hard-coding them via some sort of +quirk-like interface into the I2C core. + +Signed-off-by: Maximilian Luz +Patchset: surface-sam-over-hid +--- + drivers/i2c/i2c-core-acpi.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c -index d6037a328..a290ebc77 100644 +index d6037a328669..a290ebc77aea 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -628,6 +628,28 @@ static int acpi_gsb_i2c_write_bytes(struct i2c_client *client, @@ -5110,429 +5446,1532 @@ index d6037a328..a290ebc77 100644 default: dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n", accessor_type, client->addr); -diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c -index e79f54979..2bddbe6e9 100644 ---- a/drivers/input/misc/soc_button_array.c -+++ b/drivers/input/misc/soc_button_array.c -@@ -537,8 +537,8 @@ static const struct soc_device_data soc_device_MSHW0028 = { - * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned - * devices use MSHW0040 for power and volume buttons, however the way they - * have to be addressed differs. Make sure that we only load this drivers -- * for the correct devices by checking the OEM Platform Revision provided by -- * the _DSM method. -+ * for the correct devices by checking if the OEM Platform Revision DSM call -+ * exists. - */ - #define MSHW0040_DSM_REVISION 0x01 - #define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision -@@ -549,31 +549,14 @@ static const guid_t MSHW0040_DSM_UUID = - static int soc_device_check_MSHW0040(struct device *dev) - { - acpi_handle handle = ACPI_HANDLE(dev); -- union acpi_object *result; -- u64 oem_platform_rev = 0; // valid revisions are nonzero -- -- // get OEM platform revision -- result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, -- MSHW0040_DSM_REVISION, -- MSHW0040_DSM_GET_OMPR, NULL, -- ACPI_TYPE_INTEGER); -- -- if (result) { -- oem_platform_rev = result->integer.value; -- ACPI_FREE(result); -- } -- -- /* -- * If the revision is zero here, the _DSM evaluation has failed. This -- * indicates that we have a Pro 4 or Book 1 and this driver should not -- * be used. -- */ -- if (oem_platform_rev == 0) -- return -ENODEV; -+ bool exists; - -- dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev); -+ // check if OEM platform revision DSM call exists -+ exists = acpi_check_dsm(handle, &MSHW0040_DSM_UUID, -+ MSHW0040_DSM_REVISION, -+ BIT(MSHW0040_DSM_GET_OMPR)); - -- return 0; -+ return exists ? 0 : -ENODEV; - } - - /* -diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c -index 5c8c5cdc3..e10b4f625 100644 ---- a/drivers/iommu/intel/iommu.c -+++ b/drivers/iommu/intel/iommu.c -@@ -37,6 +37,14 @@ - #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) - #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB) - #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) -+#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ -+ ((pdev)->device == 0x9a19 || \ -+ (pdev)->device == 0x9a39 || \ -+ (pdev)->device == 0x4e19 || \ -+ (pdev)->device == 0x465d || \ -+ (pdev)->device == 0x1919)) -+#define IS_IPTS(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ -+ ((pdev)->device == 0x9d3e)) - #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) - - #define IOAPIC_RANGE_START (0xfee00000) -@@ -287,12 +295,16 @@ int intel_iommu_enabled = 0; - EXPORT_SYMBOL_GPL(intel_iommu_enabled); - - static int dmar_map_gfx = 1; -+static int dmar_map_ipts = 1; -+static int dmar_map_ipu = 1; - static int intel_iommu_superpage = 1; - static int iommu_identity_mapping; - static int iommu_skip_te_disable; - - #define IDENTMAP_GFX 2 - #define IDENTMAP_AZALIA 4 -+#define IDENTMAP_IPU 8 -+#define IDENTMAP_IPTS 16 - - const struct iommu_ops intel_iommu_ops; - -@@ -2548,6 +2560,12 @@ static int device_def_domain_type(struct device *dev) +-- +2.42.0 + +From ec8fe494052629fc2a9f5234c674f42e42aee254 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sat, 13 Feb 2021 16:41:18 +0100 +Subject: [PATCH] platform/surface: Add driver for Surface Book 1 dGPU switch + +Add driver exposing the discrete GPU power-switch of the Microsoft +Surface Book 1 to user-space. + +On the Surface Book 1, the dGPU power is controlled via the Surface +System Aggregator Module (SAM). The specific SAM-over-HID command for +this is exposed via ACPI. This module provides a simple driver exposing +the ACPI call via a sysfs parameter to user-space, so that users can +easily power-on/-off the dGPU. + +Patchset: surface-sam-over-hid +--- + drivers/platform/surface/Kconfig | 7 + + drivers/platform/surface/Makefile | 1 + + .../surface/surfacebook1_dgpu_switch.c | 162 ++++++++++++++++++ + 3 files changed, 170 insertions(+) + create mode 100644 drivers/platform/surface/surfacebook1_dgpu_switch.c + +diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig +index b629e82af97c..68656e8f309e 100644 +--- a/drivers/platform/surface/Kconfig ++++ b/drivers/platform/surface/Kconfig +@@ -149,6 +149,13 @@ config SURFACE_AGGREGATOR_TABLET_SWITCH + Select M or Y here, if you want to provide tablet-mode switch input + events on the Surface Pro 8, Surface Pro X, and Surface Laptop Studio. - if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) - return IOMMU_DOMAIN_IDENTITY; -+ -+ if ((iommu_identity_mapping & IDENTMAP_IPU) && IS_INTEL_IPU(pdev)) -+ return IOMMU_DOMAIN_IDENTITY; ++config SURFACE_BOOK1_DGPU_SWITCH ++ tristate "Surface Book 1 dGPU Switch Driver" ++ depends on SYSFS ++ help ++ This driver provides a sysfs switch to set the power-state of the ++ discrete GPU found on the Microsoft Surface Book 1. + -+ if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev)) -+ return IOMMU_DOMAIN_IDENTITY; - } - - return 0; -@@ -2855,6 +2873,12 @@ static int __init init_dmars(void) - if (!dmar_map_gfx) - iommu_identity_mapping |= IDENTMAP_GFX; - -+ if (!dmar_map_ipu) -+ iommu_identity_mapping |= IDENTMAP_IPU; + config SURFACE_DTX + tristate "Surface DTX (Detachment System) Driver" + depends on SURFACE_AGGREGATOR +diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile +index 53344330939b..7efcd0cdb532 100644 +--- a/drivers/platform/surface/Makefile ++++ b/drivers/platform/surface/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o + obj-$(CONFIG_SURFACE_AGGREGATOR_HUB) += surface_aggregator_hub.o + obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o + obj-$(CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH) += surface_aggregator_tabletsw.o ++obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH) += surfacebook1_dgpu_switch.o + obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o + obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o + obj-$(CONFIG_SURFACE_HOTPLUG) += surface_hotplug.o +diff --git a/drivers/platform/surface/surfacebook1_dgpu_switch.c b/drivers/platform/surface/surfacebook1_dgpu_switch.c +new file mode 100644 +index 000000000000..8b816ed8f35c +--- /dev/null ++++ b/drivers/platform/surface/surfacebook1_dgpu_switch.c +@@ -0,0 +1,162 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later + -+ if (!dmar_map_ipts) -+ iommu_identity_mapping |= IDENTMAP_IPTS; ++#include ++#include ++#include ++#include + - check_tylersburg_isoch(); - - ret = si_domain_init(hw_pass_through); -@@ -4771,6 +4795,30 @@ static void quirk_iommu_igfx(struct pci_dev *dev) - dmar_map_gfx = 0; - } - -+static void quirk_iommu_ipu(struct pci_dev *dev) -+{ -+ if (!IS_INTEL_IPU(dev)) -+ return; + -+ if (risky_device(dev)) -+ return; ++#ifdef pr_fmt ++#undef pr_fmt ++#endif ++#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ + -+ pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n"); -+ dmar_map_ipu = 0; -+} + -+static void quirk_iommu_ipts(struct pci_dev *dev) ++static const guid_t dgpu_sw_guid = GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, ++ 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35); ++ ++#define DGPUSW_ACPI_PATH_DSM "\\_SB_.PCI0.LPCB.EC0_.VGBI" ++#define DGPUSW_ACPI_PATH_HGON "\\_SB_.PCI0.RP05.HGON" ++#define DGPUSW_ACPI_PATH_HGOF "\\_SB_.PCI0.RP05.HGOF" ++ ++ ++static int sb1_dgpu_sw_dsmcall(void) +{ -+ if (!IS_IPTS(dev)) -+ return; ++ union acpi_object *ret; ++ acpi_handle handle; ++ acpi_status status; + -+ if (risky_device(dev)) -+ return; ++ status = acpi_get_handle(NULL, DGPUSW_ACPI_PATH_DSM, &handle); ++ if (status) ++ return -EINVAL; + -+ pci_info(dev, "Passthrough IOMMU for IPTS\n"); -+ dmar_map_ipts = 0; -+} ++ ret = acpi_evaluate_dsm_typed(handle, &dgpu_sw_guid, 1, 1, NULL, ACPI_TYPE_BUFFER); ++ if (!ret) ++ return -EINVAL; + - /* G4x/GM45 integrated gfx dmar support is totally busted. */ - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx); -@@ -4806,6 +4854,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); - -+/* disable IPU dmar support */ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu); ++ ACPI_FREE(ret); ++ return 0; ++} + -+/* disable IPTS dmar support */ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9D3E, quirk_iommu_ipts); ++static int sb1_dgpu_sw_hgon(void) ++{ ++ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; ++ acpi_status status; + - static void quirk_iommu_rwbf(struct pci_dev *dev) - { - if (risky_device(dev)) -diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c -index 08f56326e..75218b389 100644 ---- a/drivers/iommu/intel/irq_remapping.c -+++ b/drivers/iommu/intel/irq_remapping.c -@@ -386,6 +386,22 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev) - data.busmatch_count = 0; - pci_for_each_dma_alias(dev, set_msi_sid_cb, &data); - -+ /* -+ * The Intel Touch Host Controller is at 00:10.6, but for some reason -+ * the MSI interrupts have request id 01:05.0. -+ * Disable id verification to work around this. -+ * FIXME Find proper fix or turn this into a quirk. -+ */ -+ if (dev->vendor == PCI_VENDOR_ID_INTEL && (dev->class >> 8) == PCI_CLASS_INPUT_PEN) { -+ switch(dev->device) { -+ case 0x98d0: case 0x98d1: // LKF -+ case 0xa0d0: case 0xa0d1: // TGL LP -+ case 0x43d0: case 0x43d1: // TGL H -+ set_irte_sid(irte, SVT_NO_VERIFY, SQ_ALL_16, 0); -+ return 0; -+ } ++ status = acpi_evaluate_object(NULL, DGPUSW_ACPI_PATH_HGON, NULL, &buf); ++ if (status) { ++ pr_err("failed to run HGON: %d\n", status); ++ return -EINVAL; + } + - /* - * DMA alias provides us with a PCI device and alias. The only case - * where the it will return an alias on a different bus than the -diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index 6046dfeca..385c06e4f 100644 ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -864,6 +864,18 @@ config LEDS_TPS6105X - It is a single boost converter primarily for white LEDs and - audio amplifiers. - -+config LEDS_TPS68470 -+ tristate "LED support for TI TPS68470" -+ depends on LEDS_CLASS -+ depends on INTEL_SKL_INT3472 -+ help -+ This driver supports TPS68470 PMIC with LED chip. -+ It provides two LED controllers, with the ability to drive 2 -+ indicator LEDs and 2 flash LEDs. ++ if (buf.pointer) ++ ACPI_FREE(buf.pointer); + -+ To compile this driver as a module, choose M and it will be -+ called leds-tps68470 ++ pr_info("turned-on dGPU via HGON\n"); ++ return 0; ++} + - config LEDS_IP30 - tristate "LED support for SGI Octane machines" - depends on LEDS_CLASS -diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile -index d71f12265..e2002b535 100644 ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -83,6 +83,7 @@ obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o - obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o - obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o - obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o -+obj-$(CONFIG_LEDS_TPS68470) += leds-tps68470.o - obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o - obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o - obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o -diff --git a/drivers/leds/leds-tps68470.c b/drivers/leds/leds-tps68470.c -new file mode 100644 -index 000000000..35aeb5db8 ---- /dev/null -+++ b/drivers/leds/leds-tps68470.c -@@ -0,0 +1,185 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * LED driver for TPS68470 PMIC -+ * -+ * Copyright (C) 2023 Red Hat -+ * -+ * Authors: -+ * Kate Hsuan -+ */ ++static int sb1_dgpu_sw_hgof(void) ++{ ++ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; ++ acpi_status status; + -+#include -+#include -+#include -+#include -+#include -+#include ++ status = acpi_evaluate_object(NULL, DGPUSW_ACPI_PATH_HGOF, NULL, &buf); ++ if (status) { ++ pr_err("failed to run HGOF: %d\n", status); ++ return -EINVAL; ++ } + ++ if (buf.pointer) ++ ACPI_FREE(buf.pointer); + -+#define lcdev_to_led(led_cdev) \ -+ container_of(led_cdev, struct tps68470_led, lcdev) ++ pr_info("turned-off dGPU via HGOF\n"); ++ return 0; ++} + -+#define led_to_tps68470(led, index) \ -+ container_of(led, struct tps68470_device, leds[index]) + -+enum tps68470_led_ids { -+ TPS68470_ILED_A, -+ TPS68470_ILED_B, -+ TPS68470_NUM_LEDS -+}; ++static ssize_t dgpu_dsmcall_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t len) ++{ ++ int status, value; + -+static const char *tps68470_led_names[] = { -+ [TPS68470_ILED_A] = "tps68470-iled_a", -+ [TPS68470_ILED_B] = "tps68470-iled_b", -+}; ++ status = kstrtoint(buf, 0, &value); ++ if (status < 0) ++ return status; + -+struct tps68470_led { -+ unsigned int led_id; -+ struct led_classdev lcdev; -+}; ++ if (value != 1) ++ return -EINVAL; + -+struct tps68470_device { -+ struct device *dev; -+ struct regmap *regmap; -+ struct tps68470_led leds[TPS68470_NUM_LEDS]; -+}; ++ status = sb1_dgpu_sw_dsmcall(); + -+enum ctrlb_current { -+ CTRLB_2MA = 0, -+ CTRLB_4MA = 1, -+ CTRLB_8MA = 2, -+ CTRLB_16MA = 3, -+}; ++ return status < 0 ? status : len; ++} + -+static int tps68470_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) ++static ssize_t dgpu_power_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t len) +{ -+ struct tps68470_led *led = lcdev_to_led(led_cdev); -+ struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id); -+ struct regmap *regmap = tps68470->regmap; ++ bool power; ++ int status; + -+ switch (led->led_id) { -+ case TPS68470_ILED_A: -+ return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENA, -+ brightness ? TPS68470_ILEDCTL_ENA : 0); -+ case TPS68470_ILED_B: -+ return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENB, -+ brightness ? TPS68470_ILEDCTL_ENB : 0); -+ } -+ return -EINVAL; ++ status = kstrtobool(buf, &power); ++ if (status < 0) ++ return status; ++ ++ if (power) ++ status = sb1_dgpu_sw_hgon(); ++ else ++ status = sb1_dgpu_sw_hgof(); ++ ++ return status < 0 ? status : len; +} + -+static enum led_brightness tps68470_brightness_get(struct led_classdev *led_cdev) -+{ -+ struct tps68470_led *led = lcdev_to_led(led_cdev); -+ struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id); -+ struct regmap *regmap = tps68470->regmap; -+ int ret = 0; -+ int value = 0; ++static DEVICE_ATTR_WO(dgpu_dsmcall); ++static DEVICE_ATTR_WO(dgpu_power); + -+ ret = regmap_read(regmap, TPS68470_REG_ILEDCTL, &value); -+ if (ret) -+ return dev_err_probe(led_cdev->dev, -EINVAL, "failed on reading register\n"); ++static struct attribute *sb1_dgpu_sw_attrs[] = { ++ &dev_attr_dgpu_dsmcall.attr, ++ &dev_attr_dgpu_power.attr, ++ NULL, ++}; + -+ switch (led->led_id) { -+ case TPS68470_ILED_A: -+ value = value & TPS68470_ILEDCTL_ENA; -+ break; -+ case TPS68470_ILED_B: -+ value = value & TPS68470_ILEDCTL_ENB; -+ break; -+ } ++static const struct attribute_group sb1_dgpu_sw_attr_group = { ++ .attrs = sb1_dgpu_sw_attrs, ++}; + -+ return value ? LED_ON : LED_OFF; -+} + ++static int sb1_dgpu_sw_probe(struct platform_device *pdev) ++{ ++ return sysfs_create_group(&pdev->dev.kobj, &sb1_dgpu_sw_attr_group); ++} + -+static int tps68470_ledb_current_init(struct platform_device *pdev, -+ struct tps68470_device *tps68470) ++static int sb1_dgpu_sw_remove(struct platform_device *pdev) +{ -+ int ret = 0; -+ unsigned int curr; ++ sysfs_remove_group(&pdev->dev.kobj, &sb1_dgpu_sw_attr_group); ++ return 0; ++} ++ ++/* ++ * The dGPU power seems to be actually handled by MSHW0040. However, that is ++ * also the power-/volume-button device with a mainline driver. So let's use ++ * MSHW0041 instead for now, which seems to be the LTCH (latch/DTX) device. ++ */ ++static const struct acpi_device_id sb1_dgpu_sw_match[] = { ++ { "MSHW0041", }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(acpi, sb1_dgpu_sw_match); ++ ++static struct platform_driver sb1_dgpu_sw = { ++ .probe = sb1_dgpu_sw_probe, ++ .remove = sb1_dgpu_sw_remove, ++ .driver = { ++ .name = "surfacebook1_dgpu_switch", ++ .acpi_match_table = sb1_dgpu_sw_match, ++ .probe_type = PROBE_PREFER_ASYNCHRONOUS, ++ }, ++}; ++module_platform_driver(sb1_dgpu_sw); ++ ++MODULE_AUTHOR("Maximilian Luz "); ++MODULE_DESCRIPTION("Discrete GPU Power-Switch for Surface Book 1"); ++MODULE_LICENSE("GPL"); +-- +2.42.0 + +From b595029ce12d05babb051893a3b5ad8a0555a553 Mon Sep 17 00:00:00 2001 +From: Sachi King +Date: Tue, 5 Oct 2021 00:05:09 +1100 +Subject: [PATCH] Input: soc_button_array - support AMD variant Surface devices + +The power button on the AMD variant of the Surface Laptop uses the +same MSHW0040 device ID as the 5th and later generation of Surface +devices, however they report 0 for their OEM platform revision. As the +_DSM does not exist on the devices requiring special casing, check for +the existance of the _DSM to determine if soc_button_array should be +loaded. + +Fixes: c394159310d0 ("Input: soc_button_array - add support for newer surface devices") +Co-developed-by: Maximilian Luz + +Signed-off-by: Sachi King +Patchset: surface-button +--- + drivers/input/misc/soc_button_array.c | 33 +++++++-------------------- + 1 file changed, 8 insertions(+), 25 deletions(-) + +diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c +index e79f5497948b..2bddbe6e9ea4 100644 +--- a/drivers/input/misc/soc_button_array.c ++++ b/drivers/input/misc/soc_button_array.c +@@ -537,8 +537,8 @@ static const struct soc_device_data soc_device_MSHW0028 = { + * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned + * devices use MSHW0040 for power and volume buttons, however the way they + * have to be addressed differs. Make sure that we only load this drivers +- * for the correct devices by checking the OEM Platform Revision provided by +- * the _DSM method. ++ * for the correct devices by checking if the OEM Platform Revision DSM call ++ * exists. + */ + #define MSHW0040_DSM_REVISION 0x01 + #define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision +@@ -549,31 +549,14 @@ static const guid_t MSHW0040_DSM_UUID = + static int soc_device_check_MSHW0040(struct device *dev) + { + acpi_handle handle = ACPI_HANDLE(dev); +- union acpi_object *result; +- u64 oem_platform_rev = 0; // valid revisions are nonzero +- +- // get OEM platform revision +- result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, +- MSHW0040_DSM_REVISION, +- MSHW0040_DSM_GET_OMPR, NULL, +- ACPI_TYPE_INTEGER); +- +- if (result) { +- oem_platform_rev = result->integer.value; +- ACPI_FREE(result); +- } +- +- /* +- * If the revision is zero here, the _DSM evaluation has failed. This +- * indicates that we have a Pro 4 or Book 1 and this driver should not +- * be used. +- */ +- if (oem_platform_rev == 0) +- return -ENODEV; ++ bool exists; + +- dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev); ++ // check if OEM platform revision DSM call exists ++ exists = acpi_check_dsm(handle, &MSHW0040_DSM_UUID, ++ MSHW0040_DSM_REVISION, ++ BIT(MSHW0040_DSM_GET_OMPR)); + +- return 0; ++ return exists ? 0 : -ENODEV; + } + + /* +-- +2.42.0 + +From 701b3618008b9aad7c8f480e781a3fd412b169f0 Mon Sep 17 00:00:00 2001 +From: Sachi King +Date: Tue, 5 Oct 2021 00:22:57 +1100 +Subject: [PATCH] platform/surface: surfacepro3_button: don't load on amd + variant + +The AMD variant of the Surface Laptop report 0 for their OEM platform +revision. The Surface devices that require the surfacepro3_button +driver do not have the _DSM that gets the OEM platform revision. If the +method does not exist, load surfacepro3_button. + +Fixes: 64dd243d7356 ("platform/x86: surfacepro3_button: Fix device check") +Co-developed-by: Maximilian Luz + +Signed-off-by: Sachi King +Patchset: surface-button +--- + drivers/platform/surface/surfacepro3_button.c | 30 ++++--------------- + 1 file changed, 6 insertions(+), 24 deletions(-) + +diff --git a/drivers/platform/surface/surfacepro3_button.c b/drivers/platform/surface/surfacepro3_button.c +index 2755601f979c..4240c98ca226 100644 +--- a/drivers/platform/surface/surfacepro3_button.c ++++ b/drivers/platform/surface/surfacepro3_button.c +@@ -149,7 +149,8 @@ static int surface_button_resume(struct device *dev) + /* + * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device + * ID (MSHW0040) for the power/volume buttons. Make sure this is the right +- * device by checking for the _DSM method and OEM Platform Revision. ++ * device by checking for the _DSM method and OEM Platform Revision DSM ++ * function. + * + * Returns true if the driver should bind to this device, i.e. the device is + * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1. +@@ -157,30 +158,11 @@ static int surface_button_resume(struct device *dev) + static bool surface_button_check_MSHW0040(struct acpi_device *dev) + { + acpi_handle handle = dev->handle; +- union acpi_object *result; +- u64 oem_platform_rev = 0; // valid revisions are nonzero +- +- // get OEM platform revision +- result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, +- MSHW0040_DSM_REVISION, +- MSHW0040_DSM_GET_OMPR, +- NULL, ACPI_TYPE_INTEGER); +- +- /* +- * If evaluating the _DSM fails, the method is not present. This means +- * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we +- * should use this driver. We use revision 0 indicating it is +- * unavailable. +- */ +- +- if (result) { +- oem_platform_rev = result->integer.value; +- ACPI_FREE(result); +- } +- +- dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev); + +- return oem_platform_rev == 0; ++ // make sure that OEM platform revision DSM call does not exist ++ return !acpi_check_dsm(handle, &MSHW0040_DSM_UUID, ++ MSHW0040_DSM_REVISION, ++ BIT(MSHW0040_DSM_GET_OMPR)); + } + + +-- +2.42.0 + +From d38931d4fe25e2f1a02fcde88b0cbf0756304631 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sat, 18 Feb 2023 01:02:49 +0100 +Subject: [PATCH] USB: quirks: Add USB_QUIRK_DELAY_INIT for Surface Go 3 + Type-Cover + +The touchpad on the Type-Cover of the Surface Go 3 is sometimes not +being initialized properly. Apply USB_QUIRK_DELAY_INIT to fix this +issue. + +More specifically, the device in question is a fairly standard modern +touchpad with pointer and touchpad input modes. During setup, the device +needs to be switched from pointer- to touchpad-mode (which is done in +hid-multitouch) to fully utilize it as intended. Unfortunately, however, +this seems to occasionally fail silently, leaving the device in +pointer-mode. Applying USB_QUIRK_DELAY_INIT seems to fix this. + +Link: https://github.com/linux-surface/linux-surface/issues/1059 +Signed-off-by: Maximilian Luz +Patchset: surface-typecover +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 15e9bd180a1d..0d70461d01e1 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -220,6 +220,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */ + { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM }, + ++ /* Microsoft Surface Go 3 Type-Cover */ ++ { USB_DEVICE(0x045e, 0x09b5), .driver_info = USB_QUIRK_DELAY_INIT }, ++ + /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */ + { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME }, + +-- +2.42.0 + +From 75a8d59dc8c049e0fe3eaeb509552a37ba3dc6f0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= +Date: Thu, 5 Nov 2020 13:09:45 +0100 +Subject: [PATCH] hid/multitouch: Turn off Type Cover keyboard backlight when + suspending + +The Type Cover for Microsoft Surface devices supports a special usb +control request to disable or enable the built-in keyboard backlight. +On Windows, this request happens when putting the device into suspend or +resuming it, without it the backlight of the Type Cover will remain +enabled for some time even though the computer is suspended, which looks +weird to the user. + +So add support for this special usb control request to hid-multitouch, +which is the driver that's handling the Type Cover. + +The reason we have to use a pm_notifier for this instead of the usual +suspend/resume methods is that those won't get called in case the usb +device is already autosuspended. + +Also, if the device is autosuspended, we have to briefly autoresume it +in order to send the request. Doing that should be fine, the usb-core +driver does something similar during suspend inside choose_wakeup(). + +To make sure we don't send that request to every device but only to +devices which support it, add a new quirk +MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER to hid-multitouch. For now this quirk +is only enabled for the usb id of the Surface Pro 2017 Type Cover, which +is where I confirmed that it's working. + +Patchset: surface-typecover +--- + drivers/hid/hid-multitouch.c | 100 ++++++++++++++++++++++++++++++++++- + 1 file changed, 98 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 521b2ffb4244..c8f3d05c8866 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -34,7 +34,10 @@ + #include + #include + #include ++#include + #include ++#include ++#include + #include + #include + #include +@@ -47,6 +50,7 @@ MODULE_DESCRIPTION("HID multitouch panels"); + MODULE_LICENSE("GPL"); + + #include "hid-ids.h" ++#include "usbhid/usbhid.h" + + /* quirks to control the device */ + #define MT_QUIRK_NOT_SEEN_MEANS_UP BIT(0) +@@ -72,12 +76,15 @@ MODULE_LICENSE("GPL"); + #define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) + #define MT_QUIRK_DISABLE_WAKEUP BIT(21) + #define MT_QUIRK_ORIENTATION_INVERT BIT(22) ++#define MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT BIT(23) + + #define MT_INPUTMODE_TOUCHSCREEN 0x02 + #define MT_INPUTMODE_TOUCHPAD 0x03 + + #define MT_BUTTONTYPE_CLICKPAD 0 + ++#define MS_TYPE_COVER_FEATURE_REPORT_USAGE 0xff050086 ++ + enum latency_mode { + HID_LATENCY_NORMAL = 0, + HID_LATENCY_HIGH = 1, +@@ -169,6 +176,8 @@ struct mt_device { + + struct list_head applications; + struct list_head reports; ++ ++ struct notifier_block pm_notifier; + }; + + static void mt_post_parse_default_settings(struct mt_device *td, +@@ -213,6 +222,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); + #define MT_CLS_GOOGLE 0x0111 + #define MT_CLS_RAZER_BLADE_STEALTH 0x0112 + #define MT_CLS_SMART_TECH 0x0113 ++#define MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER 0x0114 + + #define MT_DEFAULT_MAXCONTACT 10 + #define MT_MAX_MAXCONTACT 250 +@@ -397,6 +407,16 @@ static const struct mt_class mt_classes[] = { + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_SEPARATE_APP_REPORT, + }, ++ { .name = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER, ++ .quirks = MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT | ++ MT_QUIRK_ALWAYS_VALID | ++ MT_QUIRK_IGNORE_DUPLICATES | ++ MT_QUIRK_HOVERING | ++ MT_QUIRK_CONTACT_CNT_ACCURATE | ++ MT_QUIRK_STICKY_FINGERS | ++ MT_QUIRK_WIN8_PTP_BUTTONS, ++ .export_all_inputs = true ++ }, + { } + }; + +@@ -1721,6 +1741,69 @@ static void mt_expired_timeout(struct timer_list *t) + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } + ++static void get_type_cover_backlight_field(struct hid_device *hdev, ++ struct hid_field **field) ++{ ++ struct hid_report_enum *rep_enum; ++ struct hid_report *rep; ++ struct hid_field *cur_field; ++ int i, j; ++ ++ rep_enum = &hdev->report_enum[HID_FEATURE_REPORT]; ++ list_for_each_entry(rep, &rep_enum->report_list, list) { ++ for (i = 0; i < rep->maxfield; i++) { ++ cur_field = rep->field[i]; ++ ++ for (j = 0; j < cur_field->maxusage; j++) { ++ if (cur_field->usage[j].hid ++ == MS_TYPE_COVER_FEATURE_REPORT_USAGE) { ++ *field = cur_field; ++ return; ++ } ++ } ++ } ++ } ++} ++ ++static void update_keyboard_backlight(struct hid_device *hdev, bool enabled) ++{ ++ struct usb_device *udev = hid_to_usb_dev(hdev); ++ struct hid_field *field = NULL; ++ ++ /* Wake up the device in case it's already suspended */ ++ pm_runtime_get_sync(&udev->dev); ++ ++ get_type_cover_backlight_field(hdev, &field); ++ if (!field) { ++ hid_err(hdev, "couldn't find backlight field\n"); ++ goto out; ++ } ++ ++ field->value[field->index] = enabled ? 0x01ff00ff : 0x00ff00ff; ++ hid_hw_request(hdev, field->report, HID_REQ_SET_REPORT); ++ ++out: ++ pm_runtime_put_sync(&udev->dev); ++} ++ ++static int mt_pm_notifier(struct notifier_block *notifier, ++ unsigned long pm_event, ++ void *unused) ++{ ++ struct mt_device *td = ++ container_of(notifier, struct mt_device, pm_notifier); ++ struct hid_device *hdev = td->hdev; ++ ++ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT) { ++ if (pm_event == PM_SUSPEND_PREPARE) ++ update_keyboard_backlight(hdev, 0); ++ else if (pm_event == PM_POST_SUSPEND) ++ update_keyboard_backlight(hdev, 1); ++ } ++ ++ return NOTIFY_DONE; ++} ++ + static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + { + int ret, i; +@@ -1744,6 +1827,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; + hid_set_drvdata(hdev, td); + ++ td->pm_notifier.notifier_call = mt_pm_notifier; ++ register_pm_notifier(&td->pm_notifier); ++ + INIT_LIST_HEAD(&td->applications); + INIT_LIST_HEAD(&td->reports); + +@@ -1782,15 +1868,19 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + timer_setup(&td->release_timer, mt_expired_timeout, 0); + + ret = hid_parse(hdev); +- if (ret != 0) ++ if (ret != 0) { ++ unregister_pm_notifier(&td->pm_notifier); + return ret; ++ } + + if (mtclass->quirks & MT_QUIRK_FIX_CONST_CONTACT_ID) + mt_fix_const_fields(hdev, HID_DG_CONTACTID); + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +- if (ret) ++ if (ret) { ++ unregister_pm_notifier(&td->pm_notifier); + return ret; ++ } + + ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); + if (ret) +@@ -1842,6 +1932,7 @@ static void mt_remove(struct hid_device *hdev) + { + struct mt_device *td = hid_get_drvdata(hdev); + ++ unregister_pm_notifier(&td->pm_notifier); + del_timer_sync(&td->release_timer); + + sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); +@@ -2219,6 +2310,11 @@ static const struct hid_device_id mt_devices[] = { + MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, + USB_DEVICE_ID_XIROKU_CSR2) }, + ++ /* Microsoft Surface type cover */ ++ { .driver_data = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER, ++ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, ++ USB_VENDOR_ID_MICROSOFT, 0x09c0) }, ++ + /* Google MT devices */ + { .driver_data = MT_CLS_GOOGLE, + HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, +-- +2.42.0 + +From 6387e47aa58153a28176ffb65da4f3c40842b495 Mon Sep 17 00:00:00 2001 +From: PJungkamp +Date: Fri, 25 Feb 2022 12:04:25 +0100 +Subject: [PATCH] hid/multitouch: Add support for surface pro type cover tablet + switch + +The Surface Pro Type Cover has several non standard HID usages in it's +hid report descriptor. +I noticed that, upon folding the typecover back, a vendor specific range +of 4 32 bit integer hid usages is transmitted. +Only the first byte of the message seems to convey reliable information +about the keyboard state. + +0x22 => Normal (keys enabled) +0x33 => Folded back (keys disabled) +0x53 => Rotated left/right side up (keys disabled) +0x13 => Cover closed (keys disabled) +0x43 => Folded back and Tablet upside down (keys disabled) +This list may not be exhaustive. + +The tablet mode switch will be disabled for a value of 0x22 and enabled +on any other value. + +Patchset: surface-typecover +--- + drivers/hid/hid-multitouch.c | 148 +++++++++++++++++++++++++++++------ + 1 file changed, 122 insertions(+), 26 deletions(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index c8f3d05c8866..1c6e4d66e762 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -77,6 +77,7 @@ MODULE_LICENSE("GPL"); + #define MT_QUIRK_DISABLE_WAKEUP BIT(21) + #define MT_QUIRK_ORIENTATION_INVERT BIT(22) + #define MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT BIT(23) ++#define MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH BIT(24) + + #define MT_INPUTMODE_TOUCHSCREEN 0x02 + #define MT_INPUTMODE_TOUCHPAD 0x03 +@@ -84,6 +85,8 @@ MODULE_LICENSE("GPL"); + #define MT_BUTTONTYPE_CLICKPAD 0 + + #define MS_TYPE_COVER_FEATURE_REPORT_USAGE 0xff050086 ++#define MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE 0xff050072 ++#define MS_TYPE_COVER_APPLICATION 0xff050050 + + enum latency_mode { + HID_LATENCY_NORMAL = 0, +@@ -409,6 +412,7 @@ static const struct mt_class mt_classes[] = { + }, + { .name = MT_CLS_WIN_8_MS_SURFACE_TYPE_COVER, + .quirks = MT_QUIRK_HAS_TYPE_COVER_BACKLIGHT | ++ MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH | + MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_IGNORE_DUPLICATES | + MT_QUIRK_HOVERING | +@@ -1390,6 +1394,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + field->application != HID_CP_CONSUMER_CONTROL && + field->application != HID_GD_WIRELESS_RADIO_CTLS && + field->application != HID_GD_SYSTEM_MULTIAXIS && ++ !(field->application == MS_TYPE_COVER_APPLICATION && ++ application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && ++ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) && + !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && + application->quirks & MT_QUIRK_ASUS_CUSTOM_UP)) + return -1; +@@ -1417,6 +1424,21 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, + return 1; + } + ++ /* ++ * The Microsoft Surface Pro Typecover has a non-standard HID ++ * tablet mode switch on a vendor specific usage page with vendor ++ * specific usage. ++ */ ++ if (field->application == MS_TYPE_COVER_APPLICATION && ++ application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && ++ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { ++ usage->type = EV_SW; ++ usage->code = SW_TABLET_MODE; ++ *max = SW_MAX; ++ *bit = hi->input->swbit; ++ return 1; ++ } ++ + if (rdata->is_mt_collection) + return mt_touch_input_mapping(hdev, hi, field, usage, bit, max, + application); +@@ -1438,6 +1460,7 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, + { + struct mt_device *td = hid_get_drvdata(hdev); + struct mt_report_data *rdata; ++ struct input_dev *input; + + rdata = mt_find_report_data(td, field->report); + if (rdata && rdata->is_mt_collection) { +@@ -1445,6 +1468,19 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, + return -1; + } + ++ /* ++ * We own an input device which acts as a tablet mode switch for ++ * the Surface Pro Typecover. ++ */ ++ if (field->application == MS_TYPE_COVER_APPLICATION && ++ rdata->application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && ++ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { ++ input = hi->input; ++ input_set_capability(input, EV_SW, SW_TABLET_MODE); ++ input_report_switch(input, SW_TABLET_MODE, 0); ++ return -1; ++ } + -+ /* configure LEDB current if the properties can be got */ -+ if (!device_property_read_u32(&pdev->dev, "ti,ledb-current", &curr)) { -+ if (curr > CTRLB_16MA) { -+ dev_err(&pdev->dev, -+ "Invalid LEDB current value: %d\n", -+ curr); -+ return -EINVAL; + /* let hid-core decide for the others */ + return 0; + } +@@ -1454,11 +1490,21 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, + { + struct mt_device *td = hid_get_drvdata(hid); + struct mt_report_data *rdata; ++ struct input_dev *input; + + rdata = mt_find_report_data(td, field->report); + if (rdata && rdata->is_mt_collection) + return mt_touch_event(hid, field, usage, value); + ++ if (field->application == MS_TYPE_COVER_APPLICATION && ++ rdata->application->quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH && ++ usage->hid == MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE) { ++ input = field->hidinput->input; ++ input_report_switch(input, SW_TABLET_MODE, (value & 0xFF) != 0x22); ++ input_sync(input); ++ return 1; ++ } ++ + return 0; + } + +@@ -1611,6 +1657,42 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app) + app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; + } + ++static int get_type_cover_field(struct hid_report_enum *rep_enum, ++ struct hid_field **field, int usage) ++{ ++ struct hid_report *rep; ++ struct hid_field *cur_field; ++ int i, j; ++ ++ list_for_each_entry(rep, &rep_enum->report_list, list) { ++ for (i = 0; i < rep->maxfield; i++) { ++ cur_field = rep->field[i]; ++ if (cur_field->application != MS_TYPE_COVER_APPLICATION) ++ continue; ++ for (j = 0; j < cur_field->maxusage; j++) { ++ if (cur_field->usage[j].hid == usage) { ++ *field = cur_field; ++ return true; ++ } ++ } + } -+ ret = regmap_update_bits(tps68470->regmap, TPS68470_REG_ILEDCTL, -+ TPS68470_ILEDCTL_CTRLB, curr); + } -+ return ret; ++ return false; ++} ++ ++static void request_type_cover_tablet_mode_switch(struct hid_device *hdev) ++{ ++ struct hid_field *field; ++ ++ if (get_type_cover_field(&hdev->report_enum[HID_INPUT_REPORT], ++ &field, ++ MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE)) { ++ hid_hw_request(hdev, field->report, HID_REQ_GET_REPORT); ++ } else { ++ hid_err(hdev, "couldn't find tablet mode field\n"); ++ } ++} ++ + static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) + { + struct mt_device *td = hid_get_drvdata(hdev); +@@ -1659,6 +1741,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) + /* force BTN_STYLUS to allow tablet matching in udev */ + __set_bit(BTN_STYLUS, hi->input->keybit); + break; ++ case MS_TYPE_COVER_APPLICATION: ++ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) { ++ suffix = "Tablet Mode Switch"; ++ request_type_cover_tablet_mode_switch(hdev); ++ break; ++ } ++ fallthrough; + default: + suffix = "UNKNOWN"; + break; +@@ -1741,30 +1830,6 @@ static void mt_expired_timeout(struct timer_list *t) + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } + +-static void get_type_cover_backlight_field(struct hid_device *hdev, +- struct hid_field **field) +-{ +- struct hid_report_enum *rep_enum; +- struct hid_report *rep; +- struct hid_field *cur_field; +- int i, j; +- +- rep_enum = &hdev->report_enum[HID_FEATURE_REPORT]; +- list_for_each_entry(rep, &rep_enum->report_list, list) { +- for (i = 0; i < rep->maxfield; i++) { +- cur_field = rep->field[i]; +- +- for (j = 0; j < cur_field->maxusage; j++) { +- if (cur_field->usage[j].hid +- == MS_TYPE_COVER_FEATURE_REPORT_USAGE) { +- *field = cur_field; +- return; +- } +- } +- } +- } +-} +- + static void update_keyboard_backlight(struct hid_device *hdev, bool enabled) + { + struct usb_device *udev = hid_to_usb_dev(hdev); +@@ -1773,8 +1838,9 @@ static void update_keyboard_backlight(struct hid_device *hdev, bool enabled) + /* Wake up the device in case it's already suspended */ + pm_runtime_get_sync(&udev->dev); + +- get_type_cover_backlight_field(hdev, &field); +- if (!field) { ++ if (!get_type_cover_field(&hdev->report_enum[HID_FEATURE_REPORT], ++ &field, ++ MS_TYPE_COVER_FEATURE_REPORT_USAGE)) { + hid_err(hdev, "couldn't find backlight field\n"); + goto out; + } +@@ -1909,13 +1975,24 @@ static int mt_suspend(struct hid_device *hdev, pm_message_t state) + + static int mt_reset_resume(struct hid_device *hdev) + { ++ struct mt_device *td = hid_get_drvdata(hdev); ++ + mt_release_contacts(hdev); + mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); ++ ++ /* Request an update on the typecover folding state on resume ++ * after reset. ++ */ ++ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) ++ request_type_cover_tablet_mode_switch(hdev); ++ + return 0; + } + + static int mt_resume(struct hid_device *hdev) + { ++ struct mt_device *td = hid_get_drvdata(hdev); ++ + /* Some Elan legacy devices require SET_IDLE to be set on resume. + * It should be safe to send it to other devices too. + * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ +@@ -1924,6 +2001,10 @@ static int mt_resume(struct hid_device *hdev) + + mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true); + ++ /* Request an update on the typecover folding state on resume. */ ++ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) ++ request_type_cover_tablet_mode_switch(hdev); ++ + return 0; + } + #endif +@@ -1931,6 +2012,21 @@ static int mt_resume(struct hid_device *hdev) + static void mt_remove(struct hid_device *hdev) + { + struct mt_device *td = hid_get_drvdata(hdev); ++ struct hid_field *field; ++ struct input_dev *input; ++ ++ /* Reset tablet mode switch on disconnect. */ ++ if (td->mtclass.quirks & MT_QUIRK_HAS_TYPE_COVER_TABLET_MODE_SWITCH) { ++ if (get_type_cover_field(&hdev->report_enum[HID_INPUT_REPORT], ++ &field, ++ MS_TYPE_COVER_TABLET_MODE_SWITCH_USAGE)) { ++ input = field->hidinput->input; ++ input_report_switch(input, SW_TABLET_MODE, 0); ++ input_sync(input); ++ } else { ++ hid_err(hdev, "couldn't find tablet mode field\n"); ++ } ++ } + + unregister_pm_notifier(&td->pm_notifier); + del_timer_sync(&td->release_timer); +-- +2.42.0 + +From 42a0ecfd028c26a4ea5a5f8108c36fe3ffe4f6a2 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sun, 19 Feb 2023 22:12:24 +0100 +Subject: [PATCH] PCI: Add quirk to prevent calling shutdown mehtod + +Work around buggy EFI firmware: On some Microsoft Surface devices +(Surface Pro 9 and Surface Laptop 5) the EFI ResetSystem call with +EFI_RESET_SHUTDOWN doesn't function properly. Instead of shutting the +system down, it returns and the system stays on. + +It turns out that this only happens after PCI shutdown callbacks ran for +specific devices. Excluding those devices from the shutdown process +makes the ResetSystem call work as expected. + +TODO: Maybe we can find a better way or the root cause of this? + +Not-Signed-off-by: Maximilian Luz +Patchset: surface-shutdown +--- + drivers/pci/pci-driver.c | 3 +++ + drivers/pci/quirks.c | 36 ++++++++++++++++++++++++++++++++++++ + include/linux/pci.h | 1 + + 3 files changed, 40 insertions(+) + +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index ae9baf801681..fdfaec2312a0 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -507,6 +507,9 @@ static void pci_device_shutdown(struct device *dev) + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_driver *drv = pci_dev->driver; + ++ if (pci_dev->no_shutdown) ++ return; ++ + pm_runtime_resume(dev); + + if (drv && drv->shutdown) +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 321156ca273d..37e06e778ce2 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -6138,3 +6138,39 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); + #endif ++ ++static const struct dmi_system_id no_shutdown_dmi_table[] = { ++ /* ++ * Systems on which some devices should not be touched during shutdown. ++ */ ++ { ++ .ident = "Microsoft Surface Pro 9", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Pro 9"), ++ }, ++ }, ++ { ++ .ident = "Microsoft Surface Laptop 5", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 5"), ++ }, ++ }, ++ {} ++}; ++ ++static void quirk_no_shutdown(struct pci_dev *dev) ++{ ++ if (!dmi_check_system(no_shutdown_dmi_table)) ++ return; ++ ++ dev->no_shutdown = 1; ++ pci_info(dev, "disabling shutdown ops for [%04x:%04x]\n", ++ dev->vendor, dev->device); +} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461e, quirk_no_shutdown); // Thunderbolt 4 USB Controller ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x462f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x466d, quirk_no_shutdown); // Thunderbolt 4 NHI ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x46a8, quirk_no_shutdown); // GPU +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 7ee498cd1f37..740049a82343 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -464,6 +464,7 @@ struct pci_dev { + unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */ + unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */ + unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */ ++ unsigned int no_shutdown:1; /* Do not touch device on shutdown */ + pci_dev_flags_t dev_flags; + atomic_t enable_cnt; /* pci_enable_device has been called */ + +-- +2.42.0 + +From 0e7f1e2a3a8d9bfbacaa6dfd2f902de83390b4c1 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Sun, 12 Mar 2023 01:41:57 +0100 +Subject: [PATCH] platform/surface: gpe: Add support for Surface Pro 9 + +Add the lid GPE used by the Surface Pro 9. + +Signed-off-by: Maximilian Luz +Patchset: surface-gpe +--- + drivers/platform/surface/surface_gpe.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c +index c219b840d491..69c4352e8406 100644 +--- a/drivers/platform/surface/surface_gpe.c ++++ b/drivers/platform/surface/surface_gpe.c +@@ -41,6 +41,11 @@ static const struct property_entry lid_device_props_l4F[] = { + {}, + }; + ++static const struct property_entry lid_device_props_l52[] = { ++ PROPERTY_ENTRY_U32("gpe", 0x52), ++ {}, ++}; ++ + static const struct property_entry lid_device_props_l57[] = { + PROPERTY_ENTRY_U32("gpe", 0x57), + {}, +@@ -107,6 +112,18 @@ static const struct dmi_system_id dmi_lid_device_table[] = { + }, + .driver_data = (void *)lid_device_props_l4B, + }, ++ { ++ /* ++ * We match for SKU here due to product name clash with the ARM ++ * version. ++ */ ++ .ident = "Surface Pro 9", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_9_2038"), ++ }, ++ .driver_data = (void *)lid_device_props_l52, ++ }, + { + .ident = "Surface Book 1", + .matches = { +-- +2.42.0 + +From 91a302af94f03251baa2e66abe81b0beb967a4ae Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 10 Oct 2021 20:56:57 +0200 +Subject: [PATCH] ACPI: delay enumeration of devices with a _DEP pointing to an + INT3472 device + +The clk and regulator frameworks expect clk/regulator consumer-devices +to have info about the consumed clks/regulators described in the device's +fw_node. + +To work around cases where this info is not present in the firmware tables, +which is often the case on x86/ACPI devices, both frameworks allow the +provider-driver to attach info about consumers to the clks/regulators +when registering these. + +This causes problems with the probe ordering wrt drivers for consumers +of these clks/regulators. Since the lookups are only registered when the +provider-driver binds, trying to get these clks/regulators before then +results in a -ENOENT error for clks and a dummy regulator for regulators. + +One case where we hit this issue is camera sensors such as e.g. the OV8865 +sensor found on the Microsoft Surface Go. The sensor uses clks, regulators +and GPIOs provided by a TPS68470 PMIC which is described in an INT3472 +ACPI device. There is special platform code handling this and setting +platform_data with the necessary consumer info on the MFD cells +instantiated for the PMIC under: drivers/platform/x86/intel/int3472. + +For this to work properly the ov8865 driver must not bind to the I2C-client +for the OV8865 sensor until after the TPS68470 PMIC gpio, regulator and +clk MFD cells have all been fully setup. + +The OV8865 on the Microsoft Surface Go is just one example, all X86 +devices using the Intel IPU3 camera block found on recent Intel SoCs +have similar issues where there is an INT3472 HID ACPI-device, which +describes the clks and regulators, and the driver for this INT3472 device +must be fully initialized before the sensor driver (any sensor driver) +binds for things to work properly. + +On these devices the ACPI nodes describing the sensors all have a _DEP +dependency on the matching INT3472 ACPI device (there is one per sensor). + +This allows solving the probe-ordering problem by delaying the enumeration +(instantiation of the I2C-client in the ov8865 example) of ACPI-devices +which have a _DEP dependency on an INT3472 device. + +The new acpi_dev_ready_for_enumeration() helper used for this is also +exported because for devices, which have the enumeration_by_parent flag +set, the parent-driver will do its own scan of child ACPI devices and +it will try to enumerate those during its probe(). Code doing this such +as e.g. the i2c-core-acpi.c code must call this new helper to ensure +that it too delays the enumeration until all the _DEP dependencies are +met on devices which have the new honor_deps flag set. + +Signed-off-by: Hans de Goede +Patchset: cameras +--- + drivers/acpi/scan.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c +index 87e385542576..1183d09c13a6 100644 +--- a/drivers/acpi/scan.c ++++ b/drivers/acpi/scan.c +@@ -2105,6 +2105,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used, + + static void acpi_default_enumeration(struct acpi_device *device) + { ++ if (!acpi_dev_ready_for_enumeration(device)) ++ return; + -+static int tps68470_leds_probe(struct platform_device *pdev) -+{ -+ int i = 0; -+ int ret = 0; -+ struct tps68470_device *tps68470; -+ struct tps68470_led *led; -+ struct led_classdev *lcdev; + /* + * Do not enumerate devices with enumeration_by_parent flag set as + * they will be enumerated by their respective parents. +-- +2.42.0 + +From 2b033206c433221e3955fab9f7cc0ce07794a2ec Mon Sep 17 00:00:00 2001 +From: zouxiaoh +Date: Fri, 25 Jun 2021 08:52:59 +0800 +Subject: [PATCH] iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs + +Intel IPU(Image Processing Unit) has its own (IO)MMU hardware, +The IPU driver allocates its own page table that is not mapped +via the DMA, and thus the Intel IOMMU driver blocks access giving +this error: DMAR: DRHD: handling fault status reg 3 DMAR: +[DMA Read] Request device [00:05.0] PASID ffffffff +fault addr 76406000 [fault reason 06] PTE Read access is not set +As IPU is not an external facing device which is not risky, so use +IOMMU passthrough mode for Intel IPUs. + +Change-Id: I6dcccdadac308cf42e20a18e1b593381391e3e6b +Depends-On: Iacd67578e8c6a9b9ac73285f52b4081b72fb68a6 +Tracked-On: #JIITL8-411 +Signed-off-by: Bingbu Cao +Signed-off-by: zouxiaoh +Signed-off-by: Xu Chongyang +Patchset: cameras +--- + drivers/iommu/intel/iommu.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c +index fc4799415c3c..e10b4f62594d 100644 +--- a/drivers/iommu/intel/iommu.c ++++ b/drivers/iommu/intel/iommu.c +@@ -37,6 +37,12 @@ + #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) + #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB) + #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) ++#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ ++ ((pdev)->device == 0x9a19 || \ ++ (pdev)->device == 0x9a39 || \ ++ (pdev)->device == 0x4e19 || \ ++ (pdev)->device == 0x465d || \ ++ (pdev)->device == 0x1919)) + #define IS_IPTS(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ + ((pdev)->device == 0x9d3e)) + #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) +@@ -290,12 +296,14 @@ EXPORT_SYMBOL_GPL(intel_iommu_enabled); + + static int dmar_map_gfx = 1; + static int dmar_map_ipts = 1; ++static int dmar_map_ipu = 1; + static int intel_iommu_superpage = 1; + static int iommu_identity_mapping; + static int iommu_skip_te_disable; + + #define IDENTMAP_GFX 2 + #define IDENTMAP_AZALIA 4 ++#define IDENTMAP_IPU 8 + #define IDENTMAP_IPTS 16 + + const struct iommu_ops intel_iommu_ops; +@@ -2553,6 +2561,9 @@ static int device_def_domain_type(struct device *dev) + if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) + return IOMMU_DOMAIN_IDENTITY; + ++ if ((iommu_identity_mapping & IDENTMAP_IPU) && IS_INTEL_IPU(pdev)) ++ return IOMMU_DOMAIN_IDENTITY; + -+ tps68470 = devm_kzalloc(&pdev->dev, sizeof(struct tps68470_device), -+ GFP_KERNEL); -+ if (!tps68470) -+ return -ENOMEM; + if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev)) + return IOMMU_DOMAIN_IDENTITY; + } +@@ -2862,6 +2873,9 @@ static int __init init_dmars(void) + if (!dmar_map_gfx) + iommu_identity_mapping |= IDENTMAP_GFX; + ++ if (!dmar_map_ipu) ++ iommu_identity_mapping |= IDENTMAP_IPU; + -+ tps68470->dev = &pdev->dev; -+ tps68470->regmap = dev_get_drvdata(pdev->dev.parent); + if (!dmar_map_ipts) + iommu_identity_mapping |= IDENTMAP_IPTS; + +@@ -4781,6 +4795,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev) + dmar_map_gfx = 0; + } + ++static void quirk_iommu_ipu(struct pci_dev *dev) ++{ ++ if (!IS_INTEL_IPU(dev)) ++ return; + -+ for (i = 0; i < TPS68470_NUM_LEDS; i++) { -+ led = &tps68470->leds[i]; -+ lcdev = &led->lcdev; ++ if (risky_device(dev)) ++ return; + -+ led->led_id = i; ++ pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n"); ++ dmar_map_ipu = 0; ++} + -+ lcdev->name = devm_kasprintf(tps68470->dev, GFP_KERNEL, "%s::%s", -+ tps68470_led_names[i], LED_FUNCTION_INDICATOR); -+ if (!lcdev->name) -+ return -ENOMEM; + static void quirk_iommu_ipts(struct pci_dev *dev) + { + if (!IS_IPTS(dev)) +@@ -4792,6 +4818,7 @@ static void quirk_iommu_ipts(struct pci_dev *dev) + pci_info(dev, "Passthrough IOMMU for IPTS\n"); + dmar_map_ipts = 0; + } + -+ lcdev->max_brightness = 1; -+ lcdev->brightness = 0; -+ lcdev->brightness_set_blocking = tps68470_brightness_set; -+ lcdev->brightness_get = tps68470_brightness_get; -+ lcdev->dev = &pdev->dev; + /* G4x/GM45 integrated gfx dmar support is totally busted. */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx); +@@ -4827,6 +4854,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); + ++/* disable IPU dmar support */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu); + -+ ret = devm_led_classdev_register(tps68470->dev, lcdev); -+ if (ret) { -+ dev_err_probe(tps68470->dev, ret, -+ "error registering led\n"); -+ goto err_exit; -+ } + /* disable IPTS dmar support */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9D3E, quirk_iommu_ipts); + +-- +2.42.0 + +From eec09b357ed7b25912c9bf682e21fa0f1344e912 Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Sun, 10 Oct 2021 20:57:02 +0200 +Subject: [PATCH] platform/x86: int3472: Enable I2c daisy chain + +The TPS68470 PMIC has an I2C passthrough mode through which I2C traffic +can be forwarded to a device connected to the PMIC as though it were +connected directly to the system bus. Enable this mode when the chip +is initialised. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/platform/x86/intel/int3472/tps68470.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c +index 1e107fd49f82..e3e1696e7f0e 100644 +--- a/drivers/platform/x86/intel/int3472/tps68470.c ++++ b/drivers/platform/x86/intel/int3472/tps68470.c +@@ -46,6 +46,13 @@ static int tps68470_chip_init(struct device *dev, struct regmap *regmap) + return ret; + } + ++ /* Enable I2C daisy chain */ ++ ret = regmap_write(regmap, TPS68470_REG_S_I2C_CTL, 0x03); ++ if (ret) { ++ dev_err(dev, "Failed to enable i2c daisy chain\n"); ++ return ret; ++ } + -+ if (i == TPS68470_ILED_B) { -+ ret = tps68470_ledb_current_init(pdev, tps68470); -+ if (ret) -+ goto err_exit; -+ } + dev_info(dev, "TPS68470 REVID: 0x%02x\n", version); + + return 0; +-- +2.42.0 + +From 3ee1b7ce0457aba33817a415213caf951dab2cbf Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Wed, 4 May 2022 23:21:45 +0100 +Subject: [PATCH] media: ipu3-cio2: Move functionality from .complete() to + .bound() + +Creating links and registering subdev nodes during the .complete() +callback has the unfortunate effect of preventing all cameras that +connect to a notifier from working if any one of their drivers fails +to probe. Moving the functionality from .complete() to .bound() allows +those camera sensor drivers that did probe correctly to work regardless. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 59 +++++++------------ + 1 file changed, 21 insertions(+), 38 deletions(-) + +diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +index ca51776a961f..c027b2bfd851 100644 +--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c ++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +@@ -1386,7 +1386,10 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, + { + struct cio2_device *cio2 = to_cio2_device(notifier); + struct sensor_async_subdev *s_asd = to_sensor_asd(asd); ++ struct device *dev = &cio2->pci_dev->dev; + struct cio2_queue *q; ++ unsigned int pad; ++ int ret; + + if (cio2->queue[s_asd->csi2.port].sensor) + return -EBUSY; +@@ -1397,7 +1400,24 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, + q->sensor = sd; + q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port); + +- return 0; ++ ret = media_entity_get_fwnode_pad(&q->sensor->entity, ++ s_asd->asd.match.fwnode, ++ MEDIA_PAD_FL_SOURCE); ++ if (ret < 0) { ++ dev_err(dev, "no pad for endpoint %pfw (%d)\n", ++ s_asd->asd.match.fwnode, ret); ++ return ret; + } + -+err_exit: ++ ret = media_create_pad_link(&q->sensor->entity, ret, &q->subdev.entity, ++ CIO2_PAD_SINK, 0); + if (ret) { -+ for (i = 0; i < TPS68470_NUM_LEDS; i++) { -+ if (tps68470->leds[i].lcdev.name) -+ devm_led_classdev_unregister(&pdev->dev, -+ &tps68470->leds[i].lcdev); -+ } ++ dev_err(dev, "failed to create link for %s\n", ++ q->sensor->name); ++ return ret; + } + -+ return ret; ++ return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); + } + + /* The .unbind callback */ +@@ -1411,46 +1431,9 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier, + cio2->queue[s_asd->csi2.port].sensor = NULL; + } + +-/* .complete() is called after all subdevices have been located */ +-static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) +-{ +- struct cio2_device *cio2 = to_cio2_device(notifier); +- struct device *dev = &cio2->pci_dev->dev; +- struct sensor_async_subdev *s_asd; +- struct v4l2_async_subdev *asd; +- struct cio2_queue *q; +- int ret; +- +- list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) { +- s_asd = to_sensor_asd(asd); +- q = &cio2->queue[s_asd->csi2.port]; +- +- ret = media_entity_get_fwnode_pad(&q->sensor->entity, +- s_asd->asd.match.fwnode, +- MEDIA_PAD_FL_SOURCE); +- if (ret < 0) { +- dev_err(dev, "no pad for endpoint %pfw (%d)\n", +- s_asd->asd.match.fwnode, ret); +- return ret; +- } +- +- ret = media_create_pad_link(&q->sensor->entity, ret, +- &q->subdev.entity, CIO2_PAD_SINK, +- 0); +- if (ret) { +- dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n", +- q->sensor->name, s_asd->asd.match.fwnode, ret); +- return ret; +- } +- } +- +- return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); +-} +- + static const struct v4l2_async_notifier_operations cio2_async_ops = { + .bound = cio2_notifier_bound, + .unbind = cio2_notifier_unbind, +- .complete = cio2_notifier_complete, + }; + + static int cio2_parse_firmware(struct cio2_device *cio2) +-- +2.42.0 + +From 43767f29d49a977f39fe9bcbd9d347b5b2549f3d Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Thu, 2 Jun 2022 22:15:56 +0100 +Subject: [PATCH] media: ipu3-cio2: Re-add .complete() to ipu3-cio2 + +Removing the .complete() callback had some unintended consequences. +Because the VCM driver is not directly linked to the ipu3-cio2 +driver .bound() never gets called for it, which means its devnode +is never created if it probes late. Because .complete() waits for +any sub-notifiers to also be complete it is captured in that call. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +index c027b2bfd851..031acee26553 100644 +--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c ++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +@@ -1431,9 +1431,18 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier, + cio2->queue[s_asd->csi2.port].sensor = NULL; + } + ++/* .complete() is called after all subdevices have been located */ ++static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) ++{ ++ struct cio2_device *cio2 = to_cio2_device(notifier); ++ ++ return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); +} -+static struct platform_driver tps68470_led_driver = { -+ .driver = { -+ .name = "tps68470-led", -+ }, -+ .probe = tps68470_leds_probe, -+}; + -+module_platform_driver(tps68470_led_driver); + static const struct v4l2_async_notifier_operations cio2_async_ops = { + .bound = cio2_notifier_bound, + .unbind = cio2_notifier_unbind, ++ .complete = cio2_notifier_complete, + }; + + static int cio2_parse_firmware(struct cio2_device *cio2) +-- +2.42.0 + +From 5aa4977340e179ed4e2b7e1236ee8f0ed5af3d4b Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Thu, 28 Oct 2021 21:55:16 +0100 +Subject: [PATCH] media: i2c: Add driver for DW9719 VCM + +Add a driver for the DW9719 VCM. The driver creates a v4l2 subdevice +and registers a control to set the desired focus. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + MAINTAINERS | 7 + + drivers/media/i2c/Kconfig | 11 + + drivers/media/i2c/Makefile | 1 + + drivers/media/i2c/dw9719.c | 425 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 444 insertions(+) + create mode 100644 drivers/media/i2c/dw9719.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 4cc6bf79fdd8..439cf523b80e 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -6251,6 +6251,13 @@ T: git git://linuxtv.org/media_tree.git + F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml + F: drivers/media/i2c/dw9714.c + ++DONGWOON DW9719 LENS VOICE COIL DRIVER ++M: Daniel Scally ++L: linux-media@vger.kernel.org ++S: Maintained ++T: git git://linuxtv.org/media_tree.git ++F: drivers/media/i2c/dw9719.c + -+MODULE_ALIAS("platform:tps68470-led"); -+MODULE_DESCRIPTION("LED driver for TPS68470 PMIC"); -+MODULE_LICENSE("GPL v2"); + DONGWOON DW9768 LENS VOICE COIL DRIVER + M: Dongchun Zhu + L: linux-media@vger.kernel.org diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index 226454b6a..ddddf6849 100644 +index 0669aea3eba3..6959ee1a89fb 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig -@@ -848,6 +848,17 @@ config VIDEO_DW9714 +@@ -855,6 +855,17 @@ config VIDEO_DW9714 capability. This is designed for linear control of voice coil motors, controlled via I2C serial interface. +config VIDEO_DW9719 + tristate "DW9719 lens voice coil support" -+ depends on I2C && VIDEO_DEV ++ depends on I2C && VIDEO_V4L2 + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC @@ -5545,7 +6984,7 @@ index 226454b6a..ddddf6849 100644 tristate "DW9768 lens voice coil support" depends on I2C && VIDEO_DEV diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile -index c743aeb5d..db1ebf5ca 100644 +index c743aeb5d1ad..db1ebf5cadfe 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o @@ -5558,7 +6997,7 @@ index c743aeb5d..db1ebf5ca 100644 obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/ diff --git a/drivers/media/i2c/dw9719.c b/drivers/media/i2c/dw9719.c new file mode 100644 -index 000000000..180b04d2a +index 000000000000..180b04d2a6b3 --- /dev/null +++ b/drivers/media/i2c/dw9719.c @@ -0,0 +1,425 @@ @@ -5712,1209 +7151,1007 @@ index 000000000..180b04d2a + /* Need 100us to transit from SHUTDOWN to STANDBY*/ + usleep_range(100, 1000); + -+ ret = dw9719_i2c_wr8(dw9719->client, DW9719_CONTROL, -+ DW9719_ENABLE_RINGING); -+ if (ret < 0) -+ goto fail_powerdown; -+ -+ ret = dw9719_i2c_wr8(dw9719->client, DW9719_MODE, DW9719_MODE_SAC3); -+ if (ret < 0) -+ goto fail_powerdown; -+ -+ ret = dw9719_i2c_wr8(dw9719->client, DW9719_VCM_FREQ, -+ DW9719_DEFAULT_VCM_FREQ); -+ if (ret < 0) -+ goto fail_powerdown; -+ -+ return 0; -+ -+fail_powerdown: -+ dw9719_power_down(dw9719); -+ return ret; -+} -+ -+static int dw9719_t_focus_abs(struct dw9719_device *dw9719, s32 value) -+{ -+ int ret; -+ -+ value = clamp(value, 0, DW9719_MAX_FOCUS_POS); -+ ret = dw9719_i2c_wr16(dw9719->client, DW9719_VCM_CURRENT, value); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int dw9719_set_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct dw9719_device *dw9719 = container_of(ctrl->handler, -+ struct dw9719_device, -+ ctrls.handler); -+ int ret; -+ -+ /* Only apply changes to the controls if the device is powered up */ -+ if (!pm_runtime_get_if_in_use(dw9719->dev)) -+ return 0; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_FOCUS_ABSOLUTE: -+ ret = dw9719_t_focus_abs(dw9719, ctrl->val); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ pm_runtime_put(dw9719->dev); -+ -+ return ret; -+} -+ -+static const struct v4l2_ctrl_ops dw9719_ctrl_ops = { -+ .s_ctrl = dw9719_set_ctrl, -+}; -+ -+static int __maybe_unused dw9719_suspend(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct dw9719_device *dw9719 = to_dw9719_device(sd); -+ int ret; -+ int val; -+ -+ for (val = dw9719->ctrls.focus->val; val >= 0; -+ val -= DW9719_CTRL_STEPS) { -+ ret = dw9719_t_focus_abs(dw9719, val); -+ if (ret) -+ return ret; -+ -+ usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10); -+ } -+ -+ return dw9719_power_down(dw9719); -+} -+ -+static int __maybe_unused dw9719_resume(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct dw9719_device *dw9719 = to_dw9719_device(sd); -+ int current_focus = dw9719->ctrls.focus->val; -+ int ret; -+ int val; -+ -+ ret = dw9719_power_up(dw9719); -+ if (ret) -+ return ret; -+ -+ for (val = current_focus % DW9719_CTRL_STEPS; val < current_focus; -+ val += DW9719_CTRL_STEPS) { -+ ret = dw9719_t_focus_abs(dw9719, val); -+ if (ret) -+ goto err_power_down; -+ -+ usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10); -+ } -+ -+ return 0; -+ -+err_power_down: -+ dw9719_power_down(dw9719); -+ return ret; -+} -+ -+static int dw9719_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -+{ -+ return pm_runtime_resume_and_get(sd->dev); -+} -+ -+static int dw9719_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -+{ -+ pm_runtime_put(sd->dev); -+ -+ return 0; -+} -+ -+static const struct v4l2_subdev_internal_ops dw9719_internal_ops = { -+ .open = dw9719_open, -+ .close = dw9719_close, -+}; -+ -+static int dw9719_init_controls(struct dw9719_device *dw9719) -+{ -+ const struct v4l2_ctrl_ops *ops = &dw9719_ctrl_ops; -+ int ret; -+ -+ ret = v4l2_ctrl_handler_init(&dw9719->ctrls.handler, 1); -+ if (ret) -+ return ret; -+ -+ dw9719->ctrls.focus = v4l2_ctrl_new_std(&dw9719->ctrls.handler, ops, -+ V4L2_CID_FOCUS_ABSOLUTE, 0, -+ DW9719_MAX_FOCUS_POS, 1, 0); -+ -+ if (dw9719->ctrls.handler.error) { -+ dev_err(dw9719->dev, "Error initialising v4l2 ctrls\n"); -+ ret = dw9719->ctrls.handler.error; -+ goto err_free_handler; -+ } -+ -+ dw9719->sd.ctrl_handler = &dw9719->ctrls.handler; -+ -+ return ret; -+ -+err_free_handler: -+ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); -+ return ret; -+} -+ -+static const struct v4l2_subdev_ops dw9719_ops = { }; -+ -+static int dw9719_probe(struct i2c_client *client) -+{ -+ struct dw9719_device *dw9719; -+ int ret; -+ -+ dw9719 = devm_kzalloc(&client->dev, sizeof(*dw9719), GFP_KERNEL); -+ if (!dw9719) -+ return -ENOMEM; -+ -+ dw9719->client = client; -+ dw9719->dev = &client->dev; -+ -+ dw9719->regulators[0].supply = "vdd"; -+ /* -+ * The DW9719 has only the 1 VDD voltage input, but some PMICs such as -+ * the TPS68470 PMIC have I2C passthrough capability, to disconnect the -+ * sensor's I2C pins from the I2C bus when the sensors VSIO (Sensor-IO) -+ * is off, because some sensors then short these pins to ground; -+ * and the DW9719 might sit behind this passthrough, this it needs to -+ * enable VSIO as that will also enable the I2C passthrough. -+ */ -+ dw9719->regulators[1].supply = "vsio"; -+ -+ ret = devm_regulator_bulk_get(&client->dev, NUM_REGULATORS, -+ dw9719->regulators); -+ if (ret) -+ return dev_err_probe(&client->dev, ret, "getting regulators\n"); -+ -+ v4l2_i2c_subdev_init(&dw9719->sd, client, &dw9719_ops); -+ dw9719->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -+ dw9719->sd.internal_ops = &dw9719_internal_ops; -+ -+ ret = dw9719_init_controls(dw9719); -+ if (ret) -+ return ret; -+ -+ ret = media_entity_pads_init(&dw9719->sd.entity, 0, NULL); -+ if (ret < 0) -+ goto err_free_ctrl_handler; -+ -+ dw9719->sd.entity.function = MEDIA_ENT_F_LENS; -+ -+ /* -+ * We need the driver to work in the event that pm runtime is disable in -+ * the kernel, so power up and verify the chip now. In the event that -+ * runtime pm is disabled this will leave the chip on, so that the lens -+ * will work. -+ */ -+ -+ ret = dw9719_power_up(dw9719); -+ if (ret) -+ goto err_cleanup_media; -+ -+ ret = dw9719_detect(dw9719); -+ if (ret) -+ goto err_powerdown; -+ -+ pm_runtime_set_active(&client->dev); -+ pm_runtime_get_noresume(&client->dev); -+ pm_runtime_enable(&client->dev); -+ -+ ret = v4l2_async_register_subdev(&dw9719->sd); ++ ret = dw9719_i2c_wr8(dw9719->client, DW9719_CONTROL, ++ DW9719_ENABLE_RINGING); + if (ret < 0) -+ goto err_pm_runtime; ++ goto fail_powerdown; + -+ pm_runtime_set_autosuspend_delay(&client->dev, 1000); -+ pm_runtime_use_autosuspend(&client->dev); -+ pm_runtime_put_autosuspend(&client->dev); ++ ret = dw9719_i2c_wr8(dw9719->client, DW9719_MODE, DW9719_MODE_SAC3); ++ if (ret < 0) ++ goto fail_powerdown; + -+ return ret; ++ ret = dw9719_i2c_wr8(dw9719->client, DW9719_VCM_FREQ, ++ DW9719_DEFAULT_VCM_FREQ); ++ if (ret < 0) ++ goto fail_powerdown; + -+err_pm_runtime: -+ pm_runtime_disable(&client->dev); -+ pm_runtime_put_noidle(&client->dev); -+err_powerdown: -+ dw9719_power_down(dw9719); -+err_cleanup_media: -+ media_entity_cleanup(&dw9719->sd.entity); -+err_free_ctrl_handler: -+ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); ++ return 0; + ++fail_powerdown: ++ dw9719_power_down(dw9719); + return ret; +} + -+static void dw9719_remove(struct i2c_client *client) ++static int dw9719_t_focus_abs(struct dw9719_device *dw9719, s32 value) +{ -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct dw9719_device *dw9719 = container_of(sd, struct dw9719_device, -+ sd); ++ int ret; + -+ pm_runtime_disable(&client->dev); -+ v4l2_async_unregister_subdev(sd); -+ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); -+ media_entity_cleanup(&dw9719->sd.entity); ++ value = clamp(value, 0, DW9719_MAX_FOCUS_POS); ++ ret = dw9719_i2c_wr16(dw9719->client, DW9719_VCM_CURRENT, value); ++ if (ret < 0) ++ return ret; ++ ++ return 0; +} + -+static const struct i2c_device_id dw9719_id_table[] = { -+ { "dw9719" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, dw9719_id_table); ++static int dw9719_set_ctrl(struct v4l2_ctrl *ctrl) ++{ ++ struct dw9719_device *dw9719 = container_of(ctrl->handler, ++ struct dw9719_device, ++ ctrls.handler); ++ int ret; + -+static const struct dev_pm_ops dw9719_pm_ops = { -+ SET_RUNTIME_PM_OPS(dw9719_suspend, dw9719_resume, NULL) -+}; ++ /* Only apply changes to the controls if the device is powered up */ ++ if (!pm_runtime_get_if_in_use(dw9719->dev)) ++ return 0; + -+static struct i2c_driver dw9719_i2c_driver = { -+ .driver = { -+ .name = "dw9719", -+ .pm = &dw9719_pm_ops, -+ }, -+ .probe_new = dw9719_probe, -+ .remove = dw9719_remove, -+ .id_table = dw9719_id_table, ++ switch (ctrl->id) { ++ case V4L2_CID_FOCUS_ABSOLUTE: ++ ret = dw9719_t_focus_abs(dw9719, ctrl->val); ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ pm_runtime_put(dw9719->dev); ++ ++ return ret; ++} ++ ++static const struct v4l2_ctrl_ops dw9719_ctrl_ops = { ++ .s_ctrl = dw9719_set_ctrl, +}; -+module_i2c_driver(dw9719_i2c_driver); + -+MODULE_AUTHOR("Daniel Scally "); -+MODULE_DESCRIPTION("DW9719 VCM Driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c -index 675fb37a6..43b30db08 100644 ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -1051,7 +1051,7 @@ static int ov7251_s_ctrl(struct v4l2_ctrl *ctrl) - case V4L2_CID_EXPOSURE: - ret = ov7251_set_exposure(ov7251, ctrl->val); - break; -- case V4L2_CID_GAIN: -+ case V4L2_CID_ANALOGUE_GAIN: - ret = ov7251_set_gain(ov7251, ctrl->val); - break; - case V4L2_CID_TEST_PATTERN: -@@ -1551,7 +1551,7 @@ static int ov7251_init_ctrls(struct ov7251 *ov7251) - ov7251->exposure = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_EXPOSURE, 1, 32, 1, 32); - ov7251->gain = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -- V4L2_CID_GAIN, 16, 1023, 1, 16); -+ V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 16); - v4l2_ctrl_new_std_menu_items(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(ov7251_test_pattern_menu) - 1, -diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -index 34984a747..67a44f6da 100644 ---- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -@@ -1385,7 +1385,10 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, - { - struct cio2_device *cio2 = to_cio2_device(notifier); - struct sensor_async_subdev *s_asd = to_sensor_asd(asd); -+ struct device *dev = &cio2->pci_dev->dev; - struct cio2_queue *q; -+ unsigned int pad; ++static int __maybe_unused dw9719_suspend(struct device *dev) ++{ ++ struct v4l2_subdev *sd = dev_get_drvdata(dev); ++ struct dw9719_device *dw9719 = to_dw9719_device(sd); + int ret; - - if (cio2->queue[s_asd->csi2.port].sensor) - return -EBUSY; -@@ -1396,7 +1399,26 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, - q->sensor = sd; - q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port); - -- return 0; -+ for (pad = 0; pad < q->sensor->entity.num_pads; pad++) -+ if (q->sensor->entity.pads[pad].flags & -+ MEDIA_PAD_FL_SOURCE) -+ break; ++ int val; + -+ if (pad == q->sensor->entity.num_pads) { -+ dev_err(dev, "failed to find src pad for %s\n", -+ q->sensor->name); -+ return -ENXIO; -+ } ++ for (val = dw9719->ctrls.focus->val; val >= 0; ++ val -= DW9719_CTRL_STEPS) { ++ ret = dw9719_t_focus_abs(dw9719, val); ++ if (ret) ++ return ret; + -+ ret = media_create_pad_link(&q->sensor->entity, pad, &q->subdev.entity, -+ CIO2_PAD_SINK, 0); -+ if (ret) { -+ dev_err(dev, "failed to create link for %s\n", -+ q->sensor->name); -+ return ret; ++ usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10); + } + -+ return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); - } - - /* The .unbind callback */ -@@ -1414,34 +1436,6 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier, - static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) - { - struct cio2_device *cio2 = to_cio2_device(notifier); -- struct device *dev = &cio2->pci_dev->dev; -- struct sensor_async_subdev *s_asd; -- struct v4l2_async_subdev *asd; -- struct cio2_queue *q; -- int ret; -- -- list_for_each_entry(asd, &cio2->notifier.asd_list, asd_list) { -- s_asd = to_sensor_asd(asd); -- q = &cio2->queue[s_asd->csi2.port]; -- -- ret = media_entity_get_fwnode_pad(&q->sensor->entity, -- s_asd->asd.match.fwnode, -- MEDIA_PAD_FL_SOURCE); -- if (ret < 0) { -- dev_err(dev, "no pad for endpoint %pfw (%d)\n", -- s_asd->asd.match.fwnode, ret); -- return ret; -- } -- -- ret = media_create_pad_link(&q->sensor->entity, ret, -- &q->subdev.entity, CIO2_PAD_SINK, -- 0); -- if (ret) { -- dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n", -- q->sensor->name, s_asd->asd.match.fwnode, ret); -- return ret; -- } -- } - - return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); - } -diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c -index b16b5f4cb..33739a979 100644 ---- a/drivers/media/v4l2-core/v4l2-async.c -+++ b/drivers/media/v4l2-core/v4l2-async.c -@@ -760,6 +760,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) - struct v4l2_async_notifier *notifier; - int ret; - -+ ret = v4l2_subdev_get_privacy_led(sd); -+ if (ret < 0) ++ return dw9719_power_down(dw9719); ++} ++ ++static int __maybe_unused dw9719_resume(struct device *dev) ++{ ++ struct v4l2_subdev *sd = dev_get_drvdata(dev); ++ struct dw9719_device *dw9719 = to_dw9719_device(sd); ++ int current_focus = dw9719->ctrls.focus->val; ++ int ret; ++ int val; ++ ++ ret = dw9719_power_up(dw9719); ++ if (ret) + return ret; + - /* - * No reference taken. The reference is held by the device - * (struct v4l2_subdev.dev), and async sub-device does not -diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c -index 049c2f200..f8c3e40b2 100644 ---- a/drivers/media/v4l2-core/v4l2-fwnode.c -+++ b/drivers/media/v4l2-core/v4l2-fwnode.c -@@ -1304,10 +1304,6 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd) - - v4l2_async_nf_init(notifier); - -- ret = v4l2_subdev_get_privacy_led(sd); -- if (ret < 0) -- goto out_cleanup; -- - ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); - if (ret < 0) - goto out_cleanup; -diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h -index bdc65d50b..08723c01d 100644 ---- a/drivers/misc/mei/hw-me-regs.h -+++ b/drivers/misc/mei/hw-me-regs.h -@@ -92,6 +92,7 @@ - #define MEI_DEV_ID_CDF 0x18D3 /* Cedar Fork */ - - #define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */ -+#define MEI_DEV_ID_ICP_LP_3 0x34E4 /* Ice Lake Point LP 3 (iTouch) */ - #define MEI_DEV_ID_ICP_N 0x38E0 /* Ice Lake Point N */ - - #define MEI_DEV_ID_JSP_N 0x4DE0 /* Jasper Lake Point N */ -diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c -index 676d566f3..6b37dd1f8 100644 ---- a/drivers/misc/mei/pci-me.c -+++ b/drivers/misc/mei/pci-me.c -@@ -97,6 +97,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = { - {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, -+ {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP_3, MEI_ME_PCH12_CFG)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, -diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c -index 6cdb225b7..19c036751 100644 ---- a/drivers/net/wireless/ath/ath10k/core.c -+++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -38,6 +38,9 @@ static bool fw_diag_log; - /* frame mode values are mapped as per enum ath10k_hw_txrx_mode */ - unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI; - -+static char *override_board = ""; -+static char *override_board2 = ""; ++ for (val = current_focus % DW9719_CTRL_STEPS; val < current_focus; ++ val += DW9719_CTRL_STEPS) { ++ ret = dw9719_t_focus_abs(dw9719, val); ++ if (ret) ++ goto err_power_down; ++ ++ usleep_range(DW9719_CTRL_DELAY_US, DW9719_CTRL_DELAY_US + 10); ++ } + - unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) | - BIT(ATH10K_FW_CRASH_DUMP_CE_DATA); - -@@ -50,6 +53,9 @@ module_param(fw_diag_log, bool, 0644); - module_param_named(frame_mode, ath10k_frame_mode, uint, 0644); - module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444); - -+module_param(override_board, charp, 0644); -+module_param(override_board2, charp, 0644); ++ return 0; + - MODULE_PARM_DESC(debug_mask, "Debugging mask"); - MODULE_PARM_DESC(uart_print, "Uart target debugging"); - MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); -@@ -59,6 +65,9 @@ MODULE_PARM_DESC(frame_mode, - MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); - MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); - -+MODULE_PARM_DESC(override_board, "Override for board.bin file"); -+MODULE_PARM_DESC(override_board2, "Override for board-2.bin file"); ++err_power_down: ++ dw9719_power_down(dw9719); ++ return ret; ++} + - static const struct ath10k_hw_params ath10k_hw_params_list[] = { - { - .id = QCA988X_HW_2_0_VERSION, -@@ -911,6 +920,42 @@ static int ath10k_init_configure_target(struct ath10k *ar) - return 0; - } - -+static const char *ath10k_override_board_fw_file(struct ath10k *ar, -+ const char *file) ++static int dw9719_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ -+ if (strcmp(file, "board.bin") == 0) { -+ if (strcmp(override_board, "") == 0) -+ return file; ++ return pm_runtime_resume_and_get(sd->dev); ++} + -+ if (strcmp(override_board, "none") == 0) { -+ dev_info(ar->dev, "firmware override: pretending 'board.bin' does not exist\n"); -+ return NULL; -+ } ++static int dw9719_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) ++{ ++ pm_runtime_put(sd->dev); + -+ dev_info(ar->dev, "firmware override: replacing 'board.bin' with '%s'\n", -+ override_board); ++ return 0; ++} + -+ return override_board; -+ } ++static const struct v4l2_subdev_internal_ops dw9719_internal_ops = { ++ .open = dw9719_open, ++ .close = dw9719_close, ++}; + -+ if (strcmp(file, "board-2.bin") == 0) { -+ if (strcmp(override_board2, "") == 0) -+ return file; ++static int dw9719_init_controls(struct dw9719_device *dw9719) ++{ ++ const struct v4l2_ctrl_ops *ops = &dw9719_ctrl_ops; ++ int ret; + -+ if (strcmp(override_board2, "none") == 0) { -+ dev_info(ar->dev, "firmware override: pretending 'board-2.bin' does not exist\n"); -+ return NULL; -+ } ++ ret = v4l2_ctrl_handler_init(&dw9719->ctrls.handler, 1); ++ if (ret) ++ return ret; + -+ dev_info(ar->dev, "firmware override: replacing 'board-2.bin' with '%s'\n", -+ override_board2); ++ dw9719->ctrls.focus = v4l2_ctrl_new_std(&dw9719->ctrls.handler, ops, ++ V4L2_CID_FOCUS_ABSOLUTE, 0, ++ DW9719_MAX_FOCUS_POS, 1, 0); + -+ return override_board2; ++ if (dw9719->ctrls.handler.error) { ++ dev_err(dw9719->dev, "Error initialising v4l2 ctrls\n"); ++ ret = dw9719->ctrls.handler.error; ++ goto err_free_handler; + } + -+ return file; ++ dw9719->sd.ctrl_handler = &dw9719->ctrls.handler; ++ ++ return ret; ++ ++err_free_handler: ++ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); ++ return ret; +} + - static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, - const char *dir, - const char *file) -@@ -925,6 +970,19 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, - if (dir == NULL) - dir = "."; - -+ /* HACK: Override board.bin and board-2.bin files if specified. -+ * -+ * Some Surface devices perform better with a different board -+ * configuration. To this end, one would need to replace the board.bin -+ * file with the modified config and remove the board-2.bin file. -+ * Unfortunately, that's not a solution that we can easily package. So -+ * we add module options to perform these overrides here. ++static const struct v4l2_subdev_ops dw9719_ops = { }; ++ ++static int dw9719_probe(struct i2c_client *client) ++{ ++ struct dw9719_device *dw9719; ++ int ret; ++ ++ dw9719 = devm_kzalloc(&client->dev, sizeof(*dw9719), GFP_KERNEL); ++ if (!dw9719) ++ return -ENOMEM; ++ ++ dw9719->client = client; ++ dw9719->dev = &client->dev; ++ ++ dw9719->regulators[0].supply = "vdd"; ++ /* ++ * The DW9719 has only the 1 VDD voltage input, but some PMICs such as ++ * the TPS68470 PMIC have I2C passthrough capability, to disconnect the ++ * sensor's I2C pins from the I2C bus when the sensors VSIO (Sensor-IO) ++ * is off, because some sensors then short these pins to ground; ++ * and the DW9719 might sit behind this passthrough, this it needs to ++ * enable VSIO as that will also enable the I2C passthrough. + */ ++ dw9719->regulators[1].supply = "vsio"; + -+ file = ath10k_override_board_fw_file(ar, file); -+ if (!file) -+ return ERR_PTR(-ENOENT); ++ ret = devm_regulator_bulk_get(&client->dev, NUM_REGULATORS, ++ dw9719->regulators); ++ if (ret) ++ return dev_err_probe(&client->dev, ret, "getting regulators\n"); + - snprintf(filename, sizeof(filename), "%s/%s", dir, file); - ret = firmware_request_nowarn(&fw, filename, ar->dev); - ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n", -diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index 9a698a16a..5e1a341f6 100644 ---- a/drivers/net/wireless/marvell/mwifiex/pcie.c -+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -368,6 +368,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) - { - struct pcie_service_card *card; -+ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); - int ret; ++ v4l2_i2c_subdev_init(&dw9719->sd, client, &dw9719_ops); ++ dw9719->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ dw9719->sd.internal_ops = &dw9719_internal_ops; ++ ++ ret = dw9719_init_controls(dw9719); ++ if (ret) ++ return ret; ++ ++ ret = media_entity_pads_init(&dw9719->sd.entity, 0, NULL); ++ if (ret < 0) ++ goto err_free_ctrl_handler; ++ ++ dw9719->sd.entity.function = MEDIA_ENT_F_LENS; ++ ++ /* ++ * We need the driver to work in the event that pm runtime is disable in ++ * the kernel, so power up and verify the chip now. In the event that ++ * runtime pm is disabled this will leave the chip on, so that the lens ++ * will work. ++ */ ++ ++ ret = dw9719_power_up(dw9719); ++ if (ret) ++ goto err_cleanup_media; ++ ++ ret = dw9719_detect(dw9719); ++ if (ret) ++ goto err_powerdown; ++ ++ pm_runtime_set_active(&client->dev); ++ pm_runtime_get_noresume(&client->dev); ++ pm_runtime_enable(&client->dev); ++ ++ ret = v4l2_async_register_subdev(&dw9719->sd); ++ if (ret < 0) ++ goto err_pm_runtime; ++ ++ pm_runtime_set_autosuspend_delay(&client->dev, 1000); ++ pm_runtime_use_autosuspend(&client->dev); ++ pm_runtime_put_autosuspend(&client->dev); ++ ++ return ret; ++ ++err_pm_runtime: ++ pm_runtime_disable(&client->dev); ++ pm_runtime_put_noidle(&client->dev); ++err_powerdown: ++ dw9719_power_down(dw9719); ++err_cleanup_media: ++ media_entity_cleanup(&dw9719->sd.entity); ++err_free_ctrl_handler: ++ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); ++ ++ return ret; ++} ++ ++static void dw9719_remove(struct i2c_client *client) ++{ ++ struct v4l2_subdev *sd = i2c_get_clientdata(client); ++ struct dw9719_device *dw9719 = container_of(sd, struct dw9719_device, ++ sd); ++ ++ pm_runtime_disable(&client->dev); ++ v4l2_async_unregister_subdev(sd); ++ v4l2_ctrl_handler_free(&dw9719->ctrls.handler); ++ media_entity_cleanup(&dw9719->sd.entity); ++} ++ ++static const struct i2c_device_id dw9719_id_table[] = { ++ { "dw9719" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(i2c, dw9719_id_table); ++ ++static const struct dev_pm_ops dw9719_pm_ops = { ++ SET_RUNTIME_PM_OPS(dw9719_suspend, dw9719_resume, NULL) ++}; ++ ++static struct i2c_driver dw9719_i2c_driver = { ++ .driver = { ++ .name = "dw9719", ++ .pm = &dw9719_pm_ops, ++ }, ++ .probe_new = dw9719_probe, ++ .remove = dw9719_remove, ++ .id_table = dw9719_id_table, ++}; ++module_i2c_driver(dw9719_i2c_driver); ++ ++MODULE_AUTHOR("Daniel Scally "); ++MODULE_DESCRIPTION("DW9719 VCM Driver"); ++MODULE_LICENSE("GPL"); +-- +2.42.0 + +From c5d772b1854f0ac07aa20ba39e7e0d513c14cd2a Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Fri, 15 Jul 2022 23:48:00 +0200 +Subject: [PATCH] drivers/media/i2c: Fix DW9719 dependencies + +It should depend on VIDEO_DEV instead of VIDEO_V4L2. + +Signed-off-by: Maximilian Luz +Patchset: cameras +--- + drivers/media/i2c/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig +index 6959ee1a89fb..1d5082fe9ce3 100644 +--- a/drivers/media/i2c/Kconfig ++++ b/drivers/media/i2c/Kconfig +@@ -857,7 +857,7 @@ config VIDEO_DW9714 - pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", -@@ -409,6 +410,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, - return -1; + config VIDEO_DW9719 + tristate "DW9719 lens voice coil support" +- depends on I2C && VIDEO_V4L2 ++ depends on I2C && VIDEO_DEV + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC +-- +2.42.0 + +From a91910f04221481012703436c3e821a54332beee Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Thu, 2 Mar 2023 12:59:39 +0000 +Subject: [PATCH] platform/x86: int3472: Remap reset GPIO for INT347E + +ACPI _HID INT347E represents the OmniVision 7251 camera sensor. The +driver for this sensor expects a single pin named "enable", but on +some Microsoft Surface platforms the sensor is assigned a single +GPIO who's type flag is INT3472_GPIO_TYPE_RESET. + +Remap the GPIO pin's function from "reset" to "enable". This is done +outside of the existing remap table since it is a more widespread +discrepancy than that method is designed for. Additionally swap the +polarity of the pin to match the driver's expectation. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/platform/x86/intel/int3472/discrete.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c +index e33c2d75975c..c0c90ae66b70 100644 +--- a/drivers/platform/x86/intel/int3472/discrete.c ++++ b/drivers/platform/x86/intel/int3472/discrete.c +@@ -57,6 +57,9 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 + const char *func, u32 polarity) + { + char *path = agpio->resource_source.string_ptr; ++ const struct acpi_device_id ov7251_ids[] = { ++ { "INT347E" }, ++ }; + struct gpiod_lookup *table_entry; + struct acpi_device *adev; + acpi_handle handle; +@@ -67,6 +70,17 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 + return -EINVAL; } -+ /* disable bridge_d3 for Surface gen4+ devices to fix fw crashing -+ * after suspend ++ /* ++ * In addition to the function remap table we need to bulk remap the ++ * "reset" GPIO for the OmniVision 7251 sensor, as the driver for that ++ * expects its only GPIO pin to be called "enable" (and to have the ++ * opposite polarity). + */ -+ if (card->quirks & QUIRK_NO_BRIDGE_D3) -+ parent_pdev->bridge_d3 = false; ++ if (!strcmp(func, "reset") && !acpi_match_device_ids(int3472->sensor, ov7251_ids)) { ++ func = "enable"; ++ polarity = GPIO_ACTIVE_HIGH; ++ } + - return 0; - } - -@@ -1762,9 +1769,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) - static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) - { - struct pcie_service_card *card = adapter->card; -+ struct pci_dev *pdev = card->dev; -+ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev); - const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask; + status = acpi_get_handle(NULL, path, &handle); + if (ACPI_FAILURE(status)) + return -EINVAL; +-- +2.42.0 + +From e33de4cf8fa02ac63ceb16f3f860ddfae8ea8726 Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Tue, 21 Mar 2023 13:45:26 +0000 +Subject: [PATCH] media: i2c: Clarify that gain is Analogue gain in OV7251 + +Update the control ID for the gain control in the ov7251 driver to +V4L2_CID_ANALOGUE_GAIN. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/media/i2c/ov7251.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c +index 675fb37a6fea..43b30db08c9e 100644 +--- a/drivers/media/i2c/ov7251.c ++++ b/drivers/media/i2c/ov7251.c +@@ -1051,7 +1051,7 @@ static int ov7251_s_ctrl(struct v4l2_ctrl *ctrl) + case V4L2_CID_EXPOSURE: + ret = ov7251_set_exposure(ov7251, ctrl->val); + break; +- case V4L2_CID_GAIN: ++ case V4L2_CID_ANALOGUE_GAIN: + ret = ov7251_set_gain(ov7251, ctrl->val); + break; + case V4L2_CID_TEST_PATTERN: +@@ -1551,7 +1551,7 @@ static int ov7251_init_ctrls(struct ov7251 *ov7251) + ov7251->exposure = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, + V4L2_CID_EXPOSURE, 1, 32, 1, 32); + ov7251->gain = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, +- V4L2_CID_GAIN, 16, 1023, 1, 16); ++ V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 16); + v4l2_ctrl_new_std_menu_items(&ov7251->ctrls, &ov7251_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(ov7251_test_pattern_menu) - 1, +-- +2.42.0 + +From 4c3f0ec8d169cd6114990df67b3bb43dc351f951 Mon Sep 17 00:00:00 2001 +From: Daniel Scally +Date: Wed, 22 Mar 2023 11:01:42 +0000 +Subject: [PATCH] media: v4l2-core: Acquire privacy led in + v4l2_async_register_subdev() + +The current call to v4l2_subdev_get_privacy_led() is contained in +v4l2_async_register_subdev_sensor(), but that function isn't used by +all the sensor drivers. Move the acquisition of the privacy led to +v4l2_async_register_subdev() instead. + +Signed-off-by: Daniel Scally +Patchset: cameras +--- + drivers/media/v4l2-core/v4l2-async.c | 4 ++++ + drivers/media/v4l2-core/v4l2-fwnode.c | 4 ---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c +index b16b5f4cb91e..33739a979cbc 100644 +--- a/drivers/media/v4l2-core/v4l2-async.c ++++ b/drivers/media/v4l2-core/v4l2-async.c +@@ -760,6 +760,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) + struct v4l2_async_notifier *notifier; + int ret; -+ /* Trigger a function level reset of the PCI bridge device, this makes -+ * the firmware of PCIe 88W8897 cards stop reporting a fixed LTR value -+ * that prevents the system from entering package C10 and S0ix powersaving -+ * states. -+ * We need to do it here because it must happen after firmware -+ * initialization and this function is called after that is done. -+ */ -+ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE) -+ pci_reset_function(parent_pdev); ++ ret = v4l2_subdev_get_privacy_led(sd); ++ if (ret < 0) ++ return ret; + - /* Write the RX ring read pointer in to reg->rx_rdptr */ - if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr | - tx_wrap)) { -diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -index dd6d21f1d..99b024ecb 100644 ---- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -@@ -13,7 +13,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Pro 5", -@@ -22,7 +24,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Pro 5 (LTE)", -@@ -31,7 +35,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Pro 6", -@@ -39,7 +45,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Book 1", -@@ -47,7 +55,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Book 2", -@@ -55,7 +65,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Laptop 1", -@@ -63,7 +75,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - { - .ident = "Surface Laptop 2", -@@ -71,7 +85,9 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"), - }, -- .driver_data = (void *)QUIRK_FW_RST_D3COLD, -+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD | -+ QUIRK_DO_FLR_ON_BRIDGE | -+ QUIRK_NO_BRIDGE_D3), - }, - {} - }; -@@ -89,6 +105,11 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) - dev_info(&pdev->dev, "no quirks enabled\n"); - if (card->quirks & QUIRK_FW_RST_D3COLD) - dev_info(&pdev->dev, "quirk reset_d3cold enabled\n"); -+ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE) -+ dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n"); -+ if (card->quirks & QUIRK_NO_BRIDGE_D3) -+ dev_info(&pdev->dev, -+ "quirk no_brigde_d3 enabled\n"); - } + /* + * No reference taken. The reference is held by the device + * (struct v4l2_subdev.dev), and async sub-device does not +diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c +index 4fa9225aa3d9..ed4c75253cbc 100644 +--- a/drivers/media/v4l2-core/v4l2-fwnode.c ++++ b/drivers/media/v4l2-core/v4l2-fwnode.c +@@ -1314,10 +1314,6 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd) - static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) -diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -index d6ff964ae..c14eb56eb 100644 ---- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -@@ -4,6 +4,8 @@ - #include "pcie.h" + v4l2_async_nf_init(notifier); - #define QUIRK_FW_RST_D3COLD BIT(0) -+#define QUIRK_DO_FLR_ON_BRIDGE BIT(1) -+#define QUIRK_NO_BRIDGE_D3 BIT(2) +- ret = v4l2_subdev_get_privacy_led(sd); +- if (ret < 0) +- goto out_cleanup; +- + ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); + if (ret < 0) + goto out_cleanup; +-- +2.42.0 + +From 6d72225fd0eefb1e15f645d404dfa31873ce5a8b Mon Sep 17 00:00:00 2001 +From: Kate Hsuan +Date: Tue, 21 Mar 2023 23:37:16 +0800 +Subject: [PATCH] platform: x86: int3472: Add MFD cell for tps68470 LED + +Add MFD cell for tps68470-led. + +Reviewed-by: Daniel Scally +Signed-off-by: Kate Hsuan +Reviewed-by: Hans de Goede +Patchset: cameras +--- + drivers/platform/x86/intel/int3472/tps68470.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c +index e3e1696e7f0e..423dc555093f 100644 +--- a/drivers/platform/x86/intel/int3472/tps68470.c ++++ b/drivers/platform/x86/intel/int3472/tps68470.c +@@ -17,7 +17,7 @@ + #define DESIGNED_FOR_CHROMEOS 1 + #define DESIGNED_FOR_WINDOWS 2 - void mwifiex_initialize_quirks(struct pcie_service_card *card); - int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); -diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c -index 55648c5fe..f1402fc70 100644 ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -514,6 +514,9 @@ static void pci_device_shutdown(struct device *dev) - struct pci_dev *pci_dev = to_pci_dev(dev); - struct pci_driver *drv = pci_dev->driver; +-#define TPS68470_WIN_MFD_CELL_COUNT 3 ++#define TPS68470_WIN_MFD_CELL_COUNT 4 -+ if (pci_dev->no_shutdown) -+ return; -+ - pm_runtime_resume(dev); + static const struct mfd_cell tps68470_cros[] = { + { .name = "tps68470-gpio" }, +@@ -200,7 +200,8 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) + cells[1].name = "tps68470-regulator"; + cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata; + cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data); +- cells[2].name = "tps68470-gpio"; ++ cells[2].name = "tps68470-led"; ++ cells[3].name = "tps68470-gpio"; + + for (i = 0; i < board_data->n_gpiod_lookups; i++) + gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_tables[i]); +-- +2.42.0 + +From 591153826d40ce4d57f2d5c4fb133e36ac187c8e Mon Sep 17 00:00:00 2001 +From: Kate Hsuan +Date: Tue, 21 Mar 2023 23:37:17 +0800 +Subject: [PATCH] include: mfd: tps68470: Add masks for LEDA and LEDB + +Add flags for both LEDA(TPS68470_ILEDCTL_ENA), LEDB +(TPS68470_ILEDCTL_ENB), and current control mask for LEDB +(TPS68470_ILEDCTL_CTRLB) + +Reviewed-by: Daniel Scally +Reviewed-by: Hans de Goede +Signed-off-by: Kate Hsuan +Patchset: cameras +--- + include/linux/mfd/tps68470.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h +index 7807fa329db0..2d2abb25b944 100644 +--- a/include/linux/mfd/tps68470.h ++++ b/include/linux/mfd/tps68470.h +@@ -34,6 +34,7 @@ + #define TPS68470_REG_SGPO 0x22 + #define TPS68470_REG_GPDI 0x26 + #define TPS68470_REG_GPDO 0x27 ++#define TPS68470_REG_ILEDCTL 0x28 + #define TPS68470_REG_VCMVAL 0x3C + #define TPS68470_REG_VAUX1VAL 0x3D + #define TPS68470_REG_VAUX2VAL 0x3E +@@ -94,4 +95,8 @@ + #define TPS68470_GPIO_MODE_OUT_CMOS 2 + #define TPS68470_GPIO_MODE_OUT_ODRAIN 3 - if (drv && drv->shutdown) -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index fc399e56e..f0dbe43d6 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -6162,3 +6162,39 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2d, dpc_log_size); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a2f, dpc_log_size); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); - #endif -+ -+static const struct dmi_system_id no_shutdown_dmi_table[] = { -+ /* -+ * Systems on which some devices should not be touched during shutdown. -+ */ -+ { -+ .ident = "Microsoft Surface Pro 9", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Pro 9"), -+ }, -+ }, -+ { -+ .ident = "Microsoft Surface Laptop 5", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 5"), -+ }, -+ }, -+ {} -+}; -+ -+static void quirk_no_shutdown(struct pci_dev *dev) -+{ -+ if (!dmi_check_system(no_shutdown_dmi_table)) -+ return; ++#define TPS68470_ILEDCTL_ENA BIT(2) ++#define TPS68470_ILEDCTL_ENB BIT(6) ++#define TPS68470_ILEDCTL_CTRLB GENMASK(5, 4) + -+ dev->no_shutdown = 1; -+ pci_info(dev, "disabling shutdown ops for [%04x:%04x]\n", -+ dev->vendor, dev->device); -+} -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461e, quirk_no_shutdown); // Thunderbolt 4 USB Controller -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x461f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x462f, quirk_no_shutdown); // Thunderbolt 4 PCI Express Root Port -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x466d, quirk_no_shutdown); // Thunderbolt 4 NHI -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x46a8, quirk_no_shutdown); // GPU -diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig -index b629e82af..68656e8f3 100644 ---- a/drivers/platform/surface/Kconfig -+++ b/drivers/platform/surface/Kconfig -@@ -149,6 +149,13 @@ config SURFACE_AGGREGATOR_TABLET_SWITCH - Select M or Y here, if you want to provide tablet-mode switch input - events on the Surface Pro 8, Surface Pro X, and Surface Laptop Studio. + #endif /* __LINUX_MFD_TPS68470_H */ +-- +2.42.0 + +From 8c8c933fccb6d380bc2dc81625ca4419c826656d Mon Sep 17 00:00:00 2001 +From: Kate Hsuan +Date: Tue, 21 Mar 2023 23:37:18 +0800 +Subject: [PATCH] leds: tps68470: Add LED control for tps68470 + +There are two LED controllers, LEDA indicator LED and LEDB flash LED for +tps68470. LEDA can be enabled by setting TPS68470_ILEDCTL_ENA. Moreover, +tps68470 provides four levels of power status for LEDB. If the +properties called "ti,ledb-current" can be found, the current will be +set according to the property values. These two LEDs can be controlled +through the LED class of sysfs (tps68470-leda and tps68470-ledb). + +Signed-off-by: Kate Hsuan +Reviewed-by: Hans de Goede +Patchset: cameras +--- + drivers/leds/Kconfig | 12 +++ + drivers/leds/Makefile | 1 + + drivers/leds/leds-tps68470.c | 185 +++++++++++++++++++++++++++++++++++ + 3 files changed, 198 insertions(+) + create mode 100644 drivers/leds/leds-tps68470.c + +diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig +index 6046dfeca16f..385c06e4f1d3 100644 +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -864,6 +864,18 @@ config LEDS_TPS6105X + It is a single boost converter primarily for white LEDs and + audio amplifiers. -+config SURFACE_BOOK1_DGPU_SWITCH -+ tristate "Surface Book 1 dGPU Switch Driver" -+ depends on SYSFS ++config LEDS_TPS68470 ++ tristate "LED support for TI TPS68470" ++ depends on LEDS_CLASS ++ depends on INTEL_SKL_INT3472 + help -+ This driver provides a sysfs switch to set the power-state of the -+ discrete GPU found on the Microsoft Surface Book 1. ++ This driver supports TPS68470 PMIC with LED chip. ++ It provides two LED controllers, with the ability to drive 2 ++ indicator LEDs and 2 flash LEDs. + - config SURFACE_DTX - tristate "Surface DTX (Detachment System) Driver" - depends on SURFACE_AGGREGATOR -diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile -index 533443309..7efcd0cdb 100644 ---- a/drivers/platform/surface/Makefile -+++ b/drivers/platform/surface/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o - obj-$(CONFIG_SURFACE_AGGREGATOR_HUB) += surface_aggregator_hub.o - obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o - obj-$(CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH) += surface_aggregator_tabletsw.o -+obj-$(CONFIG_SURFACE_BOOK1_DGPU_SWITCH) += surfacebook1_dgpu_switch.o - obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o - obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o - obj-$(CONFIG_SURFACE_HOTPLUG) += surface_hotplug.o -diff --git a/drivers/platform/surface/surface3-wmi.c b/drivers/platform/surface/surface3-wmi.c -index ca4602bcc..490b97310 100644 ---- a/drivers/platform/surface/surface3-wmi.c -+++ b/drivers/platform/surface/surface3-wmi.c -@@ -37,6 +37,13 @@ static const struct dmi_system_id surface3_dmi_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), - }, - }, -+ { -+ .matches = { -+ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), -+ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), -+ }, -+ }, - #endif - { } - }; -diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c -index c219b840d..69c4352e8 100644 ---- a/drivers/platform/surface/surface_gpe.c -+++ b/drivers/platform/surface/surface_gpe.c -@@ -41,6 +41,11 @@ static const struct property_entry lid_device_props_l4F[] = { - {}, - }; - -+static const struct property_entry lid_device_props_l52[] = { -+ PROPERTY_ENTRY_U32("gpe", 0x52), -+ {}, -+}; ++ To compile this driver as a module, choose M and it will be ++ called leds-tps68470 + - static const struct property_entry lid_device_props_l57[] = { - PROPERTY_ENTRY_U32("gpe", 0x57), - {}, -@@ -107,6 +112,18 @@ static const struct dmi_system_id dmi_lid_device_table[] = { - }, - .driver_data = (void *)lid_device_props_l4B, - }, -+ { -+ /* -+ * We match for SKU here due to product name clash with the ARM -+ * version. -+ */ -+ .ident = "Surface Pro 9", -+ .matches = { -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_9_2038"), -+ }, -+ .driver_data = (void *)lid_device_props_l52, -+ }, - { - .ident = "Surface Book 1", - .matches = { -diff --git a/drivers/platform/surface/surfacebook1_dgpu_switch.c b/drivers/platform/surface/surfacebook1_dgpu_switch.c + config LEDS_IP30 + tristate "LED support for SGI Octane machines" + depends on LEDS_CLASS +diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile +index d71f1226540c..e2002b535967 100644 +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -83,6 +83,7 @@ obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o + obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o + obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o + obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o ++obj-$(CONFIG_LEDS_TPS68470) += leds-tps68470.o + obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o + obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o + obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o +diff --git a/drivers/leds/leds-tps68470.c b/drivers/leds/leds-tps68470.c new file mode 100644 -index 000000000..8b816ed8f +index 000000000000..35aeb5db89c8 --- /dev/null -+++ b/drivers/platform/surface/surfacebook1_dgpu_switch.c -@@ -0,0 +1,162 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later ++++ b/drivers/leds/leds-tps68470.c +@@ -0,0 +1,185 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * LED driver for TPS68470 PMIC ++ * ++ * Copyright (C) 2023 Red Hat ++ * ++ * Authors: ++ * Kate Hsuan ++ */ + -+#include ++#include ++#include +#include -+#include +#include ++#include ++#include + + -+#ifdef pr_fmt -+#undef pr_fmt -+#endif -+#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ -+ -+ -+static const guid_t dgpu_sw_guid = GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, -+ 0x95, 0xed, 0xab, 0x16, 0x65, 0x49, 0x80, 0x35); -+ -+#define DGPUSW_ACPI_PATH_DSM "\\_SB_.PCI0.LPCB.EC0_.VGBI" -+#define DGPUSW_ACPI_PATH_HGON "\\_SB_.PCI0.RP05.HGON" -+#define DGPUSW_ACPI_PATH_HGOF "\\_SB_.PCI0.RP05.HGOF" -+ -+ -+static int sb1_dgpu_sw_dsmcall(void) -+{ -+ union acpi_object *ret; -+ acpi_handle handle; -+ acpi_status status; -+ -+ status = acpi_get_handle(NULL, DGPUSW_ACPI_PATH_DSM, &handle); -+ if (status) -+ return -EINVAL; ++#define lcdev_to_led(led_cdev) \ ++ container_of(led_cdev, struct tps68470_led, lcdev) + -+ ret = acpi_evaluate_dsm_typed(handle, &dgpu_sw_guid, 1, 1, NULL, ACPI_TYPE_BUFFER); -+ if (!ret) -+ return -EINVAL; ++#define led_to_tps68470(led, index) \ ++ container_of(led, struct tps68470_device, leds[index]) + -+ ACPI_FREE(ret); -+ return 0; -+} ++enum tps68470_led_ids { ++ TPS68470_ILED_A, ++ TPS68470_ILED_B, ++ TPS68470_NUM_LEDS ++}; + -+static int sb1_dgpu_sw_hgon(void) -+{ -+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; -+ acpi_status status; ++static const char *tps68470_led_names[] = { ++ [TPS68470_ILED_A] = "tps68470-iled_a", ++ [TPS68470_ILED_B] = "tps68470-iled_b", ++}; + -+ status = acpi_evaluate_object(NULL, DGPUSW_ACPI_PATH_HGON, NULL, &buf); -+ if (status) { -+ pr_err("failed to run HGON: %d\n", status); -+ return -EINVAL; -+ } ++struct tps68470_led { ++ unsigned int led_id; ++ struct led_classdev lcdev; ++}; + -+ if (buf.pointer) -+ ACPI_FREE(buf.pointer); ++struct tps68470_device { ++ struct device *dev; ++ struct regmap *regmap; ++ struct tps68470_led leds[TPS68470_NUM_LEDS]; ++}; + -+ pr_info("turned-on dGPU via HGON\n"); -+ return 0; -+} ++enum ctrlb_current { ++ CTRLB_2MA = 0, ++ CTRLB_4MA = 1, ++ CTRLB_8MA = 2, ++ CTRLB_16MA = 3, ++}; + -+static int sb1_dgpu_sw_hgof(void) ++static int tps68470_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) +{ -+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; -+ acpi_status status; ++ struct tps68470_led *led = lcdev_to_led(led_cdev); ++ struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id); ++ struct regmap *regmap = tps68470->regmap; + -+ status = acpi_evaluate_object(NULL, DGPUSW_ACPI_PATH_HGOF, NULL, &buf); -+ if (status) { -+ pr_err("failed to run HGOF: %d\n", status); -+ return -EINVAL; ++ switch (led->led_id) { ++ case TPS68470_ILED_A: ++ return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENA, ++ brightness ? TPS68470_ILEDCTL_ENA : 0); ++ case TPS68470_ILED_B: ++ return regmap_update_bits(regmap, TPS68470_REG_ILEDCTL, TPS68470_ILEDCTL_ENB, ++ brightness ? TPS68470_ILEDCTL_ENB : 0); + } -+ -+ if (buf.pointer) -+ ACPI_FREE(buf.pointer); -+ -+ pr_info("turned-off dGPU via HGOF\n"); -+ return 0; ++ return -EINVAL; +} + -+ -+static ssize_t dgpu_dsmcall_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t len) ++static enum led_brightness tps68470_brightness_get(struct led_classdev *led_cdev) +{ -+ int status, value; -+ -+ status = kstrtoint(buf, 0, &value); -+ if (status < 0) -+ return status; ++ struct tps68470_led *led = lcdev_to_led(led_cdev); ++ struct tps68470_device *tps68470 = led_to_tps68470(led, led->led_id); ++ struct regmap *regmap = tps68470->regmap; ++ int ret = 0; ++ int value = 0; + -+ if (value != 1) -+ return -EINVAL; ++ ret = regmap_read(regmap, TPS68470_REG_ILEDCTL, &value); ++ if (ret) ++ return dev_err_probe(led_cdev->dev, -EINVAL, "failed on reading register\n"); + -+ status = sb1_dgpu_sw_dsmcall(); ++ switch (led->led_id) { ++ case TPS68470_ILED_A: ++ value = value & TPS68470_ILEDCTL_ENA; ++ break; ++ case TPS68470_ILED_B: ++ value = value & TPS68470_ILEDCTL_ENB; ++ break; ++ } + -+ return status < 0 ? status : len; ++ return value ? LED_ON : LED_OFF; +} + -+static ssize_t dgpu_power_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t len) -+{ -+ bool power; -+ int status; -+ -+ status = kstrtobool(buf, &power); -+ if (status < 0) -+ return status; + -+ if (power) -+ status = sb1_dgpu_sw_hgon(); -+ else -+ status = sb1_dgpu_sw_hgof(); ++static int tps68470_ledb_current_init(struct platform_device *pdev, ++ struct tps68470_device *tps68470) ++{ ++ int ret = 0; ++ unsigned int curr; + -+ return status < 0 ? status : len; ++ /* configure LEDB current if the properties can be got */ ++ if (!device_property_read_u32(&pdev->dev, "ti,ledb-current", &curr)) { ++ if (curr > CTRLB_16MA) { ++ dev_err(&pdev->dev, ++ "Invalid LEDB current value: %d\n", ++ curr); ++ return -EINVAL; ++ } ++ ret = regmap_update_bits(tps68470->regmap, TPS68470_REG_ILEDCTL, ++ TPS68470_ILEDCTL_CTRLB, curr); ++ } ++ return ret; +} + -+static DEVICE_ATTR_WO(dgpu_dsmcall); -+static DEVICE_ATTR_WO(dgpu_power); -+ -+static struct attribute *sb1_dgpu_sw_attrs[] = { -+ &dev_attr_dgpu_dsmcall.attr, -+ &dev_attr_dgpu_power.attr, -+ NULL, -+}; -+ -+static const struct attribute_group sb1_dgpu_sw_attr_group = { -+ .attrs = sb1_dgpu_sw_attrs, -+}; ++static int tps68470_leds_probe(struct platform_device *pdev) ++{ ++ int i = 0; ++ int ret = 0; ++ struct tps68470_device *tps68470; ++ struct tps68470_led *led; ++ struct led_classdev *lcdev; + ++ tps68470 = devm_kzalloc(&pdev->dev, sizeof(struct tps68470_device), ++ GFP_KERNEL); ++ if (!tps68470) ++ return -ENOMEM; + -+static int sb1_dgpu_sw_probe(struct platform_device *pdev) -+{ -+ return sysfs_create_group(&pdev->dev.kobj, &sb1_dgpu_sw_attr_group); -+} ++ tps68470->dev = &pdev->dev; ++ tps68470->regmap = dev_get_drvdata(pdev->dev.parent); + -+static int sb1_dgpu_sw_remove(struct platform_device *pdev) -+{ -+ sysfs_remove_group(&pdev->dev.kobj, &sb1_dgpu_sw_attr_group); -+ return 0; -+} ++ for (i = 0; i < TPS68470_NUM_LEDS; i++) { ++ led = &tps68470->leds[i]; ++ lcdev = &led->lcdev; + -+/* -+ * The dGPU power seems to be actually handled by MSHW0040. However, that is -+ * also the power-/volume-button device with a mainline driver. So let's use -+ * MSHW0041 instead for now, which seems to be the LTCH (latch/DTX) device. -+ */ -+static const struct acpi_device_id sb1_dgpu_sw_match[] = { -+ { "MSHW0041", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(acpi, sb1_dgpu_sw_match); ++ led->led_id = i; + -+static struct platform_driver sb1_dgpu_sw = { -+ .probe = sb1_dgpu_sw_probe, -+ .remove = sb1_dgpu_sw_remove, -+ .driver = { -+ .name = "surfacebook1_dgpu_switch", -+ .acpi_match_table = sb1_dgpu_sw_match, -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS, -+ }, -+}; -+module_platform_driver(sb1_dgpu_sw); ++ lcdev->name = devm_kasprintf(tps68470->dev, GFP_KERNEL, "%s::%s", ++ tps68470_led_names[i], LED_FUNCTION_INDICATOR); ++ if (!lcdev->name) ++ return -ENOMEM; + -+MODULE_AUTHOR("Maximilian Luz "); -+MODULE_DESCRIPTION("Discrete GPU Power-Switch for Surface Book 1"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/platform/surface/surfacepro3_button.c b/drivers/platform/surface/surfacepro3_button.c -index 2755601f9..4240c98ca 100644 ---- a/drivers/platform/surface/surfacepro3_button.c -+++ b/drivers/platform/surface/surfacepro3_button.c -@@ -149,7 +149,8 @@ static int surface_button_resume(struct device *dev) - /* - * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device - * ID (MSHW0040) for the power/volume buttons. Make sure this is the right -- * device by checking for the _DSM method and OEM Platform Revision. -+ * device by checking for the _DSM method and OEM Platform Revision DSM -+ * function. - * - * Returns true if the driver should bind to this device, i.e. the device is - * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1. -@@ -157,30 +158,11 @@ static int surface_button_resume(struct device *dev) - static bool surface_button_check_MSHW0040(struct acpi_device *dev) - { - acpi_handle handle = dev->handle; -- union acpi_object *result; -- u64 oem_platform_rev = 0; // valid revisions are nonzero -- -- // get OEM platform revision -- result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID, -- MSHW0040_DSM_REVISION, -- MSHW0040_DSM_GET_OMPR, -- NULL, ACPI_TYPE_INTEGER); -- -- /* -- * If evaluating the _DSM fails, the method is not present. This means -- * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we -- * should use this driver. We use revision 0 indicating it is -- * unavailable. -- */ -- -- if (result) { -- oem_platform_rev = result->integer.value; -- ACPI_FREE(result); -- } -- -- dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev); - -- return oem_platform_rev == 0; -+ // make sure that OEM platform revision DSM call does not exist -+ return !acpi_check_dsm(handle, &MSHW0040_DSM_UUID, -+ MSHW0040_DSM_REVISION, -+ BIT(MSHW0040_DSM_GET_OMPR)); - } - - -diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c -index e33c2d759..c0c90ae66 100644 ---- a/drivers/platform/x86/intel/int3472/discrete.c -+++ b/drivers/platform/x86/intel/int3472/discrete.c -@@ -57,6 +57,9 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 - const char *func, u32 polarity) - { - char *path = agpio->resource_source.string_ptr; -+ const struct acpi_device_id ov7251_ids[] = { -+ { "INT347E" }, -+ }; - struct gpiod_lookup *table_entry; - struct acpi_device *adev; - acpi_handle handle; -@@ -67,6 +70,17 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 - return -EINVAL; - } - -+ /* -+ * In addition to the function remap table we need to bulk remap the -+ * "reset" GPIO for the OmniVision 7251 sensor, as the driver for that -+ * expects its only GPIO pin to be called "enable" (and to have the -+ * opposite polarity). -+ */ -+ if (!strcmp(func, "reset") && !acpi_match_device_ids(int3472->sensor, ov7251_ids)) { -+ func = "enable"; -+ polarity = GPIO_ACTIVE_HIGH; -+ } ++ lcdev->max_brightness = 1; ++ lcdev->brightness = 0; ++ lcdev->brightness_set_blocking = tps68470_brightness_set; ++ lcdev->brightness_get = tps68470_brightness_get; ++ lcdev->dev = &pdev->dev; + - status = acpi_get_handle(NULL, path, &handle); - if (ACPI_FAILURE(status)) - return -EINVAL; -diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c -index 1e107fd49..423dc5550 100644 ---- a/drivers/platform/x86/intel/int3472/tps68470.c -+++ b/drivers/platform/x86/intel/int3472/tps68470.c -@@ -17,7 +17,7 @@ - #define DESIGNED_FOR_CHROMEOS 1 - #define DESIGNED_FOR_WINDOWS 2 - --#define TPS68470_WIN_MFD_CELL_COUNT 3 -+#define TPS68470_WIN_MFD_CELL_COUNT 4 - - static const struct mfd_cell tps68470_cros[] = { - { .name = "tps68470-gpio" }, -@@ -46,6 +46,13 @@ static int tps68470_chip_init(struct device *dev, struct regmap *regmap) - return ret; - } - -+ /* Enable I2C daisy chain */ -+ ret = regmap_write(regmap, TPS68470_REG_S_I2C_CTL, 0x03); ++ ret = devm_led_classdev_register(tps68470->dev, lcdev); ++ if (ret) { ++ dev_err_probe(tps68470->dev, ret, ++ "error registering led\n"); ++ goto err_exit; ++ } ++ ++ if (i == TPS68470_ILED_B) { ++ ret = tps68470_ledb_current_init(pdev, tps68470); ++ if (ret) ++ goto err_exit; ++ } ++ } ++ ++err_exit: + if (ret) { -+ dev_err(dev, "Failed to enable i2c daisy chain\n"); -+ return ret; ++ for (i = 0; i < TPS68470_NUM_LEDS; i++) { ++ if (tps68470->leds[i].lcdev.name) ++ devm_led_classdev_unregister(&pdev->dev, ++ &tps68470->leds[i].lcdev); ++ } + } + - dev_info(dev, "TPS68470 REVID: 0x%02x\n", version); - - return 0; -@@ -193,7 +200,8 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) - cells[1].name = "tps68470-regulator"; - cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata; - cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data); -- cells[2].name = "tps68470-gpio"; -+ cells[2].name = "tps68470-led"; -+ cells[3].name = "tps68470-gpio"; - - for (i = 0; i < board_data->n_gpiod_lookups; i++) - gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_tables[i]); -diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c -index 15e9bd180..0d70461d0 100644 ---- a/drivers/usb/core/quirks.c -+++ b/drivers/usb/core/quirks.c -@@ -220,6 +220,9 @@ static const struct usb_device_id usb_quirk_list[] = { - /* Microsoft Surface Dock Ethernet (RTL8153 GigE) */ - { USB_DEVICE(0x045e, 0x07c6), .driver_info = USB_QUIRK_NO_LPM }, - -+ /* Microsoft Surface Go 3 Type-Cover */ -+ { USB_DEVICE(0x045e, 0x09b5), .driver_info = USB_QUIRK_DELAY_INIT }, ++ return ret; ++} ++static struct platform_driver tps68470_led_driver = { ++ .driver = { ++ .name = "tps68470-led", ++ }, ++ .probe = tps68470_leds_probe, ++}; + - /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */ - { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME }, - -diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h -index 7807fa329..2d2abb25b 100644 ---- a/include/linux/mfd/tps68470.h -+++ b/include/linux/mfd/tps68470.h -@@ -34,6 +34,7 @@ - #define TPS68470_REG_SGPO 0x22 - #define TPS68470_REG_GPDI 0x26 - #define TPS68470_REG_GPDO 0x27 -+#define TPS68470_REG_ILEDCTL 0x28 - #define TPS68470_REG_VCMVAL 0x3C - #define TPS68470_REG_VAUX1VAL 0x3D - #define TPS68470_REG_VAUX2VAL 0x3E -@@ -94,4 +95,8 @@ - #define TPS68470_GPIO_MODE_OUT_CMOS 2 - #define TPS68470_GPIO_MODE_OUT_ODRAIN 3 - -+#define TPS68470_ILEDCTL_ENA BIT(2) -+#define TPS68470_ILEDCTL_ENB BIT(6) -+#define TPS68470_ILEDCTL_CTRLB GENMASK(5, 4) ++module_platform_driver(tps68470_led_driver); + - #endif /* __LINUX_MFD_TPS68470_H */ -diff --git a/include/linux/pci.h b/include/linux/pci.h -index b9ae5eb4c..c615fff3c 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -464,6 +464,7 @@ struct pci_dev { - unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */ - unsigned int no_command_memory:1; /* No PCI_COMMAND_MEMORY */ - unsigned int rom_bar_overlap:1; /* ROM BAR disable broken */ -+ unsigned int no_shutdown:1; /* Do not touch device on shutdown */ - pci_dev_flags_t dev_flags; - atomic_t enable_cnt; /* pci_enable_device has been called */ ++MODULE_ALIAS("platform:tps68470-led"); ++MODULE_DESCRIPTION("LED driver for TPS68470 PMIC"); ++MODULE_LICENSE("GPL v2"); +-- +2.42.0 + +From f30fc6335df8d95752ecfe086b8a0b1c43039073 Mon Sep 17 00:00:00 2001 +From: Sachi King +Date: Sat, 29 May 2021 17:47:38 +1000 +Subject: [PATCH] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7 + override + +This patch is the work of Thomas Gleixner and is +copied from: +https://lore.kernel.org/lkml/87lf8ddjqx.ffs@nanos.tec.linutronix.de/ + +This patch adds a quirk to the ACPI setup to patch in the the irq 7 pin +setup that is missing in the laptops ACPI table. + +This patch was used for validation of the issue, and is not a proper +fix, but is probably a better temporary hack than continuing to probe +the Legacy PIC and run with the PIC in an unknown state. + +Patchset: amd-gpio +--- + arch/x86/kernel/acpi/boot.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 53369c57751e..1ec1a9015178 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include -diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index a506d940a..2766484b8 100644 ---- a/sound/soc/codecs/rt5645.c -+++ b/sound/soc/codecs/rt5645.c -@@ -3717,6 +3717,15 @@ static const struct dmi_system_id dmi_platform_data[] = { - }, - .driver_data = (void *)&intel_braswell_platform_data, - }, + #include + #include +@@ -1256,6 +1257,17 @@ static void __init mp_config_acpi_legacy_irqs(void) + } + } + ++static const struct dmi_system_id surface_quirk[] __initconst = { + { -+ .ident = "Microsoft Surface 3", ++ .ident = "Microsoft Surface Laptop 4 (AMD)", + .matches = { -+ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), -+ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953") + }, -+ .driver_data = (void *)&intel_braswell_platform_data, + }, ++ {} ++}; ++ + /* + * Parse IOAPIC related entries in MADT + * returns 0 on success, < 0 on error +@@ -1311,6 +1323,11 @@ static int __init acpi_parse_madt_ioapic_entries(void) + acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0, + acpi_gbl_FADT.sci_interrupt); + ++ if (dmi_check_system(surface_quirk)) { ++ pr_warn("Surface hack: Override irq 7\n"); ++ mp_override_legacy_irq(7, 3, 3, 7); ++ } ++ + /* Fill in identity legacy mappings where no override */ + mp_config_acpi_legacy_irqs(); + +-- +2.42.0 + +From 550bd4c801d8651b3ee57a7e412b10f0e3dc8ebb Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Thu, 3 Jun 2021 14:04:26 +0200 +Subject: [PATCH] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7 override + quirk + +The 13" version of the Surface Laptop 4 has the same problem as the 15" +version, but uses a different SKU. Add that SKU to the quirk as well. + +Patchset: amd-gpio +--- + arch/x86/kernel/acpi/boot.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index 1ec1a9015178..a7d40015e46a 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1259,12 +1259,19 @@ static void __init mp_config_acpi_legacy_irqs(void) + + static const struct dmi_system_id surface_quirk[] __initconst = { { - /* - * Match for the GPDwin which unfortunately uses somewhat -diff --git a/sound/soc/intel/common/soc-acpi-intel-cht-match.c b/sound/soc/intel/common/soc-acpi-intel-cht-match.c -index cdcbf04b8..958305779 100644 ---- a/sound/soc/intel/common/soc-acpi-intel-cht-match.c -+++ b/sound/soc/intel/common/soc-acpi-intel-cht-match.c -@@ -27,6 +27,14 @@ static const struct dmi_system_id cht_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), +- .ident = "Microsoft Surface Laptop 4 (AMD)", ++ .ident = "Microsoft Surface Laptop 4 (AMD 15\")", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953") }, }, + { -+ .callback = cht_surface_quirk_cb, ++ .ident = "Microsoft Surface Laptop 4 (AMD 13\")", + .matches = { -+ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), -+ DMI_MATCH(DMI_SYS_VENDOR, "OEMB"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "OEMB"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1958:1959") + }, + }, - { } + {} + }; + +-- +2.42.0 + +From ecca82459be635f742336b861f26018c16aeb18f Mon Sep 17 00:00:00 2001 +From: "Bart Groeneveld | GPX Solutions B.V" +Date: Mon, 5 Dec 2022 16:08:46 +0100 +Subject: [PATCH] acpi: allow usage of acpi_tad on HW-reduced platforms + +The specification [1] allows so-called HW-reduced platforms, +which do not implement everything, especially the wakeup related stuff. + +In that case, it is still usable as a RTC. This is helpful for [2] +and [3], which is about a device with no other working RTC, +but it does have an HW-reduced TAD, which can be used as a RTC instead. + +[1]: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#time-and-alarm-device +[2]: https://bugzilla.kernel.org/show_bug.cgi?id=212313 +[3]: https://github.com/linux-surface/linux-surface/issues/415 + +Signed-off-by: Bart Groeneveld | GPX Solutions B.V. +Patchset: rtc +--- + drivers/acpi/acpi_tad.c | 35 ++++++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 11 deletions(-) + +diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c +index e9b8e8305e23..944276934e7e 100644 +--- a/drivers/acpi/acpi_tad.c ++++ b/drivers/acpi/acpi_tad.c +@@ -432,6 +432,14 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, + + static DEVICE_ATTR_RO(caps); + ++static struct attribute *acpi_tad_attrs[] = { ++ &dev_attr_caps.attr, ++ NULL, ++}; ++static const struct attribute_group acpi_tad_attr_group = { ++ .attrs = acpi_tad_attrs, ++}; ++ + static ssize_t ac_alarm_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +@@ -480,15 +488,14 @@ static ssize_t ac_status_show(struct device *dev, struct device_attribute *attr, + + static DEVICE_ATTR_RW(ac_status); + +-static struct attribute *acpi_tad_attrs[] = { +- &dev_attr_caps.attr, ++static struct attribute *acpi_tad_ac_attrs[] = { + &dev_attr_ac_alarm.attr, + &dev_attr_ac_policy.attr, + &dev_attr_ac_status.attr, + NULL, + }; +-static const struct attribute_group acpi_tad_attr_group = { +- .attrs = acpi_tad_attrs, ++static const struct attribute_group acpi_tad_ac_attr_group = { ++ .attrs = acpi_tad_ac_attrs, }; + static ssize_t dc_alarm_store(struct device *dev, struct device_attribute *attr, +@@ -563,13 +570,18 @@ static int acpi_tad_remove(struct platform_device *pdev) + + pm_runtime_get_sync(dev); + ++ if (dd->capabilities & ACPI_TAD_AC_WAKE) ++ sysfs_remove_group(&dev->kobj, &acpi_tad_ac_attr_group); ++ + if (dd->capabilities & ACPI_TAD_DC_WAKE) + sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group); + + sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group); + +- acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER); +- acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER); ++ if (dd->capabilities & ACPI_TAD_AC_WAKE) { ++ acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER); ++ acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER); ++ } + if (dd->capabilities & ACPI_TAD_DC_WAKE) { + acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER); + acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER); +@@ -604,11 +616,6 @@ static int acpi_tad_probe(struct platform_device *pdev) + return -ENODEV; + } + +- if (!acpi_has_method(handle, "_PRW")) { +- dev_info(dev, "Missing _PRW\n"); +- return -ENODEV; +- } +- + dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL); + if (!dd) + return -ENOMEM; +@@ -637,6 +644,12 @@ static int acpi_tad_probe(struct platform_device *pdev) + if (ret) + goto fail; + ++ if (caps & ACPI_TAD_AC_WAKE) { ++ ret = sysfs_create_group(&dev->kobj, &acpi_tad_ac_attr_group); ++ if (ret) ++ goto fail; ++ } ++ + if (caps & ACPI_TAD_DC_WAKE) { + ret = sysfs_create_group(&dev->kobj, &acpi_tad_dc_attr_group); + if (ret) -- -2.41.0 +2.42.0 diff --git a/SOURCES/patch-6.5-redhat.patch b/SOURCES/patch-6.5-redhat.patch index 3f1689f..dd1ceda 100644 --- a/SOURCES/patch-6.5-redhat.patch +++ b/SOURCES/patch-6.5-redhat.patch @@ -18,42 +18,38 @@ drivers/input/rmi4/rmi_driver.c | 124 ++++++++++++--------- drivers/iommu/apple-dart.c | 3 +- drivers/iommu/iommu.c | 22 ++++ - drivers/misc/cardreader/rts5227.c | 2 +- - drivers/misc/cardreader/rts5228.c | 18 +++ - drivers/misc/cardreader/rts5249.c | 3 +- - drivers/misc/cardreader/rts5260.c | 18 +++ - drivers/misc/cardreader/rts5261.c | 18 +++ - drivers/misc/cardreader/rtsx_pcr.c | 5 +- + drivers/misc/cardreader/rts5228.c | 6 + + drivers/misc/cardreader/rts5260.c | 6 + + drivers/misc/cardreader/rts5261.c | 6 + drivers/nvme/host/core.c | 22 +++- drivers/nvme/host/multipath.c | 19 ++-- drivers/nvme/host/nvme.h | 4 + drivers/pci/quirks.c | 24 ++++ + drivers/power/supply/power_supply_core.c | 8 +- drivers/scsi/sd.c | 10 ++ drivers/usb/core/hub.c | 7 ++ fs/btrfs/space-info.c | 17 +++ - fs/btrfs/super.c | 3 +- - include/linux/atomic/atomic-arch-fallback.h | 10 +- include/linux/efi.h | 22 ++-- include/linux/lsm_hook_defs.h | 2 + + include/linux/power_supply.h | 2 +- include/linux/rmi.h | 1 + include/linux/security.h | 5 + kernel/module/signing.c | 9 +- - scripts/atomic/gen-atomic-fallback.sh | 2 +- scripts/tags.sh | 2 + security/integrity/platform_certs/load_uefi.c | 6 +- security/lockdown/Kconfig | 13 +++ security/lockdown/lockdown.c | 1 + security/security.c | 12 ++ - 46 files changed, 594 insertions(+), 203 deletions(-) + 42 files changed, 555 insertions(+), 191 deletions(-) diff --git a/Makefile b/Makefile -index 7545d2b0e7b7..fe35765f10c9 100644 +index 81f14b15592f..c0507c199e18 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \ PHONY := __all __all: - + +# Set RHEL variables +# Note that this ifdef'ery is required to handle when building with +# the O= mechanism (relocate the object file results) due to upstream @@ -78,7 +74,7 @@ index b0d00032479d..afb9544fb007 100644 int ipl_report_add_certificate(struct ipl_report *report, void *key, unsigned long addr, unsigned long len); +bool ipl_get_secureboot(void); - + /* * DIAG 308 support diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c @@ -87,7 +83,7 @@ index dfcb2b563e2b..29e3f1b4bd00 100644 +++ b/arch/s390/kernel/ipl.c @@ -2535,3 +2535,8 @@ int ipl_report_free(struct ipl_report *report) } - + #endif + +bool ipl_get_secureboot(void) @@ -105,11 +101,11 @@ index 00d76448319d..e679d13303e3 100644 +#include #include #include - + @@ -914,6 +915,9 @@ void __init setup_arch(char **cmdline_p) - + log_component_list(); - + + if (ipl_get_secureboot()) + security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX); + @@ -117,7 +113,7 @@ index 00d76448319d..e679d13303e3 100644 /* boot_command_line has been already set up in early.c */ *cmdline_p = boot_command_line; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index fd975a4a5200..3e05018e244c 100644 +index aa0df37c1fe7..04f1de50e058 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -21,6 +21,7 @@ @@ -128,10 +124,10 @@ index fd975a4a5200..3e05018e244c 100644 #include #include #include -@@ -1031,6 +1032,13 @@ void __init setup_arch(char **cmdline_p) +@@ -1027,6 +1028,13 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled(EFI_BOOT)) efi_init(); - + + efi_set_secure_boot(boot_params.secure_boot); + +#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT @@ -141,11 +137,11 @@ index fd975a4a5200..3e05018e244c 100644 + reserve_ibft_region(); dmi_setup(); - -@@ -1192,19 +1200,7 @@ void __init setup_arch(char **cmdline_p) + +@@ -1188,19 +1196,7 @@ void __init setup_arch(char **cmdline_p) /* Allocate bigger log buffer */ setup_log_buf(1); - + - if (efi_enabled(EFI_BOOT)) { - switch (boot_params.secure_boot) { - case efi_secureboot_mode_disabled: @@ -160,9 +156,9 @@ index fd975a4a5200..3e05018e244c 100644 - } - } + efi_set_secure_boot(boot_params.secure_boot); - + reserve_initrd(); - + diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 6aef1ee5e1bd..8f146b1b4972 100644 --- a/drivers/acpi/apei/hest.c @@ -170,7 +166,7 @@ index 6aef1ee5e1bd..8f146b1b4972 100644 @@ -96,6 +96,14 @@ static int apei_hest_parse(apei_hest_func_t func, void *data) if (hest_disable || !hest_tab) return -EINVAL; - + +#ifdef CONFIG_ARM64 + /* Ignore broken firmware */ + if (!strncmp(hest_tab->header.oem_id, "HPE ", 6) && @@ -192,7 +188,7 @@ index c2c786eb95ab..4e3aa80cd5cf 100644 struct irq_fwspec *fwspec; + bool skip_producer_check; }; - + /** @@ -211,7 +212,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, return AE_CTRL_TERMINATE; @@ -210,7 +206,7 @@ index c2c786eb95ab..4e3aa80cd5cf 100644 { - struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec }; + struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false }; - + + /* + * Firmware on arm64-based HPE m400 platform incorrectly marks + * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER. @@ -232,7 +228,7 @@ index 87e385542576..7e9de6e3eb9f 100644 @@ -1749,6 +1749,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) if (!acpi_match_device_ids(device, ignore_serial_bus_ids)) return false; - + + /* + * Firmware on some arm64 X-Gene platforms will make the UART + * device appear as both a UART and a slave of that UART. Just @@ -252,7 +248,7 @@ index a6212f6d3796..1bd84617d751 100644 @@ -729,6 +729,24 @@ int ahci_stop_engine(struct ata_port *ap) tmp &= ~PORT_CMD_START; writel(tmp, port_mmio + PORT_CMD); - + +#ifdef CONFIG_ARM64 + /* Rev Ax of Cavium CN99XX needs a hack for port stop */ + if (dev_is_pci(ap->host->dev) && @@ -281,7 +277,7 @@ index bbf7029e224b..cf7faa970dd6 100644 @@ -215,6 +215,21 @@ static int __init scan_for_dmi_ipmi(void) { const struct dmi_device *dev = NULL; - + +#ifdef CONFIG_ARM64 + /* RHEL-only + * If this is ARM-based HPE m400, return now, because that platform @@ -299,7 +295,7 @@ index bbf7029e224b..cf7faa970dd6 100644 + while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) dmi_decode_ipmi((const struct dmi_header *) dev->device_data); - + diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 186f1fee7534..93e3a76596ff 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c @@ -310,12 +306,12 @@ index 186f1fee7534..93e3a76596ff 100644 #include +#include #include - + #define IPMI_DRIVER_VERSION "39.2" @@ -5516,8 +5517,21 @@ static int __init ipmi_init_msghandler_mod(void) { int rv; - + - pr_info("version " IPMI_DRIVER_VERSION "\n"); +#ifdef CONFIG_ARM64 + /* RHEL-only @@ -324,7 +320,7 @@ index 186f1fee7534..93e3a76596ff 100644 + * does not exist in the ARM architecture. + */ + const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME); - + + if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) { + pr_debug("%s does not support host ipmi\n", dmistr); + return -ENOSYS; @@ -356,13 +352,13 @@ index 1599f1176842..a1fc17f1e0cc 100644 #include #include +#include - + #include - + @@ -953,40 +954,101 @@ int efi_mem_type(unsigned long phys_addr) } #endif - + +struct efi_error_code { + efi_status_t status; + int errno; @@ -467,7 +463,7 @@ index 1599f1176842..a1fc17f1e0cc 100644 - } + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - + - return err; + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, @@ -491,7 +487,7 @@ index 1599f1176842..a1fc17f1e0cc 100644 + return found->description; } EXPORT_SYMBOL_GPL(efi_status_to_err); - + diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c new file mode 100644 index 000000000000..de0a3714a5d4 @@ -543,7 +539,7 @@ index 82fcfd29bc4d..17b7e096b682 100644 @@ -34,6 +34,22 @@ #include #include - + +static int skip_simpledrm; + +static int __init simpledrm_disable(char *opt) @@ -564,7 +560,7 @@ index 82fcfd29bc4d..17b7e096b682 100644 static DEFINE_MUTEX(disable_lock); static bool disabled; @@ -85,7 +101,7 @@ static __init int sysfb_init(void) - + /* try to create a simple-framebuffer device */ compatible = sysfb_parse_mode(si, &mode); - if (compatible) { @@ -581,27 +577,27 @@ index 84e7ba5314d3..efc96776f761 100644 struct rmi_data *hdata = hid_get_drvdata(hdev); struct rmi_device *rmi_dev = hdata->xport.rmi_dev; - unsigned long flags; - + if (!(test_bit(RMI_STARTED, &hdata->flags))) return 0; - + - pm_wakeup_event(hdev->dev.parent, 0); - - local_irq_save(flags); - rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2); - + - generic_handle_irq(hdata->rmi_irq); - - local_irq_restore(flags); - return 1; } - + @@ -591,56 +582,6 @@ static const struct rmi_transport_ops hid_rmi_ops = { .reset = rmi_hid_reset, }; - + -static void rmi_irq_teardown(void *data) -{ - struct rmi_data *hdata = data; @@ -656,9 +652,9 @@ index 84e7ba5314d3..efc96776f761 100644 { struct rmi_data *data = NULL; @@ -713,18 +654,11 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) - + mutex_init(&data->page_mutex); - + - ret = rmi_setup_irq_domain(hdev); - if (ret) { - hid_err(hdev, "failed to allocate IRQ domain\n"); @@ -667,13 +663,13 @@ index 84e7ba5314d3..efc96776f761 100644 - if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) rmi_hid_pdata.gpio_data.disable = true; - + data->xport.dev = hdev->dev.parent; data->xport.pdata = rmi_hid_pdata; - data->xport.pdata.irq = data->rmi_irq; data->xport.proto_name = "hid"; data->xport.ops = &hid_rmi_ops; - + diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 7e307022303a..c68d7da67148 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -689,7 +685,7 @@ index 7e307022303a..c68d7da67148 100644 @@ -2265,6 +2266,16 @@ static const struct amba_id etm4_ids[] = { {}, }; - + +static const struct dmi_system_id broken_coresight[] = { + { + .matches = { @@ -701,22 +697,22 @@ index 7e307022303a..c68d7da67148 100644 +}; + MODULE_DEVICE_TABLE(amba, etm4_ids); - + static struct amba_driver etm4x_amba_driver = { @@ -2298,6 +2309,11 @@ static int __init etm4x_init(void) { int ret; - + + if (dmi_check_system(broken_coresight)) { + pr_info("ETM4 disabled due to firmware bug\n"); + return 0; + } + ret = etm4_pm_setup(); - + /* etm4_pm_setup() does its own cleanup - exit on error */ @@ -2324,6 +2340,9 @@ static int __init etm4x_init(void) - + static void __exit etm4x_exit(void) { + if (dmi_check_system(broken_coresight)) @@ -731,13 +727,13 @@ index 258d5fe3d395..f7298e3dc8f3 100644 +++ b/drivers/input/rmi4/rmi_driver.c @@ -182,34 +182,47 @@ void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status, attn_data.data = fifo_data; - + kfifo_put(&drvdata->attn_fifo, attn_data); + + schedule_work(&drvdata->attn_work); } EXPORT_SYMBOL_GPL(rmi_set_attn_data); - + -static irqreturn_t rmi_irq_fn(int irq, void *dev_id) +static void attn_callback(struct work_struct *work) { @@ -748,7 +744,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + attn_work); struct rmi4_attn_data attn_data = {0}; int ret, count; - + count = kfifo_get(&drvdata->attn_fifo, &attn_data); - if (count) { - *(drvdata->irq_status) = attn_data.irq_status; @@ -756,7 +752,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 - } + if (!count) + return; - + - ret = rmi_process_interrupt_requests(rmi_dev); + *(drvdata->irq_status) = attn_data.irq_status; + drvdata->attn_data = attn_data; @@ -766,14 +762,14 @@ index 258d5fe3d395..f7298e3dc8f3 100644 - rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, + rmi_dbg(RMI_DEBUG_CORE, &drvdata->rmi_dev->dev, "Failed to process interrupt request: %d\n", ret); - + - if (count) { - kfree(attn_data.data); - drvdata->attn_data.data = NULL; - } + kfree(attn_data.data); + drvdata->attn_data.data = NULL; - + if (!kfifo_is_empty(&drvdata->attn_fifo)) - return rmi_irq_fn(irq, dev_id); + schedule_work(&drvdata->attn_work); @@ -788,7 +784,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + if (ret) + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, + "Failed to process interrupt request: %d\n", ret); - + return IRQ_HANDLED; } @@ -217,7 +230,6 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) @@ -798,20 +794,20 @@ index 258d5fe3d395..f7298e3dc8f3 100644 - struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); int irq_flags = irq_get_trigger_type(pdata->irq); int ret; - + @@ -235,8 +247,6 @@ static int rmi_irq_init(struct rmi_device *rmi_dev) return ret; } - + - data->enabled = true; - return 0; } - + @@ -886,23 +896,27 @@ void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake) if (data->enabled) goto out; - + - enable_irq(irq); - data->enabled = true; - if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) { @@ -831,7 +827,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + "Failed to disable irq for wake: %d\n", + retval); + } - + - /* - * Call rmi_process_interrupt_requests() after enabling irq, - * otherwise we may lose interrupt on edge-triggered systems. @@ -849,12 +845,12 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + } else { + data->enabled = true; + } - + out: mutex_unlock(&data->enabled_mutex); @@ -922,20 +936,22 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake) goto out; - + data->enabled = false; - disable_irq(irq); - if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) { @@ -887,21 +883,21 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + kfree(attn_data.data); + } } - + out: @@ -981,6 +997,8 @@ static int rmi_driver_remove(struct device *dev) irq_domain_remove(data->irqdomain); data->irqdomain = NULL; - + + cancel_work_sync(&data->attn_work); + rmi_f34_remove_sysfs(rmi_dev); rmi_free_function_list(rmi_dev); - + @@ -1219,9 +1237,15 @@ static int rmi_driver_probe(struct device *dev) } } - + - retval = rmi_irq_init(rmi_dev); - if (retval < 0) - goto err_destroy_functions; @@ -914,7 +910,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 + data->enabled = true; + + INIT_WORK(&data->attn_work, attn_callback); - + if (data->f01_container->dev.driver) { /* Driver already bound, so enable ATTN now. */ diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c @@ -923,7 +919,7 @@ index 8af64b57f048..f4d880408254 100644 +++ b/drivers/iommu/apple-dart.c @@ -671,8 +671,7 @@ static int apple_dart_attach_dev(struct iommu_domain *domain, return ret; - + switch (domain->type) { - case IOMMU_DOMAIN_DMA: - case IOMMU_DOMAIN_UNMANAGED: @@ -936,7 +932,7 @@ index cabeb5bd3e41..25ef4e9cc34a 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -8,6 +8,7 @@ - + #include #include +#include @@ -946,7 +942,7 @@ index cabeb5bd3e41..25ef4e9cc34a 100644 @@ -2819,6 +2820,27 @@ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat) } EXPORT_SYMBOL_GPL(iommu_dev_disable_feature); - + +#ifdef CONFIG_ARM64 +static int __init iommu_quirks(void) +{ @@ -971,26 +967,13 @@ index cabeb5bd3e41..25ef4e9cc34a 100644 /** * iommu_setup_default_domain - Set the default_domain for the group * @group: Group to change -diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c -index 3dae5e3a1697..d676cf63a966 100644 ---- a/drivers/misc/cardreader/rts5227.c -+++ b/drivers/misc/cardreader/rts5227.c -@@ -195,7 +195,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) -+ if (option->force_clkreq_0) - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else diff --git a/drivers/misc/cardreader/rts5228.c b/drivers/misc/cardreader/rts5228.c -index f4ab09439da7..cfebad51d1d8 100644 +index 0c7f10bcf6f1..4ca9da411ebb 100644 --- a/drivers/misc/cardreader/rts5228.c +++ b/drivers/misc/cardreader/rts5228.c -@@ -435,10 +435,17 @@ static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } +@@ -400,6 +400,12 @@ static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) + if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); } + + if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN @@ -999,56 +982,15 @@ index f4ab09439da7..cfebad51d1d8 100644 + else + option->force_clkreq_0 = true; } - + static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - - rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, - CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); -@@ -469,6 +476,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c -index 47ab72a43256..91d240dd68fa 100644 ---- a/drivers/misc/cardreader/rts5249.c -+++ b/drivers/misc/cardreader/rts5249.c -@@ -327,11 +327,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) - } - } - -+ - /* - * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced - * to drive low, and we forcibly request clock. - */ -- if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) -+ if (option->force_clkreq_0) - rtsx_pci_write_register(pcr, PETXCFG, - FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); - else diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c -index 79b18f6f73a8..9b42b20a3e5a 100644 +index d2d3a6ccb8f7..0cef0808b1f1 100644 --- a/drivers/misc/cardreader/rts5260.c +++ b/drivers/misc/cardreader/rts5260.c -@@ -517,10 +517,17 @@ static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } +@@ -488,6 +488,12 @@ static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) + if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); } + + if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN @@ -1057,38 +999,15 @@ index 79b18f6f73a8..9b42b20a3e5a 100644 + else + option->force_clkreq_0 = true; } - + static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - - /* Set mcu_cnt to 7 to ensure data can be sampled properly */ - rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); -@@ -539,6 +546,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) - - rts5260_init_hw(pcr); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); - - return 0; diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c -index 94af6bf8a25a..b1e76030cafd 100644 +index 67252512a132..3236a82feca5 100644 --- a/drivers/misc/cardreader/rts5261.c +++ b/drivers/misc/cardreader/rts5261.c -@@ -498,10 +498,17 @@ static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) - option->ltr_enabled = false; - } +@@ -460,6 +460,12 @@ static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) + if (option->ltr_enabled) + rtsx_set_ltr_latency(pcr, option->ltr_active_latency); } + + if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN @@ -1097,54 +1016,14 @@ index 94af6bf8a25a..b1e76030cafd 100644 + else + option->force_clkreq_0 = true; } - + static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - { -+ struct rtsx_cr_option *option = &pcr->option; - u32 val; - - rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, -@@ -547,6 +554,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) - else - rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); - -+ /* -+ * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced -+ * to drive low, and we forcibly request clock. -+ */ -+ if (option->force_clkreq_0) -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); -+ else -+ rtsx_pci_write_register(pcr, PETXCFG, -+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -+ - rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); - - if (pcr->rtd3_en) { -diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c -index a3f4b52bb159..32b7783e9d4f 100644 ---- a/drivers/misc/cardreader/rtsx_pcr.c -+++ b/drivers/misc/cardreader/rtsx_pcr.c -@@ -1326,11 +1326,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) - return err; - } - -- if (pcr->aspm_mode == ASPM_MODE_REG) { -+ if (pcr->aspm_mode == ASPM_MODE_REG) - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); -- rtsx_pci_write_register(pcr, PETXCFG, -- FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); -- } - - /* No CD interrupt if probing driver with card inserted. - * So we need to initialize pcr->card_exist here. diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 21783aa2ee8e..f2f9bdb3e0c8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -251,6 +251,9 @@ void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl) - + static blk_status_t nvme_error_status(u16 status) { + if (unlikely(status & NVME_SC_DNR)) @@ -1160,17 +1039,17 @@ index 21783aa2ee8e..f2f9bdb3e0c8 100644 + FAILUP, AUTHENTICATE, }; - + @@ -352,15 +356,16 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req) if ((nvme_req(req)->status & 0x7ff) == NVME_SC_AUTH_REQUIRED) return AUTHENTICATE; - + - if (blk_noretry_request(req) || + if ((req->cmd_flags & (REQ_FAILFAST_DEV | REQ_FAILFAST_DRIVER)) || (nvme_req(req)->status & NVME_SC_DNR) || nvme_req(req)->retries >= nvme_max_retries) return COMPLETE; - + - if (req->cmd_flags & REQ_NVME_MPATH) { + if (req->cmd_flags & (REQ_NVME_MPATH | REQ_FAILFAST_TRANSPORT)) { if (nvme_is_path_error(nvme_req(req)->status) || @@ -1184,7 +1063,7 @@ index 21783aa2ee8e..f2f9bdb3e0c8 100644 @@ -390,6 +395,14 @@ static inline void nvme_end_req(struct request *req) blk_mq_end_request(req, status); } - + +static inline void nvme_failup_req(struct request *req) +{ + nvme_update_ana(req); @@ -1213,7 +1092,7 @@ index 0a88d7bdc5e3..967bb3a85889 100644 @@ -80,14 +80,10 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) blk_freeze_queue_start(h->disk->queue); } - + -void nvme_failover_req(struct request *req) +void nvme_update_ana(struct request *req) { @@ -1223,7 +1102,7 @@ index 0a88d7bdc5e3..967bb3a85889 100644 - struct bio *bio; - - nvme_mpath_clear_current_path(ns); - + /* * If we got back an ANA error, we know the controller is alive but not @@ -98,6 +94,16 @@ void nvme_failover_req(struct request *req) @@ -1240,18 +1119,18 @@ index 0a88d7bdc5e3..967bb3a85889 100644 + + nvme_mpath_clear_current_path(ns); + nvme_update_ana(req); - + spin_lock_irqsave(&ns->head->requeue_lock, flags); for (bio = req->bio; bio; bio = bio->bi_next) { @@ -912,8 +918,7 @@ int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) int error = 0; - + /* check if multipath is enabled and we have the capability */ - if (!multipath || !ctrl->subsys || - !(ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA)) + if (!ctrl->subsys || !(ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA)) return 0; - + if (!ctrl->max_namespaces || diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index f35647c470af..e57357f23306 100644 @@ -1282,7 +1161,7 @@ index 321156ca273d..fc399e56ec8f 100644 @@ -4406,6 +4406,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9000, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9084, quirk_bridge_cavm_thrx2_pcie_root); - + +/* + * PCI BAR 5 is not setup correctly for the on-board AHCI controller + * on Broadcom's Vulcan processor. Added a quirk to fix BAR 5 by @@ -1310,14 +1189,52 @@ index 321156ca273d..fc399e56ec8f 100644 /* * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero) * class code. Fix it. +diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c +index 3791aec69ddc..0d2e72a966c9 100644 +--- a/drivers/power/supply/power_supply_core.c ++++ b/drivers/power/supply/power_supply_core.c +@@ -29,7 +29,7 @@ + struct class *power_supply_class; + EXPORT_SYMBOL_GPL(power_supply_class); + +-ATOMIC_NOTIFIER_HEAD(power_supply_notifier); ++BLOCKING_NOTIFIER_HEAD(power_supply_notifier); + EXPORT_SYMBOL_GPL(power_supply_notifier); + + static struct device_type power_supply_dev_type; +@@ -97,7 +97,7 @@ static void power_supply_changed_work(struct work_struct *work) + class_for_each_device(power_supply_class, NULL, psy, + __power_supply_changed_work); + power_supply_update_leds(psy); +- atomic_notifier_call_chain(&power_supply_notifier, ++ blocking_notifier_call_chain(&power_supply_notifier, + PSY_EVENT_PROP_CHANGED, psy); + kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE); + spin_lock_irqsave(&psy->changed_lock, flags); +@@ -1262,13 +1262,13 @@ static void power_supply_dev_release(struct device *dev) + + int power_supply_reg_notifier(struct notifier_block *nb) + { +- return atomic_notifier_chain_register(&power_supply_notifier, nb); ++ return blocking_notifier_chain_register(&power_supply_notifier, nb); + } + EXPORT_SYMBOL_GPL(power_supply_reg_notifier); + + void power_supply_unreg_notifier(struct notifier_block *nb) + { +- atomic_notifier_chain_unregister(&power_supply_notifier, nb); ++ blocking_notifier_chain_unregister(&power_supply_notifier, nb); + } + EXPORT_SYMBOL_GPL(power_supply_unreg_notifier); + diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index 3c668cfb146d..95724cd9875f 100644 +index d6535cbb4e05..bcaad1fc5d8d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -130,6 +130,14 @@ static const char *sd_cache_types[] = { "write back, no read (daft)" }; - + +static const char *sd_probe_types[] = { "async", "sync" }; + +static char sd_probe_type[6] = "async"; @@ -1329,10 +1246,10 @@ index 3c668cfb146d..95724cd9875f 100644 static void sd_set_flush_flag(struct scsi_disk *sdkp) { bool wc = false, fua = false; -@@ -3961,6 +3969,8 @@ static int __init init_sd(void) +@@ -4024,6 +4032,8 @@ static int __init init_sd(void) goto err_out_class; } - + + if (!strcmp(sd_probe_type, "sync")) + sd_template.gendrv.probe_type = PROBE_FORCE_SYNCHRONOUS; err = scsi_register_driver(&sd_template.gendrv); @@ -1345,7 +1262,7 @@ index 26a27ff50408..e1050b7dd63d 100644 @@ -5805,6 +5805,13 @@ static void hub_event(struct work_struct *work) (u16) hub->change_bits[0], (u16) hub->event_bits[0]); - + + /* Don't disconnect USB-SATA on TrimSlice */ + if (strcmp(dev_name(hdev->bus->controller), "tegra-ehci.0") == 0) { + if ((hdev->state == 7) && (hub->change_bits[0] == 0) && @@ -1363,7 +1280,7 @@ index ba5322fe34f5..35d084c52f2d 100644 @@ -365,6 +365,23 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info, factor = btrfs_bg_type_to_factor(profile); avail = div_u64(avail, factor); - + + /* + * Since data allocations immediately use block groups as part of the + * reservation, because we assume that data reservations will == actual @@ -1384,66 +1301,6 @@ index ba5322fe34f5..35d084c52f2d 100644 /* * If we aren't flushing all things, let us overcommit up to * 1/2th of the space. If we can flush, don't let us overcommit -diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index f1dd172d8d5b..784640ce7857 100644 ---- a/fs/btrfs/super.c -+++ b/fs/btrfs/super.c -@@ -2111,7 +2111,8 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) - * calculated f_bavail. - */ - if (!mixed && block_rsv->space_info->full && -- total_free_meta - thresh < block_rsv->size) -+ (total_free_meta < thresh || -+ total_free_meta - thresh < block_rsv->size)) - buf->f_bavail = 0; - - buf->f_type = BTRFS_SUPER_MAGIC; -diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h -index 18f5744dfb5d..b83ef19da13d 100644 ---- a/include/linux/atomic/atomic-arch-fallback.h -+++ b/include/linux/atomic/atomic-arch-fallback.h -@@ -459,8 +459,6 @@ raw_atomic_read_acquire(const atomic_t *v) - { - #if defined(arch_atomic_read_acquire) - return arch_atomic_read_acquire(v); --#elif defined(arch_atomic_read) -- return arch_atomic_read(v); - #else - int ret; - -@@ -508,8 +506,6 @@ raw_atomic_set_release(atomic_t *v, int i) - { - #if defined(arch_atomic_set_release) - arch_atomic_set_release(v, i); --#elif defined(arch_atomic_set) -- arch_atomic_set(v, i); - #else - if (__native_word(atomic_t)) { - smp_store_release(&(v)->counter, i); -@@ -2575,8 +2571,6 @@ raw_atomic64_read_acquire(const atomic64_t *v) - { - #if defined(arch_atomic64_read_acquire) - return arch_atomic64_read_acquire(v); --#elif defined(arch_atomic64_read) -- return arch_atomic64_read(v); - #else - s64 ret; - -@@ -2624,8 +2618,6 @@ raw_atomic64_set_release(atomic64_t *v, s64 i) - { - #if defined(arch_atomic64_set_release) - arch_atomic64_set_release(v, i); --#elif defined(arch_atomic64_set) -- arch_atomic64_set(v, i); - #else - if (__native_word(atomic64_t)) { - smp_store_release(&(v)->counter, i); -@@ -4657,4 +4649,4 @@ raw_atomic64_dec_if_positive(atomic64_t *v) - } - - #endif /* _LINUX_ATOMIC_FALLBACK_H */ --// 202b45c7db600ce36198eb1f1fc2c2d5268ace2d -+// 2fdd6702823fa842f9cea57a002e6e4476ae780c diff --git a/include/linux/efi.h b/include/linux/efi.h index ab088c662e88..f974f9d9a7c5 100644 --- a/include/linux/efi.h @@ -1451,7 +1308,7 @@ index ab088c662e88..f974f9d9a7c5 100644 @@ -43,6 +43,8 @@ #define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1))) #define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1))) - + +#define EFI_IS_ERROR(x) ((x) & (1UL << (BITS_PER_LONG-1))) + typedef unsigned long efi_status_t; @@ -1469,22 +1326,22 @@ index ab088c662e88..f974f9d9a7c5 100644 + efi_secureboot_mode_disabled, + efi_secureboot_mode_enabled, +}; - + #ifdef CONFIG_EFI /* @@ -882,6 +892,8 @@ static inline bool efi_enabled(int feature) } extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); - + +extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode); + bool __pure __efi_soft_reserve_enabled(void); - + static inline bool __pure efi_soft_reserve_enabled(void) @@ -903,6 +915,8 @@ static inline bool efi_enabled(int feature) static inline void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {} - + +static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {} + static inline bool efi_soft_reserve_enabled(void) @@ -1492,16 +1349,16 @@ index ab088c662e88..f974f9d9a7c5 100644 return false; @@ -917,6 +931,7 @@ static inline void efi_find_mirror(void) {} #endif - + extern int efi_status_to_err(efi_status_t status); +extern const char *efi_status_to_str(efi_status_t status); - + /* * Variable Attributes @@ -1133,13 +1148,6 @@ static inline bool efi_runtime_disabled(void) { return true; } extern void efi_call_virt_check_flags(unsigned long flags, const char *call); extern unsigned long efi_call_virt_save_flags(void); - + -enum efi_secureboot_mode { - efi_secureboot_mode_unset, - efi_secureboot_mode_unknown, @@ -1518,24 +1375,37 @@ index af796986baee..83e1cb0ca159 100644 +++ b/include/linux/lsm_hook_defs.h @@ -405,6 +405,8 @@ LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free_security, struct bpf_prog_aux *aux) #endif /* CONFIG_BPF_SYSCALL */ - + LSM_HOOK(int, 0, locked_down, enum lockdown_reason what) +LSM_HOOK(int, 0, lock_kernel_down, const char *where, enum lockdown_reason level) + - + #ifdef CONFIG_PERF_EVENTS LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type) +diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h +index a427f13c757f..85b86768c0b9 100644 +--- a/include/linux/power_supply.h ++++ b/include/linux/power_supply.h +@@ -767,7 +767,7 @@ struct power_supply_battery_info { + int bti_resistance_tolerance; + }; + +-extern struct atomic_notifier_head power_supply_notifier; ++extern struct blocking_notifier_head power_supply_notifier; + extern int power_supply_reg_notifier(struct notifier_block *nb); + extern void power_supply_unreg_notifier(struct notifier_block *nb); + #if IS_ENABLED(CONFIG_POWER_SUPPLY) diff --git a/include/linux/rmi.h b/include/linux/rmi.h index ab7eea01ab42..fff7c5f737fc 100644 --- a/include/linux/rmi.h +++ b/include/linux/rmi.h @@ -364,6 +364,7 @@ struct rmi_driver_data { - + struct rmi4_attn_data attn_data; DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16); + struct work_struct attn_work; }; - + int rmi_register_transport_device(struct rmi_transport_dev *xport); diff --git a/include/linux/security.h b/include/linux/security.h index bac98ea18f78..28abed10b583 100644 @@ -1547,7 +1417,7 @@ index bac98ea18f78..28abed10b583 100644 int security_locked_down(enum lockdown_reason what); +int security_lock_kernel_down(const char *where, enum lockdown_reason level); #else /* CONFIG_SECURITY */ - + static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data) @@ -1394,6 +1395,10 @@ static inline int security_locked_down(enum lockdown_reason what) { @@ -1558,7 +1428,7 @@ index bac98ea18f78..28abed10b583 100644 + return 0; +} #endif /* CONFIG_SECURITY */ - + #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) diff --git a/kernel/module/signing.c b/kernel/module/signing.c index a2ff4242e623..f0d2be1ee4f1 100644 @@ -1567,7 +1437,7 @@ index a2ff4242e623..f0d2be1ee4f1 100644 @@ -61,10 +61,17 @@ int mod_verify_sig(const void *mod, struct load_info *info) modlen -= sig_len + sizeof(ms); info->len = modlen; - + - return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, + ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, VERIFY_USE_SECONDARY_KEYRING, @@ -1581,21 +1451,8 @@ index a2ff4242e623..f0d2be1ee4f1 100644 + } + return ret; } - + int module_sig_check(struct load_info *info, int flags) -diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh -index c0c8a85d7c81..a45154cefa48 100755 ---- a/scripts/atomic/gen-atomic-fallback.sh -+++ b/scripts/atomic/gen-atomic-fallback.sh -@@ -102,7 +102,7 @@ gen_proto_order_variant() - fi - - # Allow ACQUIRE/RELEASE/RELAXED ops to be defined in terms of FULL ops -- if [ ! -z "${order}" ]; then -+ if [ ! -z "${order}" ] && ! meta_is_implicitly_relaxed "${meta}"; then - printf "#elif defined(arch_${basename})\n" - printf "\t${retstmt}arch_${basename}(${args});\n" - fi diff --git a/scripts/tags.sh b/scripts/tags.sh index a70d43723146..56d06b04f752 100755 --- a/scripts/tags.sh @@ -1606,7 +1463,7 @@ index a70d43723146..56d06b04f752 100755 ignore="$ignore ( -name *.mod.c ) -prune -o" +# RHEL tags and cscope should also ignore redhat/rpm +ignore="$ignore ( -path redhat/rpm ) -prune -o" - + # ignore arbitrary directories if [ -n "${IGNORE_DIRS}" ]; then diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c @@ -1615,14 +1472,14 @@ index d1fdd113450a..182e8090cfe8 100644 +++ b/security/integrity/platform_certs/load_uefi.c @@ -74,7 +74,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, return NULL; - + if (*status != EFI_BUFFER_TOO_SMALL) { - pr_err("Couldn't get size: 0x%lx\n", *status); + pr_err("Couldn't get size: %s (0x%lx)\n", + efi_status_to_str(*status), *status); return NULL; } - + @@ -85,7 +86,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, *status = efi.get_variable(name, guid, NULL, &lsize, db); if (*status != EFI_SUCCESS) { @@ -1632,7 +1489,7 @@ index d1fdd113450a..182e8090cfe8 100644 + efi_status_to_str(*status), *status); return NULL; } - + diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig index e84ddf484010..d0501353a4b9 100644 --- a/security/lockdown/Kconfig @@ -1640,7 +1497,7 @@ index e84ddf484010..d0501353a4b9 100644 @@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY subsystem is fully initialised. If enabled, lockdown will unconditionally be called before any other LSMs. - + +config LOCK_DOWN_IN_EFI_SECURE_BOOT + bool "Lock down the kernel in EFI Secure Boot mode" + default n @@ -1662,12 +1519,12 @@ index 68d19632aeb7..ef348935b6ff 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -73,6 +73,7 @@ static int lockdown_is_locked_down(enum lockdown_reason what) - + static struct security_hook_list lockdown_hooks[] __ro_after_init = { LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), + LSM_HOOK_INIT(lock_kernel_down, lock_kernel_down), }; - + static int __init lockdown_lsm_init(void) diff --git a/security/security.c b/security/security.c index 549104a447e3..73670798f075 100644 @@ -1676,7 +1533,7 @@ index 549104a447e3..73670798f075 100644 @@ -5198,6 +5198,18 @@ int security_locked_down(enum lockdown_reason what) } EXPORT_SYMBOL(security_locked_down); - + +/** + * security_lock_kernel_down() - Put the kernel into lock-down mode. + * diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec index eeaf3e4..1683f80 100644 --- a/SPECS/kernel.spec +++ b/SPECS/kernel.spec @@ -160,18 +160,18 @@ Summary: The Linux kernel # the --with-release option overrides this setting.) %define debugbuildsenabled 1 %define buildid .fsync -%define specrpmversion 6.5.5 -%define specversion 6.5.5 +%define specrpmversion 6.5.6 +%define specversion 6.5.6 %define patchversion 6.5 %define pkgrelease 200 %define kversion 6 -%define tarfile_release 6.5.5 +%define tarfile_release 6.5.6 # This is needed to do merge window version magic %define patchlevel 5 # This allows pkg_release to have configurable %%{?dist} tag %define specrelease 201%{?buildid}%{?dist} # This defines the kabi tarball version -%define kabiversion 6.5.5 +%define kabiversion 6.5.6 # If this variable is set to 1, a bpf selftests build failure will cause a # fatal kernel package build error @@ -3779,8 +3779,22 @@ fi\ # # %changelog -* Sun Oct 01 2023 Jan Drögehoff - 6.5.5-201.fsync -- kernel-fsync v6.5.5 +* Sun Oct 08 2023 Jan Drögehoff - 6.5.6-201.fsync +- kernel-fsync v6.5.6 + +* Fri Oct 06 2023 Augusto Caringi [6.5.6-0] +- power: supply: core: Use blocking_notifier_call_chain to avoid RCU complaint (Kai-Heng Feng) +- Revert "Add linux-next specific files for 20231004" (Justin M. Forbes) +- redhat/configs: enable missing Kconfig options for Qualcomm RideSX4 (Brian Masney) +- add a couple of CVEs to BugsFixed (Justin M. Forbes) +- Add another F39 FE bug to BugsFixed (Justin M. Forbes) +- Add linux-next specific files for 20231004 (Stephen Rothwell) +- common: aarch64: enable NXP Flex SPI (Peter Robinson) +- fedora: Switch TI_SCI_CLK and TI_SCI_PM_DOMAINS symbols to built-in (Javier Martinez Canillas) +- Add bug for amdgpu to BugsFixed for 6.5.6 (Justin M. Forbes) +- drm/amdgpu: set completion status as preempted for the resubmission (Jiadong Zhu) +- Add CVE-2023-42756 to BugsFixed for 6.5.6 (Justin M. Forbes) +- Linux v6.5.6 * Sat Sep 23 2023 Justin M. Forbes [6.5.5-0] - iommu/apple-dart: Handle DMA_FQ domains in attach_dev() (Hector Martin) -- cgit v1.2.3