From ea6863863ba868c34af0f0bbdb7f02ec740f1c04 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 3 Jul 2024 11:09:35 +0200 Subject: [PATCH] drop some 5.10 patches --- ...dependency-of-__kernel_map_pages-on-.patch | 351 ----- ...not-register-clkdevs-for-prci-clocks.patch | 62 - ...ive-extract-prci-core-to-common-base.patch | 1318 ----------------- ...pi-unbind-mux-adapters-before-delete.patch | 158 -- queue-5.10/i2c-add-fwnode-apis.patch | 290 ---- ...aged-function-for-adding-i2c-adapter.patch | 78 - ...5-allow-module-autoloading-via-of-co.patch | 51 - ...c4005-reset-chip-on-probe-and-resume.patch | 157 -- ...ug_pagealloc_-map-unmap-_pages-helpe.patch | 192 --- .../mmc-jz4740-use-the-new-pm-macros.patch | 63 - .../mmc-mxc-use-the-new-pm-macros.patch | 60 - ...id-tif_ia32-when-checking-64bit-mode.patch | 82 - ...ew-_pm_ops-macros-deprecate-old-ones.patch | 197 --- .../pm-core-redefine-pm_ptr-macro.patch | 61 - ...tatic-qualifier-in-define_simple_dev.patch | 72 - ...e-direct-map-manipulations-more-expl.patch | 157 -- ...kernel_map_pages-to-fix-sleeping-in-.patch | 104 -- queue-5.10/series | 20 - ...ify-compat-syscall-userspace-allocat.patch | 53 - ...chine-to-select-start_thread-for-x32.patch | 65 - ...mu-context-ia32_compat-into-a-proper.patch | 137 -- 21 files changed, 3728 deletions(-) delete mode 100644 queue-5.10/arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch delete mode 100644 queue-5.10/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch delete mode 100644 queue-5.10/clk-sifive-extract-prci-core-to-common-base.patch delete mode 100644 queue-5.10/i2c-acpi-unbind-mux-adapters-before-delete.patch delete mode 100644 queue-5.10/i2c-add-fwnode-apis.patch delete mode 100644 queue-5.10/i2c-core-add-managed-function-for-adding-i2c-adapter.patch delete mode 100644 queue-5.10/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch delete mode 100644 queue-5.10/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch delete mode 100644 queue-5.10/mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch delete mode 100644 queue-5.10/mmc-jz4740-use-the-new-pm-macros.patch delete mode 100644 queue-5.10/mmc-mxc-use-the-new-pm-macros.patch delete mode 100644 queue-5.10/perf-x86-avoid-tif_ia32-when-checking-64bit-mode.patch delete mode 100644 queue-5.10/pm-core-add-new-_pm_ops-macros-deprecate-old-ones.patch delete mode 100644 queue-5.10/pm-core-redefine-pm_ptr-macro.patch delete mode 100644 queue-5.10/pm-core-remove-static-qualifier-in-define_simple_dev.patch delete mode 100644 queue-5.10/pm-hibernate-make-direct-map-manipulations-more-expl.patch delete mode 100644 queue-5.10/riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch delete mode 100644 queue-5.10/x86-compat-simplify-compat-syscall-userspace-allocat.patch delete mode 100644 queue-5.10/x86-elf-use-e_machine-to-select-start_thread-for-x32.patch delete mode 100644 queue-5.10/x86-mm-convert-mmu-context-ia32_compat-into-a-proper.patch diff --git a/queue-5.10/arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch b/queue-5.10/arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch deleted file mode 100644 index 027d9723781..00000000000 --- a/queue-5.10/arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch +++ /dev/null @@ -1,351 +0,0 @@ -From fc3d2d8da62d1731dd1ec10acc392318ca6c371f Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 14 Dec 2020 19:10:30 -0800 -Subject: arch, mm: restore dependency of __kernel_map_pages() on - DEBUG_PAGEALLOC - -From: Mike Rapoport - -[ Upstream commit 5d6ad668f31625c6aa9ed8dc3bdb29561d2b1144 ] - -The design of DEBUG_PAGEALLOC presumes that __kernel_map_pages() must -never fail. With this assumption is wouldn't be safe to allow general -usage of this function. - -Moreover, some architectures that implement __kernel_map_pages() have this -function guarded by #ifdef DEBUG_PAGEALLOC and some refuse to map/unmap -pages when page allocation debugging is disabled at runtime. - -As all the users of __kernel_map_pages() were converted to use -debug_pagealloc_map_pages() it is safe to make it available only when -DEBUG_PAGEALLOC is set. - -Link: https://lkml.kernel.org/r/20201109192128.960-4-rppt@kernel.org -Signed-off-by: Mike Rapoport -Acked-by: David Hildenbrand -Acked-by: Kirill A. Shutemov -Cc: Albert Ou -Cc: Andy Lutomirski -Cc: Benjamin Herrenschmidt -Cc: Borislav Petkov -Cc: Catalin Marinas -Cc: Christian Borntraeger -Cc: Christoph Lameter -Cc: Dave Hansen -Cc: David Rientjes -Cc: "David S. Miller" -Cc: "Edgecombe, Rick P" -Cc: Heiko Carstens -Cc: "H. Peter Anvin" -Cc: Ingo Molnar -Cc: Joonsoo Kim -Cc: Len Brown -Cc: Michael Ellerman -Cc: Palmer Dabbelt -Cc: Paul Mackerras -Cc: Paul Walmsley -Cc: Pavel Machek -Cc: Pekka Enberg -Cc: Peter Zijlstra -Cc: Rafael J. Wysocki -Cc: "Rafael J. Wysocki" -Cc: Thomas Gleixner -Cc: Vasily Gorbik -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context") -Signed-off-by: Sasha Levin ---- - arch/Kconfig | 3 +++ - arch/arm64/Kconfig | 4 +--- - arch/arm64/mm/pageattr.c | 8 ++++++-- - arch/powerpc/Kconfig | 5 +---- - arch/riscv/Kconfig | 4 +--- - arch/riscv/include/asm/pgtable.h | 2 -- - arch/riscv/mm/pageattr.c | 2 ++ - arch/s390/Kconfig | 4 +--- - arch/sparc/Kconfig | 4 +--- - arch/x86/Kconfig | 4 +--- - arch/x86/mm/pat/set_memory.c | 2 ++ - include/linux/mm.h | 10 +++++++--- - 12 files changed, 26 insertions(+), 26 deletions(-) - -diff --git a/arch/Kconfig b/arch/Kconfig -index 72e4cef062aca..3f025e47fb5d6 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -1073,6 +1073,9 @@ config ARCH_SPLIT_ARG64 - If a 32-bit architecture requires 64-bit arguments to be split into - pairs of 32-bit arguments, select this option. - -+config ARCH_SUPPORTS_DEBUG_PAGEALLOC -+ bool -+ - source "kernel/gcov/Kconfig" - - source "scripts/gcc-plugins/Kconfig" -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 13cf137da999a..c47b2887f300e 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -71,6 +71,7 @@ config ARM64 - select ARCH_USE_QUEUED_RWLOCKS - select ARCH_USE_QUEUED_SPINLOCKS - select ARCH_USE_SYM_ANNOTATIONS -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC - select ARCH_SUPPORTS_MEMORY_FAILURE - select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK - select ARCH_SUPPORTS_ATOMIC_RMW -@@ -1063,9 +1064,6 @@ config HOLES_IN_ZONE - - source "kernel/Kconfig.hz" - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- def_bool y -- - config ARCH_SPARSEMEM_ENABLE - def_bool y - select SPARSEMEM_VMEMMAP_ENABLE -diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c -index 1b94f5b826545..439325532be1e 100644 ---- a/arch/arm64/mm/pageattr.c -+++ b/arch/arm64/mm/pageattr.c -@@ -155,7 +155,7 @@ int set_direct_map_invalid_noflush(struct page *page) - .clear_mask = __pgprot(PTE_VALID), - }; - -- if (!rodata_full) -+ if (!debug_pagealloc_enabled() && !rodata_full) - return 0; - - return apply_to_page_range(&init_mm, -@@ -170,7 +170,7 @@ int set_direct_map_default_noflush(struct page *page) - .clear_mask = __pgprot(PTE_RDONLY), - }; - -- if (!rodata_full) -+ if (!debug_pagealloc_enabled() && !rodata_full) - return 0; - - return apply_to_page_range(&init_mm, -@@ -178,6 +178,7 @@ int set_direct_map_default_noflush(struct page *page) - PAGE_SIZE, change_page_range, &data); - } - -+#ifdef CONFIG_DEBUG_PAGEALLOC - void __kernel_map_pages(struct page *page, int numpages, int enable) - { - if (!debug_pagealloc_enabled() && !rodata_full) -@@ -186,6 +187,7 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) - set_memory_valid((unsigned long)page_address(page), numpages, enable); - } - -+#ifdef CONFIG_HIBERNATION - /* - * This function is used to determine if a linear map page has been marked as - * not-valid. Walk the page table and check the PTE_VALID bit. This is based -@@ -232,3 +234,5 @@ bool kernel_page_present(struct page *page) - ptep = pte_offset_kernel(pmdp, addr); - return pte_valid(READ_ONCE(*ptep)); - } -+#endif /* CONFIG_HIBERNATION */ -+#endif /* CONFIG_DEBUG_PAGEALLOC */ -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index 78dd6be8b31dd..c8e5b0929ef25 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -146,6 +146,7 @@ config PPC - select ARCH_MIGHT_HAVE_PC_SERIO - select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX - select ARCH_SUPPORTS_ATOMIC_RMW -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC32 || PPC_BOOK3S_64 - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_CMPXCHG_LOCKREF if PPC64 - select ARCH_USE_QUEUED_RWLOCKS if PPC_QUEUED_SPINLOCKS -@@ -356,10 +357,6 @@ config PPC_OF_PLATFORM_PCI - depends on PCI - depends on PPC64 # not supported on 32 bits yet - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- depends on PPC32 || PPC_BOOK3S_64 -- def_bool y -- - config ARCH_SUPPORTS_UPROBES - def_bool y - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 70271db833831..dc141bd752a2a 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -14,6 +14,7 @@ config RISCV - def_bool y - select ARCH_CLOCKSOURCE_INIT - select ARCH_SUPPORTS_ATOMIC_RMW -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU - select ARCH_HAS_BINFMT_FLAT - select ARCH_HAS_DEBUG_VM_PGTABLE - select ARCH_HAS_DEBUG_VIRTUAL if MMU -@@ -160,9 +161,6 @@ config ARCH_SELECT_MEMORY_MODEL - config ARCH_WANT_GENERAL_HUGETLB - def_bool y - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- def_bool y -- - config SYS_SUPPORTS_HUGETLBFS - depends on MMU - def_bool y -diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h -index 982745572945e..99110223eb0e1 100644 ---- a/arch/riscv/include/asm/pgtable.h -+++ b/arch/riscv/include/asm/pgtable.h -@@ -460,8 +460,6 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, - #define VMALLOC_START _AC(0, UL) - #define VMALLOC_END TASK_SIZE - --static inline void __kernel_map_pages(struct page *page, int numpages, int enable) {} -- - #endif /* !CONFIG_MMU */ - - #define kern_addr_valid(addr) (1) /* FIXME */ -diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c -index 09f6be19ba7b3..ae63a0227e2fb 100644 ---- a/arch/riscv/mm/pageattr.c -+++ b/arch/riscv/mm/pageattr.c -@@ -184,6 +184,7 @@ int set_direct_map_default_noflush(struct page *page) - return ret; - } - -+#ifdef CONFIG_DEBUG_PAGEALLOC - void __kernel_map_pages(struct page *page, int numpages, int enable) - { - if (!debug_pagealloc_enabled()) -@@ -196,3 +197,4 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) - __set_memory((unsigned long)page_address(page), numpages, - __pgprot(0), __pgprot(_PAGE_PRESENT)); - } -+#endif -diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig -index 878993982e39d..cf5b7bb3726f7 100644 ---- a/arch/s390/Kconfig -+++ b/arch/s390/Kconfig -@@ -35,9 +35,6 @@ config GENERIC_LOCKBREAK - config PGSTE - def_bool y if KVM - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- def_bool y -- - config AUDIT_ARCH - def_bool y - -@@ -106,6 +103,7 @@ config S390 - select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE - select ARCH_STACKWALK - select ARCH_SUPPORTS_ATOMIC_RMW -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC - select ARCH_SUPPORTS_NUMA_BALANCING - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_CMPXCHG_LOCKREF -diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig -index 7e2ce4c8d6571..1206bb46dd016 100644 ---- a/arch/sparc/Kconfig -+++ b/arch/sparc/Kconfig -@@ -89,6 +89,7 @@ config SPARC64 - select HAVE_C_RECORDMCOUNT - select HAVE_ARCH_AUDITSYSCALL - select ARCH_SUPPORTS_ATOMIC_RMW -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC - select HAVE_NMI - select HAVE_REGS_AND_STACK_ACCESS_API - select ARCH_USE_QUEUED_RWLOCKS -@@ -149,9 +150,6 @@ config GENERIC_ISA_DMA - bool - default y if SPARC32 - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- def_bool y if SPARC64 -- - config PGTABLE_LEVELS - default 4 if 64BIT - default 3 -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 0c802ade80406..a948d614fbe52 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -94,6 +94,7 @@ config X86 - select ARCH_STACKWALK - select ARCH_SUPPORTS_ACPI - select ARCH_SUPPORTS_ATOMIC_RMW -+ select ARCH_SUPPORTS_DEBUG_PAGEALLOC - select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 - select ARCH_USE_BUILTIN_BSWAP - select ARCH_USE_QUEUED_RWLOCKS -@@ -333,9 +334,6 @@ config ZONE_DMA32 - config AUDIT_ARCH - def_bool y if X86_64 - --config ARCH_SUPPORTS_DEBUG_PAGEALLOC -- def_bool y -- - config KASAN_SHADOW_OFFSET - hex - depends on KASAN -diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c -index 217dda690ed82..57ba2603d481e 100644 ---- a/arch/x86/mm/pat/set_memory.c -+++ b/arch/x86/mm/pat/set_memory.c -@@ -2194,6 +2194,7 @@ int set_direct_map_default_noflush(struct page *page) - return __set_pages_p(page, 1); - } - -+#ifdef CONFIG_DEBUG_PAGEALLOC - void __kernel_map_pages(struct page *page, int numpages, int enable) - { - if (PageHighMem(page)) -@@ -2239,6 +2240,7 @@ bool kernel_page_present(struct page *page) - return (pte_val(*pte) & _PAGE_PRESENT); - } - #endif /* CONFIG_HIBERNATION */ -+#endif /* CONFIG_DEBUG_PAGEALLOC */ - - int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address, - unsigned numpages, unsigned long page_flags) -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 61ed8b20ea704..5c957fbef655b 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -2955,7 +2955,11 @@ static inline bool debug_pagealloc_enabled_static(void) - return static_branch_unlikely(&_debug_pagealloc_enabled); - } - --#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP) -+#ifdef CONFIG_DEBUG_PAGEALLOC -+/* -+ * To support DEBUG_PAGEALLOC architecture must ensure that -+ * __kernel_map_pages() never fails -+ */ - extern void __kernel_map_pages(struct page *page, int numpages, int enable); - - static inline void debug_pagealloc_map_pages(struct page *page, int numpages) -@@ -2973,13 +2977,13 @@ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) - #ifdef CONFIG_HIBERNATION - extern bool kernel_page_present(struct page *page); - #endif /* CONFIG_HIBERNATION */ --#else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ -+#else /* CONFIG_DEBUG_PAGEALLOC */ - static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {} - static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {} - #ifdef CONFIG_HIBERNATION - static inline bool kernel_page_present(struct page *page) { return true; } - #endif /* CONFIG_HIBERNATION */ --#endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ -+#endif /* CONFIG_DEBUG_PAGEALLOC */ - - #ifdef __HAVE_ARCH_GATE_AREA - extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm); --- -2.43.0 - diff --git a/queue-5.10/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch b/queue-5.10/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch deleted file mode 100644 index cc801fa69ba..00000000000 --- a/queue-5.10/clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 4e248c24e73eb129235ddf9172597a6cee057dbd Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 27 May 2024 17:14:12 -0700 -Subject: clk: sifive: Do not register clkdevs for PRCI clocks - -From: Samuel Holland - -[ Upstream commit 2607133196c35f31892ee199ce7ffa717bea4ad1 ] - -These clkdevs were unnecessary, because systems using this driver always -look up clocks using the devicetree. And as Russell King points out[1], -since the provided device name was truncated, lookups via clkdev would -never match. - -Recently, commit 8d532528ff6a ("clkdev: report over-sized strings when -creating clkdev entries") caused clkdev registration to fail due to the -truncation, and this now prevents the driver from probing. Fix the -driver by removing the clkdev registration. - -Link: https://lore.kernel.org/linux-clk/ZkfYqj+OcAxd9O2t@shell.armlinux.org.uk/ [1] -Fixes: 30b8e27e3b58 ("clk: sifive: add a driver for the SiFive FU540 PRCI IP block") -Fixes: 8d532528ff6a ("clkdev: report over-sized strings when creating clkdev entries") -Reported-by: Guenter Roeck -Closes: https://lore.kernel.org/linux-clk/7eda7621-0dde-4153-89e4-172e4c095d01@roeck-us.net/ -Suggested-by: Russell King -Signed-off-by: Samuel Holland -Link: https://lore.kernel.org/r/20240528001432.1200403-1-samuel.holland@sifive.com -Signed-off-by: Stephen Boyd -Signed-off-by: Sasha Levin ---- - drivers/clk/sifive/sifive-prci.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c -index 70653d33f33fe..b043180ad3e5d 100644 ---- a/drivers/clk/sifive/sifive-prci.c -+++ b/drivers/clk/sifive/sifive-prci.c -@@ -4,7 +4,6 @@ - * Copyright (C) 2020 Zong Li - */ - --#include - #include - #include - #include -@@ -317,13 +316,6 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, - return r; - } - -- r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); -- if (r) { -- dev_warn(dev, "Failed to register clkdev for %s: %d\n", -- init.name, r); -- return r; -- } -- - pd->hw_clks.hws[i] = &pic->hw; - } - --- -2.43.0 - diff --git a/queue-5.10/clk-sifive-extract-prci-core-to-common-base.patch b/queue-5.10/clk-sifive-extract-prci-core-to-common-base.patch deleted file mode 100644 index c6ef251ce66..00000000000 --- a/queue-5.10/clk-sifive-extract-prci-core-to-common-base.patch +++ /dev/null @@ -1,1318 +0,0 @@ -From 8fe0f6fb3c2cab46eaff8297d9043035d0ca3fd6 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 9 Dec 2020 17:49:12 +0800 -Subject: clk: sifive: Extract prci core to common base - -From: Zong Li - -[ Upstream commit c816e1ddf2b60b31d121118488c5a854d9a2fad9 ] - -Extract common core of prci driver to an independent file, it could -allow other chips to reuse it. Separate SoCs-dependent code 'fu540' -from prci core, then we can easily add 'fu740' later. - -Almost these changes are code movement. The different is adding the -private data for each SoC use, so it needs to get match data in probe -callback function, then use the data for initialization. - -Signed-off-by: Zong Li -Reviewed-by: Pragnesh Patel -Acked-by: Palmer Dabbelt -Link: https://lore.kernel.org/r/20201209094916.17383-2-zong.li@sifive.com -[sboyd@kernel.org: Include header to silence sparse] -Signed-off-by: Stephen Boyd -Stable-dep-of: 2607133196c3 ("clk: sifive: Do not register clkdevs for PRCI clocks") -Signed-off-by: Sasha Levin ---- - drivers/clk/sifive/Makefile | 2 +- - drivers/clk/sifive/fu540-prci.c | 593 ++----------------------------- - drivers/clk/sifive/fu540-prci.h | 21 ++ - drivers/clk/sifive/sifive-prci.c | 395 ++++++++++++++++++++ - drivers/clk/sifive/sifive-prci.h | 201 +++++++++++ - 5 files changed, 641 insertions(+), 571 deletions(-) - create mode 100644 drivers/clk/sifive/fu540-prci.h - create mode 100644 drivers/clk/sifive/sifive-prci.c - create mode 100644 drivers/clk/sifive/sifive-prci.h - -diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile -index 0797f14fef6b6..51b6ebc359e44 100644 ---- a/drivers/clk/sifive/Makefile -+++ b/drivers/clk/sifive/Makefile -@@ -1,2 +1,2 @@ - # SPDX-License-Identifier: GPL-2.0-only --obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += fu540-prci.o -+obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += sifive-prci.o fu540-prci.o -diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c -index a8901f90a61ac..83ced24b0b949 100644 ---- a/drivers/clk/sifive/fu540-prci.c -+++ b/drivers/clk/sifive/fu540-prci.c -@@ -1,17 +1,9 @@ - // SPDX-License-Identifier: GPL-2.0 - /* - * Copyright (C) 2018-2019 SiFive, Inc. -- * Wesley Terpstra -- * Paul Walmsley -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -+ * Copyright (C) 2018-2019 Wesley Terpstra -+ * Copyright (C) 2018-2019 Paul Walmsley -+ * Copyright (C) 2020 Zong Li - * - * The FU540 PRCI implements clock and reset control for the SiFive - * FU540-C000 chip. This driver assumes that it has sole control -@@ -24,464 +16,47 @@ - * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset" - */ - --#include --#include --#include --#include --#include --#include --#include - #include --#include --#include --#include --#include -- --/* -- * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects: -- * hfclk and rtcclk -- */ --#define EXPECTED_CLK_PARENT_COUNT 2 -- --/* -- * Register offsets and bitmasks -- */ -- --/* COREPLLCFG0 */ --#define PRCI_COREPLLCFG0_OFFSET 0x4 --# define PRCI_COREPLLCFG0_DIVR_SHIFT 0 --# define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT) --# define PRCI_COREPLLCFG0_DIVF_SHIFT 6 --# define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT) --# define PRCI_COREPLLCFG0_DIVQ_SHIFT 15 --# define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT) --# define PRCI_COREPLLCFG0_RANGE_SHIFT 18 --# define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT) --# define PRCI_COREPLLCFG0_BYPASS_SHIFT 24 --# define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT) --# define PRCI_COREPLLCFG0_FSE_SHIFT 25 --# define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT) --# define PRCI_COREPLLCFG0_LOCK_SHIFT 31 --# define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) - --/* DDRPLLCFG0 */ --#define PRCI_DDRPLLCFG0_OFFSET 0xc --# define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 --# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT) --# define PRCI_DDRPLLCFG0_DIVF_SHIFT 6 --# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT) --# define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15 --# define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT) --# define PRCI_DDRPLLCFG0_RANGE_SHIFT 18 --# define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT) --# define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24 --# define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT) --# define PRCI_DDRPLLCFG0_FSE_SHIFT 25 --# define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT) --# define PRCI_DDRPLLCFG0_LOCK_SHIFT 31 --# define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT) -- --/* DDRPLLCFG1 */ --#define PRCI_DDRPLLCFG1_OFFSET 0x10 --# define PRCI_DDRPLLCFG1_CKE_SHIFT 24 --# define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) -- --/* GEMGXLPLLCFG0 */ --#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c --# define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0 --# define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT) --# define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6 --# define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT) --# define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15 --# define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT) --# define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18 --# define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT) --# define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24 --# define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT) --# define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25 --# define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT) --# define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31 --# define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT) -- --/* GEMGXLPLLCFG1 */ --#define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 --# define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 --# define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) -- --/* CORECLKSEL */ --#define PRCI_CORECLKSEL_OFFSET 0x24 --# define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0 --# define PRCI_CORECLKSEL_CORECLKSEL_MASK (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT) -- --/* DEVICESRESETREG */ --#define PRCI_DEVICESRESETREG_OFFSET 0x28 --# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0 --# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT) --# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1 --# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT) --# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2 --# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT) --# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3 --# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT) --# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5 --# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) -+#include - --/* CLKMUXSTATUSREG */ --#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c --# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 --# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) -+#include "fu540-prci.h" -+#include "sifive-prci.h" - --/* -- * Private structures -- */ -+/* PRCI integration data for each WRPLL instance */ - --/** -- * struct __prci_data - per-device-instance data -- * @va: base virtual address of the PRCI IP block -- * @hw_clks: encapsulates struct clk_hw records -- * -- * PRCI per-device instance data -- */ --struct __prci_data { -- void __iomem *va; -- struct clk_hw_onecell_data hw_clks; -+static struct __prci_wrpll_data __prci_corepll_data = { -+ .cfg0_offs = PRCI_COREPLLCFG0_OFFSET, -+ .enable_bypass = sifive_prci_coreclksel_use_hfclk, -+ .disable_bypass = sifive_prci_coreclksel_use_corepll, - }; - --/** -- * struct __prci_wrpll_data - WRPLL configuration and integration data -- * @c: WRPLL current configuration record -- * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL) -- * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL) -- * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address -- * -- * @enable_bypass and @disable_bypass are used for WRPLL instances -- * that contain a separate external glitchless clock mux downstream -- * from the PLL. The WRPLL internal bypass mux is not glitchless. -- */ --struct __prci_wrpll_data { -- struct wrpll_cfg c; -- void (*enable_bypass)(struct __prci_data *pd); -- void (*disable_bypass)(struct __prci_data *pd); -- u8 cfg0_offs; -+static struct __prci_wrpll_data __prci_ddrpll_data = { -+ .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, - }; - --/** -- * struct __prci_clock - describes a clock device managed by PRCI -- * @name: user-readable clock name string - should match the manual -- * @parent_name: parent name for this clock -- * @ops: struct clk_ops for the Linux clock framework to use for control -- * @hw: Linux-private clock data -- * @pwd: WRPLL-specific data, associated with this clock (if not NULL) -- * @pd: PRCI-specific data associated with this clock (if not NULL) -- * -- * PRCI clock data. Used by the PRCI driver to register PRCI-provided -- * clocks to the Linux clock infrastructure. -- */ --struct __prci_clock { -- const char *name; -- const char *parent_name; -- const struct clk_ops *ops; -- struct clk_hw hw; -- struct __prci_wrpll_data *pwd; -- struct __prci_data *pd; -+static struct __prci_wrpll_data __prci_gemgxlpll_data = { -+ .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, - }; - --#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw) -- --/* -- * Private functions -- */ -- --/** -- * __prci_readl() - read from a PRCI register -- * @pd: PRCI context -- * @offs: register offset to read from (in bytes, from PRCI base address) -- * -- * Read the register located at offset @offs from the base virtual -- * address of the PRCI register target described by @pd, and return -- * the value to the caller. -- * -- * Context: Any context. -- * -- * Return: the contents of the register described by @pd and @offs. -- */ --static u32 __prci_readl(struct __prci_data *pd, u32 offs) --{ -- return readl_relaxed(pd->va + offs); --} -- --static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd) --{ -- writel_relaxed(v, pd->va + offs); --} -- --/* WRPLL-related private functions */ -- --/** -- * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters -- * @c: ptr to a struct wrpll_cfg record to write config into -- * @r: value read from the PRCI PLL configuration register -- * -- * Given a value @r read from an FU540 PRCI PLL configuration register, -- * split it into fields and populate it into the WRPLL configuration record -- * pointed to by @c. -- * -- * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros -- * have the same register layout. -- * -- * Context: Any context. -- */ --static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r) --{ -- u32 v; -- -- v = r & PRCI_COREPLLCFG0_DIVR_MASK; -- v >>= PRCI_COREPLLCFG0_DIVR_SHIFT; -- c->divr = v; -- -- v = r & PRCI_COREPLLCFG0_DIVF_MASK; -- v >>= PRCI_COREPLLCFG0_DIVF_SHIFT; -- c->divf = v; -- -- v = r & PRCI_COREPLLCFG0_DIVQ_MASK; -- v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT; -- c->divq = v; -- -- v = r & PRCI_COREPLLCFG0_RANGE_MASK; -- v >>= PRCI_COREPLLCFG0_RANGE_SHIFT; -- c->range = v; -- -- c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK | -- WRPLL_FLAGS_EXT_FEEDBACK_MASK); -- -- /* external feedback mode not supported */ -- c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK; --} -- --/** -- * __prci_wrpll_pack() - pack PLL configuration parameters into a register value -- * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg -- * -- * Using a set of WRPLL configuration values pointed to by @c, -- * assemble a PRCI PLL configuration register value, and return it to -- * the caller. -- * -- * Context: Any context. Caller must ensure that the contents of the -- * record pointed to by @c do not change during the execution -- * of this function. -- * -- * Returns: a value suitable for writing into a PRCI PLL configuration -- * register -- */ --static u32 __prci_wrpll_pack(const struct wrpll_cfg *c) --{ -- u32 r = 0; -- -- r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT; -- r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT; -- r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT; -- r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT; -- -- /* external feedback mode not supported */ -- r |= PRCI_COREPLLCFG0_FSE_MASK; -- -- return r; --} -- --/** -- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI -- * @pd: PRCI context -- * @pwd: PRCI WRPLL metadata -- * -- * Read the current configuration of the PLL identified by @pwd from -- * the PRCI identified by @pd, and store it into the local configuration -- * cache in @pwd. -- * -- * Context: Any context. Caller must prevent the records pointed to by -- * @pd and @pwd from changing during execution. -- */ --static void __prci_wrpll_read_cfg(struct __prci_data *pd, -- struct __prci_wrpll_data *pwd) --{ -- __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); --} -- --/** -- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI -- * @pd: PRCI context -- * @pwd: PRCI WRPLL metadata -- * @c: WRPLL configuration record to write -- * -- * Write the WRPLL configuration described by @c into the WRPLL -- * configuration register identified by @pwd in the PRCI instance -- * described by @c. Make a cached copy of the WRPLL's current -- * configuration so it can be used by other code. -- * -- * Context: Any context. Caller must prevent the records pointed to by -- * @pd and @pwd from changing during execution. -- */ --static void __prci_wrpll_write_cfg(struct __prci_data *pd, -- struct __prci_wrpll_data *pwd, -- struct wrpll_cfg *c) --{ -- __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); -- -- memcpy(&pwd->c, c, sizeof(*c)); --} -- --/* Core clock mux control */ -- --/** -- * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK -- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg -- * -- * Switch the CORECLK mux to the HFCLK input source; return once complete. -- * -- * Context: Any context. Caller must prevent concurrent changes to the -- * PRCI_CORECLKSEL_OFFSET register. -- */ --static void __prci_coreclksel_use_hfclk(struct __prci_data *pd) --{ -- u32 r; -- -- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); -- r |= PRCI_CORECLKSEL_CORECLKSEL_MASK; -- __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); -- -- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ --} -- --/** -- * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL -- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg -- * -- * Switch the CORECLK mux to the PLL output clock; return once complete. -- * -- * Context: Any context. Caller must prevent concurrent changes to the -- * PRCI_CORECLKSEL_OFFSET register. -- */ --static void __prci_coreclksel_use_corepll(struct __prci_data *pd) --{ -- u32 r; -- -- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); -- r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK; -- __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); -- -- r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ --} -- --/* -- * Linux clock framework integration -- * -- * See the Linux clock framework documentation for more information on -- * these functions. -- */ -- --static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw, -- unsigned long parent_rate) --{ -- struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -- struct __prci_wrpll_data *pwd = pc->pwd; -- -- return wrpll_calc_output_rate(&pwd->c, parent_rate); --} -- --static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw, -- unsigned long rate, -- unsigned long *parent_rate) --{ -- struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -- struct __prci_wrpll_data *pwd = pc->pwd; -- struct wrpll_cfg c; -- -- memcpy(&c, &pwd->c, sizeof(c)); -- -- wrpll_configure_for_rate(&c, rate, *parent_rate); -- -- return wrpll_calc_output_rate(&c, *parent_rate); --} -- --static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw, -- unsigned long rate, -- unsigned long parent_rate) --{ -- struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -- struct __prci_wrpll_data *pwd = pc->pwd; -- struct __prci_data *pd = pc->pd; -- int r; -- -- r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); -- if (r) -- return r; -- -- if (pwd->enable_bypass) -- pwd->enable_bypass(pd); -- -- __prci_wrpll_write_cfg(pd, pwd, &pwd->c); -- -- udelay(wrpll_calc_max_lock_us(&pwd->c)); -- -- if (pwd->disable_bypass) -- pwd->disable_bypass(pd); -- -- return 0; --} -+/* Linux clock framework integration */ - - static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = { -- .set_rate = sifive_fu540_prci_wrpll_set_rate, -- .round_rate = sifive_fu540_prci_wrpll_round_rate, -- .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, -+ .set_rate = sifive_prci_wrpll_set_rate, -+ .round_rate = sifive_prci_wrpll_round_rate, -+ .recalc_rate = sifive_prci_wrpll_recalc_rate, - }; - - static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = { -- .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, -+ .recalc_rate = sifive_prci_wrpll_recalc_rate, - }; - --/* TLCLKSEL clock integration */ -- --static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw, -- unsigned long parent_rate) --{ -- struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -- struct __prci_data *pd = pc->pd; -- u32 v; -- u8 div; -- -- v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET); -- v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK; -- div = v ? 1 : 2; -- -- return div_u64(parent_rate, div); --} -- - static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = { -- .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate, --}; -- --/* -- * PRCI integration data for each WRPLL instance -- */ -- --static struct __prci_wrpll_data __prci_corepll_data = { -- .cfg0_offs = PRCI_COREPLLCFG0_OFFSET, -- .enable_bypass = __prci_coreclksel_use_hfclk, -- .disable_bypass = __prci_coreclksel_use_corepll, --}; -- --static struct __prci_wrpll_data __prci_ddrpll_data = { -- .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, -+ .recalc_rate = sifive_prci_tlclksel_recalc_rate, - }; - --static struct __prci_wrpll_data __prci_gemgxlpll_data = { -- .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, --}; -- --/* -- * List of clock controls provided by the PRCI -- */ -- --static struct __prci_clock __prci_init_clocks[] = { -+/* List of clock controls provided by the PRCI */ -+struct __prci_clock __prci_init_clocks_fu540[] = { - [PRCI_CLK_COREPLL] = { - .name = "corepll", - .parent_name = "hfclk", -@@ -506,125 +81,3 @@ static struct __prci_clock __prci_init_clocks[] = { - .ops = &sifive_fu540_prci_tlclksel_clk_ops, - }, - }; -- --/** -- * __prci_register_clocks() - register clock controls in the PRCI with Linux -- * @dev: Linux struct device * -- * -- * Register the list of clock controls described in __prci_init_plls[] with -- * the Linux clock framework. -- * -- * Return: 0 upon success or a negative error code upon failure. -- */ --static int __prci_register_clocks(struct device *dev, struct __prci_data *pd) --{ -- struct clk_init_data init = { }; -- struct __prci_clock *pic; -- int parent_count, i, r; -- -- parent_count = of_clk_get_parent_count(dev->of_node); -- if (parent_count != EXPECTED_CLK_PARENT_COUNT) { -- dev_err(dev, "expected only two parent clocks, found %d\n", -- parent_count); -- return -EINVAL; -- } -- -- /* Register PLLs */ -- for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) { -- pic = &__prci_init_clocks[i]; -- -- init.name = pic->name; -- init.parent_names = &pic->parent_name; -- init.num_parents = 1; -- init.ops = pic->ops; -- pic->hw.init = &init; -- -- pic->pd = pd; -- -- if (pic->pwd) -- __prci_wrpll_read_cfg(pd, pic->pwd); -- -- r = devm_clk_hw_register(dev, &pic->hw); -- if (r) { -- dev_warn(dev, "Failed to register clock %s: %d\n", -- init.name, r); -- return r; -- } -- -- r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); -- if (r) { -- dev_warn(dev, "Failed to register clkdev for %s: %d\n", -- init.name, r); -- return r; -- } -- -- pd->hw_clks.hws[i] = &pic->hw; -- } -- -- pd->hw_clks.num = i; -- -- r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, -- &pd->hw_clks); -- if (r) { -- dev_err(dev, "could not add hw_provider: %d\n", r); -- return r; -- } -- -- return 0; --} -- --/* -- * Linux device model integration -- * -- * See the Linux device model documentation for more information about -- * these functions. -- */ --static int sifive_fu540_prci_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct resource *res; -- struct __prci_data *pd; -- int r; -- -- pd = devm_kzalloc(dev, -- struct_size(pd, hw_clks.hws, -- ARRAY_SIZE(__prci_init_clocks)), -- GFP_KERNEL); -- if (!pd) -- return -ENOMEM; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- pd->va = devm_ioremap_resource(dev, res); -- if (IS_ERR(pd->va)) -- return PTR_ERR(pd->va); -- -- r = __prci_register_clocks(dev, pd); -- if (r) { -- dev_err(dev, "could not register clocks: %d\n", r); -- return r; -- } -- -- dev_dbg(dev, "SiFive FU540 PRCI probed\n"); -- -- return 0; --} -- --static const struct of_device_id sifive_fu540_prci_of_match[] = { -- { .compatible = "sifive,fu540-c000-prci", }, -- {} --}; --MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match); -- --static struct platform_driver sifive_fu540_prci_driver = { -- .driver = { -- .name = "sifive-fu540-prci", -- .of_match_table = sifive_fu540_prci_of_match, -- }, -- .probe = sifive_fu540_prci_probe, --}; -- --static int __init sifive_fu540_prci_init(void) --{ -- return platform_driver_register(&sifive_fu540_prci_driver); --} --core_initcall(sifive_fu540_prci_init); -diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h -new file mode 100644 -index 0000000000000..c8271efa7bdc7 ---- /dev/null -+++ b/drivers/clk/sifive/fu540-prci.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2020 SiFive, Inc. -+ * Zong Li -+ */ -+ -+#ifndef __SIFIVE_CLK_FU540_PRCI_H -+#define __SIFIVE_CLK_FU540_PRCI_H -+ -+#include "sifive-prci.h" -+ -+#define NUM_CLOCK_FU540 4 -+ -+extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540]; -+ -+static const struct prci_clk_desc prci_clk_fu540 = { -+ .clks = __prci_init_clocks_fu540, -+ .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540), -+}; -+ -+#endif /* __SIFIVE_CLK_FU540_PRCI_H */ -diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c -new file mode 100644 -index 0000000000000..70653d33f33fe ---- /dev/null -+++ b/drivers/clk/sifive/sifive-prci.c -@@ -0,0 +1,395 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2020 SiFive, Inc. -+ * Copyright (C) 2020 Zong Li -+ */ -+ -+#include -+#include -+#include -+#include -+#include "sifive-prci.h" -+#include "fu540-prci.h" -+ -+/* -+ * Private functions -+ */ -+ -+/** -+ * __prci_readl() - read from a PRCI register -+ * @pd: PRCI context -+ * @offs: register offset to read from (in bytes, from PRCI base address) -+ * -+ * Read the register located at offset @offs from the base virtual -+ * address of the PRCI register target described by @pd, and return -+ * the value to the caller. -+ * -+ * Context: Any context. -+ * -+ * Return: the contents of the register described by @pd and @offs. -+ */ -+static u32 __prci_readl(struct __prci_data *pd, u32 offs) -+{ -+ return readl_relaxed(pd->va + offs); -+} -+ -+static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd) -+{ -+ writel_relaxed(v, pd->va + offs); -+} -+ -+/* WRPLL-related private functions */ -+ -+/** -+ * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters -+ * @c: ptr to a struct wrpll_cfg record to write config into -+ * @r: value read from the PRCI PLL configuration register -+ * -+ * Given a value @r read from an FU740 PRCI PLL configuration register, -+ * split it into fields and populate it into the WRPLL configuration record -+ * pointed to by @c. -+ * -+ * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros -+ * have the same register layout. -+ * -+ * Context: Any context. -+ */ -+static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r) -+{ -+ u32 v; -+ -+ v = r & PRCI_COREPLLCFG0_DIVR_MASK; -+ v >>= PRCI_COREPLLCFG0_DIVR_SHIFT; -+ c->divr = v; -+ -+ v = r & PRCI_COREPLLCFG0_DIVF_MASK; -+ v >>= PRCI_COREPLLCFG0_DIVF_SHIFT; -+ c->divf = v; -+ -+ v = r & PRCI_COREPLLCFG0_DIVQ_MASK; -+ v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT; -+ c->divq = v; -+ -+ v = r & PRCI_COREPLLCFG0_RANGE_MASK; -+ v >>= PRCI_COREPLLCFG0_RANGE_SHIFT; -+ c->range = v; -+ -+ c->flags &= -+ (WRPLL_FLAGS_INT_FEEDBACK_MASK | WRPLL_FLAGS_EXT_FEEDBACK_MASK); -+ -+ /* external feedback mode not supported */ -+ c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK; -+} -+ -+/** -+ * __prci_wrpll_pack() - pack PLL configuration parameters into a register value -+ * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg -+ * -+ * Using a set of WRPLL configuration values pointed to by @c, -+ * assemble a PRCI PLL configuration register value, and return it to -+ * the caller. -+ * -+ * Context: Any context. Caller must ensure that the contents of the -+ * record pointed to by @c do not change during the execution -+ * of this function. -+ * -+ * Returns: a value suitable for writing into a PRCI PLL configuration -+ * register -+ */ -+static u32 __prci_wrpll_pack(const struct wrpll_cfg *c) -+{ -+ u32 r = 0; -+ -+ r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT; -+ r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT; -+ r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT; -+ r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT; -+ -+ /* external feedback mode not supported */ -+ r |= PRCI_COREPLLCFG0_FSE_MASK; -+ -+ return r; -+} -+ -+/** -+ * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI -+ * @pd: PRCI context -+ * @pwd: PRCI WRPLL metadata -+ * -+ * Read the current configuration of the PLL identified by @pwd from -+ * the PRCI identified by @pd, and store it into the local configuration -+ * cache in @pwd. -+ * -+ * Context: Any context. Caller must prevent the records pointed to by -+ * @pd and @pwd from changing during execution. -+ */ -+static void __prci_wrpll_read_cfg(struct __prci_data *pd, -+ struct __prci_wrpll_data *pwd) -+{ -+ __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); -+} -+ -+/** -+ * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI -+ * @pd: PRCI context -+ * @pwd: PRCI WRPLL metadata -+ * @c: WRPLL configuration record to write -+ * -+ * Write the WRPLL configuration described by @c into the WRPLL -+ * configuration register identified by @pwd in the PRCI instance -+ * described by @c. Make a cached copy of the WRPLL's current -+ * configuration so it can be used by other code. -+ * -+ * Context: Any context. Caller must prevent the records pointed to by -+ * @pd and @pwd from changing during execution. -+ */ -+static void __prci_wrpll_write_cfg(struct __prci_data *pd, -+ struct __prci_wrpll_data *pwd, -+ struct wrpll_cfg *c) -+{ -+ __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); -+ -+ memcpy(&pwd->c, c, sizeof(*c)); -+} -+ -+/* -+ * Linux clock framework integration -+ * -+ * See the Linux clock framework documentation for more information on -+ * these functions. -+ */ -+ -+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -+ struct __prci_wrpll_data *pwd = pc->pwd; -+ -+ return wrpll_calc_output_rate(&pwd->c, parent_rate); -+} -+ -+long sifive_prci_wrpll_round_rate(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -+ struct __prci_wrpll_data *pwd = pc->pwd; -+ struct wrpll_cfg c; -+ -+ memcpy(&c, &pwd->c, sizeof(c)); -+ -+ wrpll_configure_for_rate(&c, rate, *parent_rate); -+ -+ return wrpll_calc_output_rate(&c, *parent_rate); -+} -+ -+int sifive_prci_wrpll_set_rate(struct clk_hw *hw, -+ unsigned long rate, unsigned long parent_rate) -+{ -+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -+ struct __prci_wrpll_data *pwd = pc->pwd; -+ struct __prci_data *pd = pc->pd; -+ int r; -+ -+ r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); -+ if (r) -+ return r; -+ -+ if (pwd->enable_bypass) -+ pwd->enable_bypass(pd); -+ -+ __prci_wrpll_write_cfg(pd, pwd, &pwd->c); -+ -+ udelay(wrpll_calc_max_lock_us(&pwd->c)); -+ -+ if (pwd->disable_bypass) -+ pwd->disable_bypass(pd); -+ -+ return 0; -+} -+ -+/* TLCLKSEL clock integration */ -+ -+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct __prci_clock *pc = clk_hw_to_prci_clock(hw); -+ struct __prci_data *pd = pc->pd; -+ u32 v; -+ u8 div; -+ -+ v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET); -+ v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK; -+ div = v ? 1 : 2; -+ -+ return div_u64(parent_rate, div); -+} -+ -+/* -+ * Core clock mux control -+ */ -+ -+/** -+ * sifive_prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK -+ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg -+ * -+ * Switch the CORECLK mux to the HFCLK input source; return once complete. -+ * -+ * Context: Any context. Caller must prevent concurrent changes to the -+ * PRCI_CORECLKSEL_OFFSET register. -+ */ -+void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd) -+{ -+ u32 r; -+ -+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); -+ r |= PRCI_CORECLKSEL_CORECLKSEL_MASK; -+ __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); -+ -+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ -+} -+ -+/** -+ * sifive_prci_coreclksel_use_corepll() - switch the CORECLK mux to output -+ * COREPLL -+ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg -+ * -+ * Switch the CORECLK mux to the COREPLL output clock; return once complete. -+ * -+ * Context: Any context. Caller must prevent concurrent changes to the -+ * PRCI_CORECLKSEL_OFFSET register. -+ */ -+void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd) -+{ -+ u32 r; -+ -+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); -+ r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK; -+ __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); -+ -+ r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ -+} -+ -+/** -+ * __prci_register_clocks() - register clock controls in the PRCI -+ * @dev: Linux struct device -+ * @pd: The pointer for PRCI per-device instance data -+ * @desc: The pointer for the information of clocks of each SoCs -+ * -+ * Register the list of clock controls described in __prci_init_clocks[] with -+ * the Linux clock framework. -+ * -+ * Return: 0 upon success or a negative error code upon failure. -+ */ -+static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, -+ const struct prci_clk_desc *desc) -+{ -+ struct clk_init_data init = { }; -+ struct __prci_clock *pic; -+ int parent_count, i, r; -+ -+ parent_count = of_clk_get_parent_count(dev->of_node); -+ if (parent_count != EXPECTED_CLK_PARENT_COUNT) { -+ dev_err(dev, "expected only two parent clocks, found %d\n", -+ parent_count); -+ return -EINVAL; -+ } -+ -+ /* Register PLLs */ -+ for (i = 0; i < desc->num_clks; ++i) { -+ pic = &(desc->clks[i]); -+ -+ init.name = pic->name; -+ init.parent_names = &pic->parent_name; -+ init.num_parents = 1; -+ init.ops = pic->ops; -+ pic->hw.init = &init; -+ -+ pic->pd = pd; -+ -+ if (pic->pwd) -+ __prci_wrpll_read_cfg(pd, pic->pwd); -+ -+ r = devm_clk_hw_register(dev, &pic->hw); -+ if (r) { -+ dev_warn(dev, "Failed to register clock %s: %d\n", -+ init.name, r); -+ return r; -+ } -+ -+ r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); -+ if (r) { -+ dev_warn(dev, "Failed to register clkdev for %s: %d\n", -+ init.name, r); -+ return r; -+ } -+ -+ pd->hw_clks.hws[i] = &pic->hw; -+ } -+ -+ pd->hw_clks.num = i; -+ -+ r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, -+ &pd->hw_clks); -+ if (r) { -+ dev_err(dev, "could not add hw_provider: %d\n", r); -+ return r; -+ } -+ -+ return 0; -+} -+ -+/** -+ * sifive_prci_init() - initialize prci data and check parent count -+ * @pdev: platform device pointer for the prci -+ * -+ * Return: 0 upon success or a negative error code upon failure. -+ */ -+static int sifive_prci_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct resource *res; -+ struct __prci_data *pd; -+ const struct prci_clk_desc *desc; -+ int r; -+ -+ desc = of_device_get_match_data(&pdev->dev); -+ -+ pd = devm_kzalloc(dev, struct_size(pd, hw_clks.hws, desc->num_clks), GFP_KERNEL); -+ if (!pd) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pd->va = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pd->va)) -+ return PTR_ERR(pd->va); -+ -+ r = __prci_register_clocks(dev, pd, desc); -+ if (r) { -+ dev_err(dev, "could not register clocks: %d\n", r); -+ return r; -+ } -+ -+ dev_dbg(dev, "SiFive PRCI probed\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id sifive_prci_of_match[] = { -+ {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540}, -+ {} -+}; -+ -+static struct platform_driver sifive_prci_driver = { -+ .driver = { -+ .name = "sifive-clk-prci", -+ .of_match_table = sifive_prci_of_match, -+ }, -+ .probe = sifive_prci_probe, -+}; -+ -+static int __init sifive_prci_init(void) -+{ -+ return platform_driver_register(&sifive_prci_driver); -+} -+core_initcall(sifive_prci_init); -diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h -new file mode 100644 -index 0000000000000..280df63b4b928 ---- /dev/null -+++ b/drivers/clk/sifive/sifive-prci.h -@@ -0,0 +1,201 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018-2019 SiFive, Inc. -+ * Wesley Terpstra -+ * Paul Walmsley -+ * Zong Li -+ */ -+ -+#ifndef __SIFIVE_CLK_SIFIVE_PRCI_H -+#define __SIFIVE_CLK_SIFIVE_PRCI_H -+ -+#include -+#include -+#include -+ -+/* -+ * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects: -+ * hfclk and rtcclk -+ */ -+#define EXPECTED_CLK_PARENT_COUNT 2 -+ -+/* -+ * Register offsets and bitmasks -+ */ -+ -+/* COREPLLCFG0 */ -+#define PRCI_COREPLLCFG0_OFFSET 0x4 -+#define PRCI_COREPLLCFG0_DIVR_SHIFT 0 -+#define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT) -+#define PRCI_COREPLLCFG0_DIVF_SHIFT 6 -+#define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT) -+#define PRCI_COREPLLCFG0_DIVQ_SHIFT 15 -+#define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT) -+#define PRCI_COREPLLCFG0_RANGE_SHIFT 18 -+#define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT) -+#define PRCI_COREPLLCFG0_BYPASS_SHIFT 24 -+#define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT) -+#define PRCI_COREPLLCFG0_FSE_SHIFT 25 -+#define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT) -+#define PRCI_COREPLLCFG0_LOCK_SHIFT 31 -+#define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) -+ -+/* DDRPLLCFG0 */ -+#define PRCI_DDRPLLCFG0_OFFSET 0xc -+#define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 -+#define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT) -+#define PRCI_DDRPLLCFG0_DIVF_SHIFT 6 -+#define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT) -+#define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15 -+#define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT) -+#define PRCI_DDRPLLCFG0_RANGE_SHIFT 18 -+#define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT) -+#define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24 -+#define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT) -+#define PRCI_DDRPLLCFG0_FSE_SHIFT 25 -+#define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT) -+#define PRCI_DDRPLLCFG0_LOCK_SHIFT 31 -+#define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT) -+ -+/* DDRPLLCFG1 */ -+#define PRCI_DDRPLLCFG1_OFFSET 0x10 -+#define PRCI_DDRPLLCFG1_CKE_SHIFT 24 -+#define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) -+ -+/* GEMGXLPLLCFG0 */ -+#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c -+#define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0 -+#define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6 -+#define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15 -+#define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18 -+#define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24 -+#define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25 -+#define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT) -+#define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31 -+#define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT) -+ -+/* GEMGXLPLLCFG1 */ -+#define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 -+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 -+#define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) -+ -+/* CORECLKSEL */ -+#define PRCI_CORECLKSEL_OFFSET 0x24 -+#define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0 -+#define PRCI_CORECLKSEL_CORECLKSEL_MASK \ -+ (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT) -+ -+/* DEVICESRESETREG */ -+#define PRCI_DEVICESRESETREG_OFFSET 0x28 -+#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0 -+#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT) -+#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1 -+#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT) -+#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2 -+#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT) -+#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3 -+#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT) -+#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5 -+#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) -+#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT 6 -+#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK \ -+ (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT) -+ -+/* CLKMUXSTATUSREG */ -+#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c -+#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 -+#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \ -+ (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) -+ -+/* -+ * Private structures -+ */ -+ -+/** -+ * struct __prci_data - per-device-instance data -+ * @va: base virtual address of the PRCI IP block -+ * @hw_clks: encapsulates struct clk_hw records -+ * -+ * PRCI per-device instance data -+ */ -+struct __prci_data { -+ void __iomem *va; -+ struct clk_hw_onecell_data hw_clks; -+}; -+ -+/** -+ * struct __prci_wrpll_data - WRPLL configuration and integration data -+ * @c: WRPLL current configuration record -+ * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL) -+ * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL) -+ * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address -+ * -+ * @enable_bypass and @disable_bypass are used for WRPLL instances -+ * that contain a separate external glitchless clock mux downstream -+ * from the PLL. The WRPLL internal bypass mux is not glitchless. -+ */ -+struct __prci_wrpll_data { -+ struct wrpll_cfg c; -+ void (*enable_bypass)(struct __prci_data *pd); -+ void (*disable_bypass)(struct __prci_data *pd); -+ u8 cfg0_offs; -+}; -+ -+/** -+ * struct __prci_clock - describes a clock device managed by PRCI -+ * @name: user-readable clock name string - should match the manual -+ * @parent_name: parent name for this clock -+ * @ops: struct clk_ops for the Linux clock framework to use for control -+ * @hw: Linux-private clock data -+ * @pwd: WRPLL-specific data, associated with this clock (if not NULL) -+ * @pd: PRCI-specific data associated with this clock (if not NULL) -+ * -+ * PRCI clock data. Used by the PRCI driver to register PRCI-provided -+ * clocks to the Linux clock infrastructure. -+ */ -+struct __prci_clock { -+ const char *name; -+ const char *parent_name; -+ const struct clk_ops *ops; -+ struct clk_hw hw; -+ struct __prci_wrpll_data *pwd; -+ struct __prci_data *pd; -+}; -+ -+#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw) -+ -+/* -+ * struct prci_clk_desc - describes the information of clocks of each SoCs -+ * @clks: point to a array of __prci_clock -+ * @num_clks: the number of element of clks -+ */ -+struct prci_clk_desc { -+ struct __prci_clock *clks; -+ size_t num_clks; -+}; -+ -+/* Core clock mux control */ -+void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd); -+void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd); -+ -+/* Linux clock framework integration */ -+long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate); -+int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate); -+unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate); -+unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate); -+ -+#endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */ --- -2.43.0 - diff --git a/queue-5.10/i2c-acpi-unbind-mux-adapters-before-delete.patch b/queue-5.10/i2c-acpi-unbind-mux-adapters-before-delete.patch deleted file mode 100644 index 59a20bb2678..00000000000 --- a/queue-5.10/i2c-acpi-unbind-mux-adapters-before-delete.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 130ab3c5df5ac2b9abb9ac6915c9c7a0e0985d72 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 13 Mar 2024 11:16:32 +1300 -Subject: i2c: acpi: Unbind mux adapters before delete - -From: Hamish Martin - -[ Upstream commit 3f858bbf04dbac934ac279aaee05d49eb9910051 ] - -There is an issue with ACPI overlay table removal specifically related -to I2C multiplexers. - -Consider an ACPI SSDT Overlay that defines a PCA9548 I2C mux on an -existing I2C bus. When this table is loaded we see the creation of a -device for the overall PCA9548 chip and 8 further devices - one -i2c_adapter each for the mux channels. These are all bound to their -ACPI equivalents via an eventual invocation of acpi_bind_one(). - -When we unload the SSDT overlay we run into the problem. The ACPI -devices are deleted as normal via acpi_device_del_work_fn() and the -acpi_device_del_list. - -However, the following warning and stack trace is output as the -deletion does not go smoothly: -------------[ cut here ]------------ -kernfs: can not remove 'physical_node', no directory -WARNING: CPU: 1 PID: 11 at fs/kernfs/dir.c:1674 kernfs_remove_by_name_ns+0xb9/0xc0 -Modules linked in: -CPU: 1 PID: 11 Comm: kworker/u128:0 Not tainted 6.8.0-rc6+ #1 -Hardware name: congatec AG conga-B7E3/conga-B7E3, BIOS 5.13 05/16/2023 -Workqueue: kacpi_hotplug acpi_device_del_work_fn -RIP: 0010:kernfs_remove_by_name_ns+0xb9/0xc0 -Code: e4 00 48 89 ef e8 07 71 db ff 5b b8 fe ff ff ff 5d 41 5c 41 5d e9 a7 55 e4 00 0f 0b eb a6 48 c7 c7 f0 38 0d 9d e8 97 0a d5 ff <0f> 0b eb dc 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 -RSP: 0018:ffff9f864008fb28 EFLAGS: 00010286 -RAX: 0000000000000000 RBX: ffff8ef90a8d4940 RCX: 0000000000000000 -RDX: ffff8f000e267d10 RSI: ffff8f000e25c780 RDI: ffff8f000e25c780 -RBP: ffff8ef9186f9870 R08: 0000000000013ffb R09: 00000000ffffbfff -R10: 00000000ffffbfff R11: ffff8f000e0a0000 R12: ffff9f864008fb50 -R13: ffff8ef90c93dd60 R14: ffff8ef9010d0958 R15: ffff8ef9186f98c8 -FS: 0000000000000000(0000) GS:ffff8f000e240000(0000) knlGS:0000000000000000 -CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 -CR2: 00007f48f5253a08 CR3: 00000003cb82e000 CR4: 00000000003506f0 -Call Trace: - - ? kernfs_remove_by_name_ns+0xb9/0xc0 - ? __warn+0x7c/0x130 - ? kernfs_remove_by_name_ns+0xb9/0xc0 - ? report_bug+0x171/0x1a0 - ? handle_bug+0x3c/0x70 - ? exc_invalid_op+0x17/0x70 - ? asm_exc_invalid_op+0x1a/0x20 - ? kernfs_remove_by_name_ns+0xb9/0xc0 - ? kernfs_remove_by_name_ns+0xb9/0xc0 - acpi_unbind_one+0x108/0x180 - device_del+0x18b/0x490 - ? srso_return_thunk+0x5/0x5f - ? srso_return_thunk+0x5/0x5f - device_unregister+0xd/0x30 - i2c_del_adapter.part.0+0x1bf/0x250 - i2c_mux_del_adapters+0xa1/0xe0 - i2c_device_remove+0x1e/0x80 - device_release_driver_internal+0x19a/0x200 - bus_remove_device+0xbf/0x100 - device_del+0x157/0x490 - ? __pfx_device_match_fwnode+0x10/0x10 - ? srso_return_thunk+0x5/0x5f - device_unregister+0xd/0x30 - i2c_acpi_notify+0x10f/0x140 - notifier_call_chain+0x58/0xd0 - blocking_notifier_call_chain+0x3a/0x60 - acpi_device_del_work_fn+0x85/0x1d0 - process_one_work+0x134/0x2f0 - worker_thread+0x2f0/0x410 - ? __pfx_worker_thread+0x10/0x10 - kthread+0xe3/0x110 - ? __pfx_kthread+0x10/0x10 - ret_from_fork+0x2f/0x50 - ? __pfx_kthread+0x10/0x10 - ret_from_fork_asm+0x1b/0x30 - ----[ end trace 0000000000000000 ]--- -... -repeated 7 more times, 1 for each channel of the mux -... - -The issue is that the binding of the ACPI devices to their peer I2C -adapters is not correctly cleaned up. Digging deeper into the issue we -see that the deletion order is such that the ACPI devices matching the -mux channel i2c adapters are deleted first during the SSDT overlay -removal. For each of the channels we see a call to i2c_acpi_notify() -with ACPI_RECONFIG_DEVICE_REMOVE but, because these devices are not -actually i2c_clients, nothing is done for them. - -Later on, after each of the mux channels has been dealt with, we come -to delete the i2c_client representing the PCA9548 device. This is the -call stack we see above, whereby the kernel cleans up the i2c_client -including destruction of the mux and its channel adapters. At this -point we do attempt to unbind from the ACPI peers but those peers no -longer exist and so we hit the kernfs errors. - -The fix is to augment i2c_acpi_notify() to handle i2c_adapters. But, -given that the life cycle of the adapters is linked to the i2c_client, -instead of deleting the i2c_adapters during the i2c_acpi_notify(), we -just trigger unbinding of the ACPI device from the adapter device, and -allow the clean up of the adapter to continue in the way it always has. - -Signed-off-by: Hamish Martin -Reviewed-by: Mika Westerberg -Reviewed-by: Andi Shyti -Fixes: 525e6fabeae2 ("i2c / ACPI: add support for ACPI reconfigure notifications") -Cc: # v4.8+ -Signed-off-by: Wolfram Sang -Signed-off-by: Sasha Levin ---- - drivers/i2c/i2c-core-acpi.c | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c -index cdc10688d6bdf..ef2326ac15d23 100644 ---- a/drivers/i2c/i2c-core-acpi.c -+++ b/drivers/i2c/i2c-core-acpi.c -@@ -396,6 +396,11 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) - return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); - } - -+static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev) -+{ -+ return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev)); -+} -+ - static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, - void *arg) - { -@@ -422,11 +427,17 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, - break; - - client = i2c_acpi_find_client_by_adev(adev); -- if (!client) -- break; -+ if (client) { -+ i2c_unregister_device(client); -+ put_device(&client->dev); -+ } -+ -+ adapter = i2c_acpi_find_adapter_by_adev(adev); -+ if (adapter) { -+ acpi_unbind_one(&adapter->dev); -+ put_device(&adapter->dev); -+ } - -- i2c_unregister_device(client); -- put_device(&client->dev); - break; - } - --- -2.43.0 - diff --git a/queue-5.10/i2c-add-fwnode-apis.patch b/queue-5.10/i2c-add-fwnode-apis.patch deleted file mode 100644 index 0347fc518df..00000000000 --- a/queue-5.10/i2c-add-fwnode-apis.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 4ad6f37bdf7a6a52db69f154b835c23085db97d3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 11 Jan 2023 10:54:21 +0000 -Subject: i2c: add fwnode APIs - -From: Russell King (Oracle) - -[ Upstream commit 373c612d72461ddaea223592df31e62c934aae61 ] - -Add fwnode APIs for finding and getting I2C adapters, which will be -used by the SFP code. These are passed the fwnode corresponding to -the adapter, and return the I2C adapter. It is the responsibility of -the caller to find the appropriate fwnode. - -We keep the DT and ACPI interfaces, but where appropriate, recode them -to use the fwnode interfaces internally. - -Reviewed-by: Mika Westerberg -Signed-off-by: Russell King (Oracle) -Signed-off-by: Wolfram Sang -Stable-dep-of: 3f858bbf04db ("i2c: acpi: Unbind mux adapters before delete") -Signed-off-by: Sasha Levin ---- - drivers/i2c/i2c-core-acpi.c | 13 +---- - drivers/i2c/i2c-core-base.c | 98 +++++++++++++++++++++++++++++++++++++ - drivers/i2c/i2c-core-of.c | 66 ------------------------- - include/linux/i2c.h | 24 +++++++-- - 4 files changed, 120 insertions(+), 81 deletions(-) - -diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c -index 4b136d8710743..cdc10688d6bdf 100644 ---- a/drivers/i2c/i2c-core-acpi.c -+++ b/drivers/i2c/i2c-core-acpi.c -@@ -393,18 +393,7 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); - - static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) - { -- struct device *dev; -- struct i2c_client *client; -- -- dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); -- if (!dev) -- return NULL; -- -- client = i2c_verify_client(dev); -- if (!client) -- put_device(dev); -- -- return client; -+ return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev)); - } - - static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, -diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c -index 8d4fa896d7909..e598cb7b31e18 100644 ---- a/drivers/i2c/i2c-core-base.c -+++ b/drivers/i2c/i2c-core-base.c -@@ -966,6 +966,35 @@ void i2c_unregister_device(struct i2c_client *client) - } - EXPORT_SYMBOL_GPL(i2c_unregister_device); - -+/** -+ * i2c_find_device_by_fwnode() - find an i2c_client for the fwnode -+ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_client -+ * -+ * Look up and return the &struct i2c_client corresponding to the @fwnode. -+ * If no client can be found, or @fwnode is NULL, this returns NULL. -+ * -+ * The user must call put_device(&client->dev) once done with the i2c client. -+ */ -+struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode) -+{ -+ struct i2c_client *client; -+ struct device *dev; -+ -+ if (!fwnode) -+ return NULL; -+ -+ dev = bus_find_device_by_fwnode(&i2c_bus_type, fwnode); -+ if (!dev) -+ return NULL; -+ -+ client = i2c_verify_client(dev); -+ if (!client) -+ put_device(dev); -+ -+ return client; -+} -+EXPORT_SYMBOL(i2c_find_device_by_fwnode); -+ - - static const struct i2c_device_id dummy_id[] = { - { "dummy", 0 }, -@@ -1731,6 +1760,75 @@ int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter) - } - EXPORT_SYMBOL_GPL(devm_i2c_add_adapter); - -+static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data) -+{ -+ if (dev_fwnode(dev) == data) -+ return 1; -+ -+ if (dev->parent && dev_fwnode(dev->parent) == data) -+ return 1; -+ -+ return 0; -+} -+ -+/** -+ * i2c_find_adapter_by_fwnode() - find an i2c_adapter for the fwnode -+ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter -+ * -+ * Look up and return the &struct i2c_adapter corresponding to the @fwnode. -+ * If no adapter can be found, or @fwnode is NULL, this returns NULL. -+ * -+ * The user must call put_device(&adapter->dev) once done with the i2c adapter. -+ */ -+struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) -+{ -+ struct i2c_adapter *adapter; -+ struct device *dev; -+ -+ if (!fwnode) -+ return NULL; -+ -+ dev = bus_find_device(&i2c_bus_type, NULL, fwnode, -+ i2c_dev_or_parent_fwnode_match); -+ if (!dev) -+ return NULL; -+ -+ adapter = i2c_verify_adapter(dev); -+ if (!adapter) -+ put_device(dev); -+ -+ return adapter; -+} -+EXPORT_SYMBOL(i2c_find_adapter_by_fwnode); -+ -+/** -+ * i2c_get_adapter_by_fwnode() - find an i2c_adapter for the fwnode -+ * @fwnode: &struct fwnode_handle corresponding to the &struct i2c_adapter -+ * -+ * Look up and return the &struct i2c_adapter corresponding to the @fwnode, -+ * and increment the adapter module's use count. If no adapter can be found, -+ * or @fwnode is NULL, this returns NULL. -+ * -+ * The user must call i2c_put_adapter(adapter) once done with the i2c adapter. -+ * Note that this is different from i2c_find_adapter_by_node(). -+ */ -+struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode) -+{ -+ struct i2c_adapter *adapter; -+ -+ adapter = i2c_find_adapter_by_fwnode(fwnode); -+ if (!adapter) -+ return NULL; -+ -+ if (!try_module_get(adapter->owner)) { -+ put_device(&adapter->dev); -+ adapter = NULL; -+ } -+ -+ return adapter; -+} -+EXPORT_SYMBOL(i2c_get_adapter_by_fwnode); -+ - static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p, - u32 def_val, bool use_def) - { -diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c -index 3ed74aa4b44bb..bce6b796e04c2 100644 ---- a/drivers/i2c/i2c-core-of.c -+++ b/drivers/i2c/i2c-core-of.c -@@ -113,72 +113,6 @@ void of_i2c_register_devices(struct i2c_adapter *adap) - of_node_put(bus); - } - --static int of_dev_or_parent_node_match(struct device *dev, const void *data) --{ -- if (dev->of_node == data) -- return 1; -- -- if (dev->parent) -- return dev->parent->of_node == data; -- -- return 0; --} -- --/* must call put_device() when done with returned i2c_client device */ --struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) --{ -- struct device *dev; -- struct i2c_client *client; -- -- dev = bus_find_device_by_of_node(&i2c_bus_type, node); -- if (!dev) -- return NULL; -- -- client = i2c_verify_client(dev); -- if (!client) -- put_device(dev); -- -- return client; --} --EXPORT_SYMBOL(of_find_i2c_device_by_node); -- --/* must call put_device() when done with returned i2c_adapter device */ --struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) --{ -- struct device *dev; -- struct i2c_adapter *adapter; -- -- dev = bus_find_device(&i2c_bus_type, NULL, node, -- of_dev_or_parent_node_match); -- if (!dev) -- return NULL; -- -- adapter = i2c_verify_adapter(dev); -- if (!adapter) -- put_device(dev); -- -- return adapter; --} --EXPORT_SYMBOL(of_find_i2c_adapter_by_node); -- --/* must call i2c_put_adapter() when done with returned i2c_adapter device */ --struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) --{ -- struct i2c_adapter *adapter; -- -- adapter = of_find_i2c_adapter_by_node(node); -- if (!adapter) -- return NULL; -- -- if (!try_module_get(adapter->owner)) { -- put_device(&adapter->dev); -- adapter = NULL; -- } -- -- return adapter; --} --EXPORT_SYMBOL(of_get_i2c_adapter_by_node); -- - static const struct of_device_id* - i2c_of_match_device_sysfs(const struct of_device_id *matches, - struct i2c_client *client) -diff --git a/include/linux/i2c.h b/include/linux/i2c.h -index 82c9b643876c9..da35562faaf33 100644 ---- a/include/linux/i2c.h -+++ b/include/linux/i2c.h -@@ -939,15 +939,33 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr); - - #endif /* I2C */ - -+/* must call put_device() when done with returned i2c_client device */ -+struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode); -+ -+/* must call put_device() when done with returned i2c_adapter device */ -+struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode); -+ -+/* must call i2c_put_adapter() when done with returned i2c_adapter device */ -+struct i2c_adapter *i2c_get_adapter_by_fwnode(struct fwnode_handle *fwnode); -+ - #if IS_ENABLED(CONFIG_OF) - /* must call put_device() when done with returned i2c_client device */ --struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); -+static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) -+{ -+ return i2c_find_device_by_fwnode(of_fwnode_handle(node)); -+} - - /* must call put_device() when done with returned i2c_adapter device */ --struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node); -+static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) -+{ -+ return i2c_find_adapter_by_fwnode(of_fwnode_handle(node)); -+} - - /* must call i2c_put_adapter() when done with returned i2c_adapter device */ --struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); -+static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node) -+{ -+ return i2c_get_adapter_by_fwnode(of_fwnode_handle(node)); -+} - - const struct of_device_id - *i2c_of_match_device(const struct of_device_id *matches, --- -2.43.0 - diff --git a/queue-5.10/i2c-core-add-managed-function-for-adding-i2c-adapter.patch b/queue-5.10/i2c-core-add-managed-function-for-adding-i2c-adapter.patch deleted file mode 100644 index 72cd0566206..00000000000 --- a/queue-5.10/i2c-core-add-managed-function-for-adding-i2c-adapter.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 667f87ed0c24ad7688e80c2cc772e3bdcfc94864 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 8 Apr 2021 19:17:17 +0800 -Subject: i2c: core: add managed function for adding i2c adapters - -From: Yicong Yang - -[ Upstream commit 07740c92ae57ca21204f1e0c6f59272cdf3190cc ] - -Some I2C controller drivers will only unregister the I2C -adapter in their .remove() callback, which can be done -by simply using a managed variant to add the I2C adapter. - -So add the managed functions for adding the I2C adapter. - -Reviewed-by: Andy Shevchenko -Reviewed-by: Dmitry Osipenko -Signed-off-by: Yicong Yang -Signed-off-by: Wolfram Sang -Stable-dep-of: 3f858bbf04db ("i2c: acpi: Unbind mux adapters before delete") -Signed-off-by: Sasha Levin ---- - drivers/i2c/i2c-core-base.c | 26 ++++++++++++++++++++++++++ - include/linux/i2c.h | 1 + - 2 files changed, 27 insertions(+) - -diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c -index e8a89e18c640e..8d4fa896d7909 100644 ---- a/drivers/i2c/i2c-core-base.c -+++ b/drivers/i2c/i2c-core-base.c -@@ -1705,6 +1705,32 @@ void i2c_del_adapter(struct i2c_adapter *adap) - } - EXPORT_SYMBOL(i2c_del_adapter); - -+static void devm_i2c_del_adapter(void *adapter) -+{ -+ i2c_del_adapter(adapter); -+} -+ -+/** -+ * devm_i2c_add_adapter - device-managed variant of i2c_add_adapter() -+ * @dev: managing device for adding this I2C adapter -+ * @adapter: the adapter to add -+ * Context: can sleep -+ * -+ * Add adapter with dynamic bus number, same with i2c_add_adapter() -+ * but the adapter will be auto deleted on driver detach. -+ */ -+int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter) -+{ -+ int ret; -+ -+ ret = i2c_add_adapter(adapter); -+ if (ret) -+ return ret; -+ -+ return devm_add_action_or_reset(dev, devm_i2c_del_adapter, adapter); -+} -+EXPORT_SYMBOL_GPL(devm_i2c_add_adapter); -+ - static void i2c_parse_timing(struct device *dev, char *prop_name, u32 *cur_val_p, - u32 def_val, bool use_def) - { -diff --git a/include/linux/i2c.h b/include/linux/i2c.h -index a670ae129f4b9..82c9b643876c9 100644 ---- a/include/linux/i2c.h -+++ b/include/linux/i2c.h -@@ -846,6 +846,7 @@ static inline void i2c_mark_adapter_resumed(struct i2c_adapter *adap) - */ - #if IS_ENABLED(CONFIG_I2C) - int i2c_add_adapter(struct i2c_adapter *adap); -+int devm_i2c_add_adapter(struct device *dev, struct i2c_adapter *adapter); - void i2c_del_adapter(struct i2c_adapter *adap); - int i2c_add_numbered_adapter(struct i2c_adapter *adap); - --- -2.43.0 - diff --git a/queue-5.10/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch b/queue-5.10/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch deleted file mode 100644 index 1cb4ce5eeaf..00000000000 --- a/queue-5.10/iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ee3a4a7c1313cc834bae493f306d009d604a52c9 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 4 Oct 2023 18:39:28 +0200 -Subject: iio: accel: mxc4005: allow module autoloading via OF compatible - -From: Luca Ceresoli - -[ Upstream commit 4d7c16d08d248952c116f2eb9b7b5abc43a19688 ] - -Add OF device table with compatible strings to allow automatic module -loading. - -Signed-off-by: Luca Ceresoli -Reviewed-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20231004-mxc4005-device-tree-support-v1-2-e7c0faea72e4@bootlin.com -Signed-off-by: Jonathan Cameron -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - drivers/iio/accel/mxc4005.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c -index e0d1491d52b01..558c0e67e10e1 100644 ---- a/drivers/iio/accel/mxc4005.c -+++ b/drivers/iio/accel/mxc4005.c -@@ -492,6 +492,13 @@ static const struct acpi_device_id mxc4005_acpi_match[] = { - }; - MODULE_DEVICE_TABLE(acpi, mxc4005_acpi_match); - -+static const struct of_device_id mxc4005_of_match[] = { -+ { .compatible = "memsic,mxc4005", }, -+ { .compatible = "memsic,mxc6655", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, mxc4005_of_match); -+ - static const struct i2c_device_id mxc4005_id[] = { - {"mxc4005", 0}, - {"mxc6655", 0}, -@@ -503,6 +510,7 @@ static struct i2c_driver mxc4005_driver = { - .driver = { - .name = MXC4005_DRV_NAME, - .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), -+ .of_match_table = mxc4005_of_match, - }, - .probe = mxc4005_probe, - .id_table = mxc4005_id, --- -2.43.0 - diff --git a/queue-5.10/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch b/queue-5.10/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch deleted file mode 100644 index e22571dcce3..00000000000 --- a/queue-5.10/iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 729a03d2d1d16422d82d0bb489b37f376a34a187 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 26 Mar 2024 12:37:00 +0100 -Subject: iio: accel: mxc4005: Reset chip on probe() and resume() - -From: Hans de Goede - -[ Upstream commit 6b8cffdc4a31e4a72f75ecd1bc13fbf0dafee390 ] - -On some designs the chip is not properly reset when powered up at boot or -after a suspend/resume cycle. - -Use the sw-reset feature to ensure that the chip is in a clean state -after probe() / resume() and in the case of resume() restore the settings -(scale, trigger-enabled). - -Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218578 -Signed-off-by: Hans de Goede -Link: https://lore.kernel.org/r/20240326113700.56725-3-hdegoede@redhat.com -Cc: -Signed-off-by: Jonathan Cameron -Signed-off-by: Sasha Levin ---- - drivers/iio/accel/mxc4005.c | 68 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 68 insertions(+) - -diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c -index 558c0e67e10e1..b6ed24042386d 100644 ---- a/drivers/iio/accel/mxc4005.c -+++ b/drivers/iio/accel/mxc4005.c -@@ -5,6 +5,7 @@ - * Copyright (c) 2014, Intel Corporation. - */ - -+#include - #include - #include - #include -@@ -36,6 +37,7 @@ - - #define MXC4005_REG_INT_CLR1 0x01 - #define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01 -+#define MXC4005_REG_INT_CLR1_SW_RST 0x10 - - #define MXC4005_REG_CONTROL 0x0D - #define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5) -@@ -43,6 +45,9 @@ - - #define MXC4005_REG_DEVICE_ID 0x0E - -+/* Datasheet does not specify a reset time, this is a conservative guess */ -+#define MXC4005_RESET_TIME_US 2000 -+ - enum mxc4005_axis { - AXIS_X, - AXIS_Y, -@@ -66,6 +71,8 @@ struct mxc4005_data { - s64 timestamp __aligned(8); - } scan; - bool trigger_enabled; -+ unsigned int control; -+ unsigned int int_mask1; - }; - - /* -@@ -353,6 +360,7 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig, - return ret; - } - -+ data->int_mask1 = val; - data->trigger_enabled = state; - mutex_unlock(&data->mutex); - -@@ -388,6 +396,13 @@ static int mxc4005_chip_init(struct mxc4005_data *data) - - dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg); - -+ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, -+ MXC4005_REG_INT_CLR1_SW_RST); -+ if (ret < 0) -+ return dev_err_probe(data->dev, ret, "resetting chip\n"); -+ -+ fsleep(MXC4005_RESET_TIME_US); -+ - ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); - if (ret < 0) - return dev_err_probe(data->dev, ret, "writing INT_MASK0\n"); -@@ -485,6 +500,58 @@ static int mxc4005_probe(struct i2c_client *client, - return devm_iio_device_register(&client->dev, indio_dev); - } - -+static int mxc4005_suspend(struct device *dev) -+{ -+ struct iio_dev *indio_dev = dev_get_drvdata(dev); -+ struct mxc4005_data *data = iio_priv(indio_dev); -+ int ret; -+ -+ /* Save control to restore it on resume */ -+ ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control); -+ if (ret < 0) -+ dev_err(data->dev, "failed to read reg_control\n"); -+ -+ return ret; -+} -+ -+static int mxc4005_resume(struct device *dev) -+{ -+ struct iio_dev *indio_dev = dev_get_drvdata(dev); -+ struct mxc4005_data *data = iio_priv(indio_dev); -+ int ret; -+ -+ ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1, -+ MXC4005_REG_INT_CLR1_SW_RST); -+ if (ret) { -+ dev_err(data->dev, "failed to reset chip: %d\n", ret); -+ return ret; -+ } -+ -+ fsleep(MXC4005_RESET_TIME_US); -+ -+ ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control); -+ if (ret) { -+ dev_err(data->dev, "failed to restore control register\n"); -+ return ret; -+ } -+ -+ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0); -+ if (ret) { -+ dev_err(data->dev, "failed to restore interrupt 0 mask\n"); -+ return ret; -+ } -+ -+ ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1); -+ if (ret) { -+ dev_err(data->dev, "failed to restore interrupt 1 mask\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume); -+ - static const struct acpi_device_id mxc4005_acpi_match[] = { - {"MXC4005", 0}, - {"MXC6655", 0}, -@@ -511,6 +578,7 @@ static struct i2c_driver mxc4005_driver = { - .name = MXC4005_DRV_NAME, - .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), - .of_match_table = mxc4005_of_match, -+ .pm = pm_sleep_ptr(&mxc4005_pm_ops), - }, - .probe = mxc4005_probe, - .id_table = mxc4005_id, --- -2.43.0 - diff --git a/queue-5.10/mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch b/queue-5.10/mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch deleted file mode 100644 index 234b4f16686..00000000000 --- a/queue-5.10/mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch +++ /dev/null @@ -1,192 +0,0 @@ -From a25514ea7731b0f9a21c67b2a8de9787b31dcd83 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 14 Dec 2020 19:10:20 -0800 -Subject: mm: introduce debug_pagealloc_{map,unmap}_pages() helpers - -From: Mike Rapoport - -[ Upstream commit 77bc7fd607dee2ffb28daff6d0dd8ae42af61ea8 ] - -Patch series "arch, mm: improve robustness of direct map manipulation", v7. - -During recent discussion about KVM protected memory, David raised a -concern about usage of __kernel_map_pages() outside of DEBUG_PAGEALLOC -scope [1]. - -Indeed, for architectures that define CONFIG_ARCH_HAS_SET_DIRECT_MAP it is -possible that __kernel_map_pages() would fail, but since this function is -void, the failure will go unnoticed. - -Moreover, there's lack of consistency of __kernel_map_pages() semantics -across architectures as some guard this function with #ifdef -DEBUG_PAGEALLOC, some refuse to update the direct map if page allocation -debugging is disabled at run time and some allow modifying the direct map -regardless of DEBUG_PAGEALLOC settings. - -This set straightens this out by restoring dependency of -__kernel_map_pages() on DEBUG_PAGEALLOC and updating the call sites -accordingly. - -Since currently the only user of __kernel_map_pages() outside -DEBUG_PAGEALLOC is hibernation, it is updated to make direct map accesses -there more explicit. - -[1] https://lore.kernel.org/lkml/2759b4bf-e1e3-d006-7d86-78a40348269d@redhat.com - -This patch (of 4): - -When CONFIG_DEBUG_PAGEALLOC is enabled, it unmaps pages from the kernel -direct mapping after free_pages(). The pages than need to be mapped back -before they could be used. Theese mapping operations use -__kernel_map_pages() guarded with with debug_pagealloc_enabled(). - -The only place that calls __kernel_map_pages() without checking whether -DEBUG_PAGEALLOC is enabled is the hibernation code that presumes -availability of this function when ARCH_HAS_SET_DIRECT_MAP is set. Still, -on arm64, __kernel_map_pages() will bail out when DEBUG_PAGEALLOC is not -enabled but set_direct_map_invalid_noflush() may render some pages not -present in the direct map and hibernation code won't be able to save such -pages. - -To make page allocation debugging and hibernation interaction more robust, -the dependency on DEBUG_PAGEALLOC or ARCH_HAS_SET_DIRECT_MAP has to be -made more explicit. - -Start with combining the guard condition and the call to -__kernel_map_pages() into debug_pagealloc_map_pages() and -debug_pagealloc_unmap_pages() functions to emphasize that -__kernel_map_pages() should not be called without DEBUG_PAGEALLOC and use -these new functions to map/unmap pages when page allocation debugging is -enabled. - -Link: https://lkml.kernel.org/r/20201109192128.960-1-rppt@kernel.org -Link: https://lkml.kernel.org/r/20201109192128.960-2-rppt@kernel.org -Signed-off-by: Mike Rapoport -Reviewed-by: David Hildenbrand -Acked-by: Kirill A. Shutemov -Acked-by: Vlastimil Babka -Cc: Albert Ou -Cc: Andy Lutomirski -Cc: Benjamin Herrenschmidt -Cc: Borislav Petkov -Cc: Catalin Marinas -Cc: Christian Borntraeger -Cc: Christoph Lameter -Cc: "David S. Miller" -Cc: Dave Hansen -Cc: David Rientjes -Cc: "Edgecombe, Rick P" -Cc: "H. Peter Anvin" -Cc: Heiko Carstens -Cc: Ingo Molnar -Cc: Joonsoo Kim -Cc: Len Brown -Cc: Michael Ellerman -Cc: Palmer Dabbelt -Cc: Paul Mackerras -Cc: Paul Walmsley -Cc: Pavel Machek -Cc: Pekka Enberg -Cc: Peter Zijlstra -Cc: "Rafael J. Wysocki" -Cc: Thomas Gleixner -Cc: Vasily Gorbik -Cc: Will Deacon -Cc: Rafael J. Wysocki -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context") -Signed-off-by: Sasha Levin ---- - include/linux/mm.h | 15 +++++++++++++++ - mm/memory_hotplug.c | 3 +-- - mm/page_alloc.c | 6 ++---- - mm/slab.c | 2 +- - 4 files changed, 19 insertions(+), 7 deletions(-) - -diff --git a/include/linux/mm.h b/include/linux/mm.h -index b8b677f47a8da..4b9c1b3656a49 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -2967,12 +2967,27 @@ kernel_map_pages(struct page *page, int numpages, int enable) - { - __kernel_map_pages(page, numpages, enable); - } -+ -+static inline void debug_pagealloc_map_pages(struct page *page, int numpages) -+{ -+ if (debug_pagealloc_enabled_static()) -+ __kernel_map_pages(page, numpages, 1); -+} -+ -+static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) -+{ -+ if (debug_pagealloc_enabled_static()) -+ __kernel_map_pages(page, numpages, 0); -+} -+ - #ifdef CONFIG_HIBERNATION - extern bool kernel_page_present(struct page *page); - #endif /* CONFIG_HIBERNATION */ - #else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ - static inline void - kernel_map_pages(struct page *page, int numpages, int enable) {} -+static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {} -+static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {} - #ifdef CONFIG_HIBERNATION - static inline bool kernel_page_present(struct page *page) { return true; } - #endif /* CONFIG_HIBERNATION */ -diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c -index 553b0705dce8e..a29b134790596 100644 ---- a/mm/memory_hotplug.c -+++ b/mm/memory_hotplug.c -@@ -596,8 +596,7 @@ void generic_online_page(struct page *page, unsigned int order) - * so we should map it first. This is better than introducing a special - * case in page freeing fast path. - */ -- if (debug_pagealloc_enabled_static()) -- kernel_map_pages(page, 1 << order, 1); -+ debug_pagealloc_map_pages(page, 1 << order); - __free_pages_core(page, order); - totalram_pages_add(1UL << order); - #ifdef CONFIG_HIGHMEM -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index ed66601044be5..5e02b4bc94a08 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -1274,8 +1274,7 @@ static __always_inline bool free_pages_prepare(struct page *page, - */ - arch_free_page(page, order); - -- if (debug_pagealloc_enabled_static()) -- kernel_map_pages(page, 1 << order, 0); -+ debug_pagealloc_unmap_pages(page, 1 << order); - - kasan_free_nondeferred_pages(page, order); - -@@ -2272,8 +2271,7 @@ inline void post_alloc_hook(struct page *page, unsigned int order, - set_page_refcounted(page); - - arch_alloc_page(page, order); -- if (debug_pagealloc_enabled_static()) -- kernel_map_pages(page, 1 << order, 1); -+ debug_pagealloc_map_pages(page, 1 << order); - kasan_alloc_pages(page, order); - kernel_poison_pages(page, 1 << order, 1); - set_page_owner(page, order, gfp_flags); -diff --git a/mm/slab.c b/mm/slab.c -index b2cc2cf7d8a33..067ffc2939904 100644 ---- a/mm/slab.c -+++ b/mm/slab.c -@@ -1434,7 +1434,7 @@ static void slab_kernel_map(struct kmem_cache *cachep, void *objp, int map) - if (!is_debug_pagealloc_cache(cachep)) - return; - -- kernel_map_pages(virt_to_page(objp), cachep->size / PAGE_SIZE, map); -+ __kernel_map_pages(virt_to_page(objp), cachep->size / PAGE_SIZE, map); - } - - #else --- -2.43.0 - diff --git a/queue-5.10/mmc-jz4740-use-the-new-pm-macros.patch b/queue-5.10/mmc-jz4740-use-the-new-pm-macros.patch deleted file mode 100644 index 313e5843408..00000000000 --- a/queue-5.10/mmc-jz4740-use-the-new-pm-macros.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 374615891aef31c57d972154f7c623573251ab37 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 7 Dec 2021 00:21:01 +0000 -Subject: mmc: jz4740: Use the new PM macros - -From: Paul Cercueil - -[ Upstream commit e0d64ecc621715e9c7807e952b68475c62bbf630 ] - - - Use DEFINE_SIMPLE_DEV_PM_OPS() instead of the SIMPLE_DEV_PM_OPS() - macro. This makes it possible to remove the __maybe_unused flags - on the callback functions. - - - Since we only have callbacks for suspend/resume, we can conditionally - compile the dev_pm_ops structure for when CONFIG_PM_SLEEP is enabled; - so use the pm_sleep_ptr() macro instead of pm_ptr(). - -Signed-off-by: Paul Cercueil -Acked-by: Ulf Hansson -Signed-off-by: Rafael J. Wysocki -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - drivers/mmc/host/jz4740_mmc.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c -index 62d00232f85ea..95ef64a103127 100644 ---- a/drivers/mmc/host/jz4740_mmc.c -+++ b/drivers/mmc/host/jz4740_mmc.c -@@ -1136,17 +1136,17 @@ static int jz4740_mmc_remove(struct platform_device *pdev) - return 0; - } - --static int __maybe_unused jz4740_mmc_suspend(struct device *dev) -+static int jz4740_mmc_suspend(struct device *dev) - { - return pinctrl_pm_select_sleep_state(dev); - } - --static int __maybe_unused jz4740_mmc_resume(struct device *dev) -+static int jz4740_mmc_resume(struct device *dev) - { - return pinctrl_select_default_state(dev); - } - --static SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, -+DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, - jz4740_mmc_resume); - - static struct platform_driver jz4740_mmc_driver = { -@@ -1156,7 +1156,7 @@ static struct platform_driver jz4740_mmc_driver = { - .name = "jz4740-mmc", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(jz4740_mmc_of_match), -- .pm = pm_ptr(&jz4740_mmc_pm_ops), -+ .pm = pm_sleep_ptr(&jz4740_mmc_pm_ops), - }, - }; - --- -2.43.0 - diff --git a/queue-5.10/mmc-mxc-use-the-new-pm-macros.patch b/queue-5.10/mmc-mxc-use-the-new-pm-macros.patch deleted file mode 100644 index d83e751a965..00000000000 --- a/queue-5.10/mmc-mxc-use-the-new-pm-macros.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 01e68c65285851b087e171ee5fdc183704e28c8c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 7 Dec 2021 00:21:02 +0000 -Subject: mmc: mxc: Use the new PM macros - -From: Paul Cercueil - -[ Upstream commit 2cdbd92c2d1dff07ad56c39f5857ee644bbd2c8a ] - -Use DEFINE_SIMPLE_DEV_PM_OPS() instead of the SIMPLE_DEV_PM_OPS() -macro, along with using pm_sleep_ptr() as this driver doesn't handle -runtime PM. - -This makes it possible to remove the #ifdef CONFIG_PM guard around -the suspend/resume functions. - -Signed-off-by: Paul Cercueil -Acked-by: Ulf Hansson -Signed-off-by: Rafael J. Wysocki -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - drivers/mmc/host/mxcmmc.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c -index 93a105b075645..a68c21506967f 100644 ---- a/drivers/mmc/host/mxcmmc.c -+++ b/drivers/mmc/host/mxcmmc.c -@@ -1209,7 +1209,6 @@ static int mxcmci_remove(struct platform_device *pdev) - return 0; - } - --#ifdef CONFIG_PM_SLEEP - static int mxcmci_suspend(struct device *dev) - { - struct mmc_host *mmc = dev_get_drvdata(dev); -@@ -1236,9 +1235,8 @@ static int mxcmci_resume(struct device *dev) - - return ret; - } --#endif - --static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); -+DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); - - static struct platform_driver mxcmci_driver = { - .probe = mxcmci_probe, -@@ -1247,7 +1245,7 @@ static struct platform_driver mxcmci_driver = { - .driver = { - .name = DRIVER_NAME, - .probe_type = PROBE_PREFER_ASYNCHRONOUS, -- .pm = &mxcmci_pm_ops, -+ .pm = pm_sleep_ptr(&mxcmci_pm_ops), - .of_match_table = mxcmci_of_match, - } - }; --- -2.43.0 - diff --git a/queue-5.10/perf-x86-avoid-tif_ia32-when-checking-64bit-mode.patch b/queue-5.10/perf-x86-avoid-tif_ia32-when-checking-64bit-mode.patch deleted file mode 100644 index 1d54ab5418b..00000000000 --- a/queue-5.10/perf-x86-avoid-tif_ia32-when-checking-64bit-mode.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 1757c2e8b089fd9dccf96b0e0cdf34c8600d7da6 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 3 Oct 2020 23:25:27 -0400 -Subject: perf/x86: Avoid TIF_IA32 when checking 64bit mode - -From: Gabriel Krisman Bertazi - -[ Upstream commit 375d4bfda57392f0865dae051e1c4bd2700e8d71 ] - -In preparation to remove TIF_IA32, stop using it in perf events code. - -Tested by running perf on 32-bit, 64-bit and x32 applications. - -Suggested-by: Andy Lutomirski -Signed-off-by: Gabriel Krisman Bertazi -Signed-off-by: Thomas Gleixner -Acked-by: Peter Zijlstra (Intel) -Link: https://lore.kernel.org/r/20201004032536.1229030-2-krisman@collabora.com -Stable-dep-of: 7fea700e04bd ("zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING") -Signed-off-by: Sasha Levin ---- - arch/x86/events/core.c | 2 +- - arch/x86/events/intel/ds.c | 2 +- - arch/x86/events/intel/lbr.c | 2 +- - arch/x86/kernel/perf_regs.c | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c -index b79b9f21cbb3b..1cef0ceb6acb3 100644 ---- a/arch/x86/events/core.c -+++ b/arch/x86/events/core.c -@@ -2615,7 +2615,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent - struct stack_frame_ia32 frame; - const struct stack_frame_ia32 __user *fp; - -- if (!test_thread_flag(TIF_IA32)) -+ if (user_64bit_mode(regs)) - return 0; - - cs_base = get_segment_base(regs->cs); -diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c -index 48f30ffef1f4b..64a847eead484 100644 ---- a/arch/x86/events/intel/ds.c -+++ b/arch/x86/events/intel/ds.c -@@ -1266,7 +1266,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) - old_to = to; - - #ifdef CONFIG_X86_64 -- is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32); -+ is_64bit = kernel_ip(to) || any_64bit_mode(regs); - #endif - insn_init(&insn, kaddr, size, is_64bit); - insn_get_length(&insn); -diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c -index 4b6c39c5facba..d93076c18c6ca 100644 ---- a/arch/x86/events/intel/lbr.c -+++ b/arch/x86/events/intel/lbr.c -@@ -1245,7 +1245,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort) - * on 64-bit systems running 32-bit apps - */ - #ifdef CONFIG_X86_64 -- is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32); -+ is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs()); - #endif - insn_init(&insn, addr, bytes_read, is64); - insn_get_opcode(&insn); -diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c -index f9e5352b3bef9..624703af80a19 100644 ---- a/arch/x86/kernel/perf_regs.c -+++ b/arch/x86/kernel/perf_regs.c -@@ -122,7 +122,7 @@ int perf_reg_validate(u64 mask) - - u64 perf_reg_abi(struct task_struct *task) - { -- if (test_tsk_thread_flag(task, TIF_IA32)) -+ if (!user_64bit_mode(task_pt_regs(task))) - return PERF_SAMPLE_REGS_ABI_32; - else - return PERF_SAMPLE_REGS_ABI_64; --- -2.43.0 - diff --git a/queue-5.10/pm-core-add-new-_pm_ops-macros-deprecate-old-ones.patch b/queue-5.10/pm-core-add-new-_pm_ops-macros-deprecate-old-ones.patch deleted file mode 100644 index 1b770ec99c2..00000000000 --- a/queue-5.10/pm-core-add-new-_pm_ops-macros-deprecate-old-ones.patch +++ /dev/null @@ -1,197 +0,0 @@ -From b934447a0fcbcd8bbd51c4dc6cbcc92c803bae21 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 7 Dec 2021 00:21:00 +0000 -Subject: PM: core: Add new *_PM_OPS macros, deprecate old ones - -From: Paul Cercueil - -[ Upstream commit 1a3c7bb088266fa2db017be299f91f1c1894c857 ] - -This commit introduces the following macros: - -SYSTEM_SLEEP_PM_OPS() -LATE_SYSTEM_SLEEP_PM_OPS() -NOIRQ_SYSTEM_SLEEP_PM_OPS() -RUNTIME_PM_OPS() - -These new macros are very similar to their SET_*_PM_OPS() equivalent. -They however differ in the fact that the callbacks they set will always -be seen as referenced by the compiler. This means that the callback -functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or -tagged with __maybe_unused, to prevent the compiler from complaining -about unused static symbols. The compiler will then simply evaluate at -compile time whether or not these symbols are dead code. - -The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are -now also wrapped with a new pm_sleep_ptr() macro, which is inspired from -pm_ptr(). This is needed for drivers that use different callbacks for -sleep and runtime PM, to handle the case where CONFIG_PM is set and -CONFIG_PM_SLEEP is not. - -This commit also deprecates the following macros: - -SIMPLE_DEV_PM_OPS() -UNIVERSAL_DEV_PM_OPS() - -And introduces the following macros: - -DEFINE_SIMPLE_DEV_PM_OPS() -DEFINE_UNIVERSAL_DEV_PM_OPS() - -These macros are similar to the functions they were created to replace, -with the following differences: - - - They use the new macros introduced above, and as such always - reference the provided callback functions. - - - They are not tagged with __maybe_unused. They are meant to be used - with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS() - and DEFINE_SIMPLE_DEV_PM_OPS() respectively. - - - They declare the symbol static, since every driver seems to do that - anyway; and if a non-static use-case is needed an indirection pointer - could be used. - -The point of this change, is to progressively switch from a code model -where PM callbacks are all protected behind CONFIG_PM guards, to a code -model where the PM callbacks are always seen by the compiler, but -discarded if not used. - -Signed-off-by: Paul Cercueil -Reviewed-by: Jonathan Cameron -Signed-off-by: Rafael J. Wysocki -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - include/linux/pm.h | 74 +++++++++++++++++++++++++++++++--------------- - 1 file changed, 50 insertions(+), 24 deletions(-) - -diff --git a/include/linux/pm.h b/include/linux/pm.h -index 5ac2c9ba5baf7..b4974dc837032 100644 ---- a/include/linux/pm.h -+++ b/include/linux/pm.h -@@ -301,47 +301,59 @@ struct dev_pm_ops { - int (*runtime_idle)(struct device *dev); - }; - -+#define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+ .suspend = pm_sleep_ptr(suspend_fn), \ -+ .resume = pm_sleep_ptr(resume_fn), \ -+ .freeze = pm_sleep_ptr(suspend_fn), \ -+ .thaw = pm_sleep_ptr(resume_fn), \ -+ .poweroff = pm_sleep_ptr(suspend_fn), \ -+ .restore = pm_sleep_ptr(resume_fn), -+ -+#define LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+ .suspend_late = pm_sleep_ptr(suspend_fn), \ -+ .resume_early = pm_sleep_ptr(resume_fn), \ -+ .freeze_late = pm_sleep_ptr(suspend_fn), \ -+ .thaw_early = pm_sleep_ptr(resume_fn), \ -+ .poweroff_late = pm_sleep_ptr(suspend_fn), \ -+ .restore_early = pm_sleep_ptr(resume_fn), -+ -+#define NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+ .suspend_noirq = pm_sleep_ptr(suspend_fn), \ -+ .resume_noirq = pm_sleep_ptr(resume_fn), \ -+ .freeze_noirq = pm_sleep_ptr(suspend_fn), \ -+ .thaw_noirq = pm_sleep_ptr(resume_fn), \ -+ .poweroff_noirq = pm_sleep_ptr(suspend_fn), \ -+ .restore_noirq = pm_sleep_ptr(resume_fn), -+ -+#define RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ -+ .runtime_suspend = suspend_fn, \ -+ .runtime_resume = resume_fn, \ -+ .runtime_idle = idle_fn, -+ - #ifdef CONFIG_PM_SLEEP - #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -- .suspend = suspend_fn, \ -- .resume = resume_fn, \ -- .freeze = suspend_fn, \ -- .thaw = resume_fn, \ -- .poweroff = suspend_fn, \ -- .restore = resume_fn, -+ SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #else - #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #endif - - #ifdef CONFIG_PM_SLEEP - #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -- .suspend_late = suspend_fn, \ -- .resume_early = resume_fn, \ -- .freeze_late = suspend_fn, \ -- .thaw_early = resume_fn, \ -- .poweroff_late = suspend_fn, \ -- .restore_early = resume_fn, -+ LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #else - #define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #endif - - #ifdef CONFIG_PM_SLEEP - #define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -- .suspend_noirq = suspend_fn, \ -- .resume_noirq = resume_fn, \ -- .freeze_noirq = suspend_fn, \ -- .thaw_noirq = resume_fn, \ -- .poweroff_noirq = suspend_fn, \ -- .restore_noirq = resume_fn, -+ NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #else - #define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) - #endif - - #ifdef CONFIG_PM - #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ -- .runtime_suspend = suspend_fn, \ -- .runtime_resume = resume_fn, \ -- .runtime_idle = idle_fn, -+ RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) - #else - #define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) - #endif -@@ -350,9 +362,9 @@ struct dev_pm_ops { - * Use this if you want to use the same suspend and resume callbacks for suspend - * to RAM and hibernation. - */ --#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ --const struct dev_pm_ops __maybe_unused name = { \ -- SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+#define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ -+static const struct dev_pm_ops name = { \ -+ SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ - } - - /* -@@ -368,6 +380,19 @@ const struct dev_pm_ops __maybe_unused name = { \ - * .resume_early(), to the same routines as .runtime_suspend() and - * .runtime_resume(), respectively (and analogously for hibernation). - */ -+#define DEFINE_UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ -+static const struct dev_pm_ops name = { \ -+ SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+ RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ -+} -+ -+/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */ -+#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ -+const struct dev_pm_ops __maybe_unused name = { \ -+ SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -+} -+ -+/* Deprecated. Use DEFINE_UNIVERSAL_DEV_PM_OPS() instead. */ - #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ - const struct dev_pm_ops __maybe_unused name = { \ - SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ -@@ -375,6 +400,7 @@ const struct dev_pm_ops __maybe_unused name = { \ - } - - #define pm_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM), (_ptr)) -+#define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr)) - - /* - * PM_EVENT_ messages --- -2.43.0 - diff --git a/queue-5.10/pm-core-redefine-pm_ptr-macro.patch b/queue-5.10/pm-core-redefine-pm_ptr-macro.patch deleted file mode 100644 index e89c68bb26b..00000000000 --- a/queue-5.10/pm-core-redefine-pm_ptr-macro.patch +++ /dev/null @@ -1,61 +0,0 @@ -From e00842f7c10a45fd93086c7b3f32e5d7786cc590 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 7 Dec 2021 00:20:59 +0000 -Subject: PM: core: Redefine pm_ptr() macro - -From: Paul Cercueil - -[ Upstream commit c06ef740d401d0f4ab188882bf6f8d9cf0f75eaf ] - -The pm_ptr() macro was previously conditionally defined, according to -the value of the CONFIG_PM option. This meant that the pointed structure -was either referenced (if CONFIG_PM was set), or never referenced (if -CONFIG_PM was not set), causing it to be detected as unused by the -compiler. - -This worked fine, but required the __maybe_unused compiler attribute to -be used to every symbol pointed to by a pointer wrapped with pm_ptr(). - -We can do better. With this change, the pm_ptr() is now defined the -same, independently of the value of CONFIG_PM. It now uses the (?:) -ternary operator to conditionally resolve to its argument. Since the -condition is known at compile time, the compiler will then choose to -discard the unused symbols, which won't need to be tagged with -__maybe_unused anymore. - -This pm_ptr() macro is usually used with pointers to dev_pm_ops -structures created with SIMPLE_DEV_PM_OPS() or similar macros. These do -use a __maybe_unused flag, which is now useless with this change, so it -later can be removed. However in the meantime it causes no harm, and all -the drivers still compile fine with the new pm_ptr() macro. - -Signed-off-by: Paul Cercueil -Reviewed-by: Jonathan Cameron -Reviewed-by: Arnd Bergmann -Signed-off-by: Rafael J. Wysocki -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - include/linux/pm.h | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/include/linux/pm.h b/include/linux/pm.h -index 52d9724db9dc6..5ac2c9ba5baf7 100644 ---- a/include/linux/pm.h -+++ b/include/linux/pm.h -@@ -374,11 +374,7 @@ const struct dev_pm_ops __maybe_unused name = { \ - SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ - } - --#ifdef CONFIG_PM --#define pm_ptr(_ptr) (_ptr) --#else --#define pm_ptr(_ptr) NULL --#endif -+#define pm_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM), (_ptr)) - - /* - * PM_EVENT_ messages --- -2.43.0 - diff --git a/queue-5.10/pm-core-remove-static-qualifier-in-define_simple_dev.patch b/queue-5.10/pm-core-remove-static-qualifier-in-define_simple_dev.patch deleted file mode 100644 index 218742ba62d..00000000000 --- a/queue-5.10/pm-core-remove-static-qualifier-in-define_simple_dev.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 9ffb7506c82e744fb98f5c77572aac496f2fc122 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 7 Jan 2022 18:17:19 +0000 -Subject: PM: core: Remove static qualifier in DEFINE_SIMPLE_DEV_PM_OPS macro - -From: Paul Cercueil - -[ Upstream commit 52cc1d7f9786d2be44a3ab9b5b48416a7618e713 ] - -Keep this macro in line with the other ones. This makes it possible to -use them in the cases where the underlying dev_pm_ops structure is -exported. - -Restore the "static" qualifier in the two drivers where the -DEFINE_SIMPLE_DEV_PM_OPS macro was used. - -Signed-off-by: Paul Cercueil -Acked-by: Jonathan Cameron -Reviewed-by: Ulf Hansson -Signed-off-by: Rafael J. Wysocki -Stable-dep-of: 6b8cffdc4a31 ("iio: accel: mxc4005: Reset chip on probe() and resume()") -Signed-off-by: Sasha Levin ---- - drivers/mmc/host/jz4740_mmc.c | 4 ++-- - drivers/mmc/host/mxcmmc.c | 2 +- - include/linux/pm.h | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c -index 95ef64a103127..da060e78e7ba9 100644 ---- a/drivers/mmc/host/jz4740_mmc.c -+++ b/drivers/mmc/host/jz4740_mmc.c -@@ -1146,8 +1146,8 @@ static int jz4740_mmc_resume(struct device *dev) - return pinctrl_select_default_state(dev); - } - --DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, -- jz4740_mmc_resume); -+static DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, -+ jz4740_mmc_resume); - - static struct platform_driver jz4740_mmc_driver = { - .probe = jz4740_mmc_probe, -diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c -index a68c21506967f..7b5d89f646de4 100644 ---- a/drivers/mmc/host/mxcmmc.c -+++ b/drivers/mmc/host/mxcmmc.c -@@ -1236,7 +1236,7 @@ static int mxcmci_resume(struct device *dev) - return ret; - } - --DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); -+static DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); - - static struct platform_driver mxcmci_driver = { - .probe = mxcmci_probe, -diff --git a/include/linux/pm.h b/include/linux/pm.h -index b4974dc837032..00e71f0b4c179 100644 ---- a/include/linux/pm.h -+++ b/include/linux/pm.h -@@ -363,7 +363,7 @@ struct dev_pm_ops { - * to RAM and hibernation. - */ - #define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ --static const struct dev_pm_ops name = { \ -+const struct dev_pm_ops name = { \ - SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ - } - --- -2.43.0 - diff --git a/queue-5.10/pm-hibernate-make-direct-map-manipulations-more-expl.patch b/queue-5.10/pm-hibernate-make-direct-map-manipulations-more-expl.patch deleted file mode 100644 index eada3779b2d..00000000000 --- a/queue-5.10/pm-hibernate-make-direct-map-manipulations-more-expl.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 2b3ed759e93fb5bc86744856a0cbe80f1b980e49 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 14 Dec 2020 19:10:25 -0800 -Subject: PM: hibernate: make direct map manipulations more explicit - -From: Mike Rapoport - -[ Upstream commit 2abf962a8d42b32f5ffeb827826290b799c85f86 ] - -When DEBUG_PAGEALLOC or ARCH_HAS_SET_DIRECT_MAP is enabled a page may be -not present in the direct map and has to be explicitly mapped before it -could be copied. - -Introduce hibernate_map_page() and hibernation_unmap_page() that will -explicitly use set_direct_map_{default,invalid}_noflush() for -ARCH_HAS_SET_DIRECT_MAP case and debug_pagealloc_{map,unmap}_pages() for -DEBUG_PAGEALLOC case. - -The remapping of the pages in safe_copy_page() presumes that it only -changes protection bits in an existing PTE and so it is safe to ignore -return value of set_direct_map_{default,invalid}_noflush(). - -Still, add a pr_warn() so that future changes in set_memory APIs will not -silently break hibernation. - -Link: https://lkml.kernel.org/r/20201109192128.960-3-rppt@kernel.org -Signed-off-by: Mike Rapoport -Acked-by: Rafael J. Wysocki -Reviewed-by: David Hildenbrand -Acked-by: Kirill A. Shutemov -Acked-by: Vlastimil Babka -Cc: Albert Ou -Cc: Andy Lutomirski -Cc: Benjamin Herrenschmidt -Cc: Borislav Petkov -Cc: Catalin Marinas -Cc: Christian Borntraeger -Cc: Christoph Lameter -Cc: Dave Hansen -Cc: David Rientjes -Cc: "David S. Miller" -Cc: "Edgecombe, Rick P" -Cc: Heiko Carstens -Cc: "H. Peter Anvin" -Cc: Ingo Molnar -Cc: Joonsoo Kim -Cc: Len Brown -Cc: Michael Ellerman -Cc: Palmer Dabbelt -Cc: Paul Mackerras -Cc: Paul Walmsley -Cc: Pavel Machek -Cc: Pekka Enberg -Cc: Peter Zijlstra -Cc: "Rafael J. Wysocki" -Cc: Thomas Gleixner -Cc: Vasily Gorbik -Cc: Will Deacon -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Stable-dep-of: fb1cf0878328 ("riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context") -Signed-off-by: Sasha Levin ---- - include/linux/mm.h | 12 ------------ - kernel/power/snapshot.c | 38 ++++++++++++++++++++++++++++++++++++-- - 2 files changed, 36 insertions(+), 14 deletions(-) - -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 4b9c1b3656a49..61ed8b20ea704 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -2958,16 +2958,6 @@ static inline bool debug_pagealloc_enabled_static(void) - #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP) - extern void __kernel_map_pages(struct page *page, int numpages, int enable); - --/* -- * When called in DEBUG_PAGEALLOC context, the call should most likely be -- * guarded by debug_pagealloc_enabled() or debug_pagealloc_enabled_static() -- */ --static inline void --kernel_map_pages(struct page *page, int numpages, int enable) --{ -- __kernel_map_pages(page, numpages, enable); --} -- - static inline void debug_pagealloc_map_pages(struct page *page, int numpages) - { - if (debug_pagealloc_enabled_static()) -@@ -2984,8 +2974,6 @@ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) - extern bool kernel_page_present(struct page *page); - #endif /* CONFIG_HIBERNATION */ - #else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ --static inline void --kernel_map_pages(struct page *page, int numpages, int enable) {} - static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {} - static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {} - #ifdef CONFIG_HIBERNATION -diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c -index c1bdaae07f4c7..e84fb16f30b9d 100644 ---- a/kernel/power/snapshot.c -+++ b/kernel/power/snapshot.c -@@ -76,6 +76,40 @@ static inline void hibernate_restore_protect_page(void *page_address) {} - static inline void hibernate_restore_unprotect_page(void *page_address) {} - #endif /* CONFIG_STRICT_KERNEL_RWX && CONFIG_ARCH_HAS_SET_MEMORY */ - -+ -+/* -+ * The calls to set_direct_map_*() should not fail because remapping a page -+ * here means that we only update protection bits in an existing PTE. -+ * It is still worth to have a warning here if something changes and this -+ * will no longer be the case. -+ */ -+static inline void hibernate_map_page(struct page *page) -+{ -+ if (IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) { -+ int ret = set_direct_map_default_noflush(page); -+ -+ if (ret) -+ pr_warn_once("Failed to remap page\n"); -+ } else { -+ debug_pagealloc_map_pages(page, 1); -+ } -+} -+ -+static inline void hibernate_unmap_page(struct page *page) -+{ -+ if (IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) { -+ unsigned long addr = (unsigned long)page_address(page); -+ int ret = set_direct_map_invalid_noflush(page); -+ -+ if (ret) -+ pr_warn_once("Failed to remap page\n"); -+ -+ flush_tlb_kernel_range(addr, addr + PAGE_SIZE); -+ } else { -+ debug_pagealloc_unmap_pages(page, 1); -+ } -+} -+ - static int swsusp_page_is_free(struct page *); - static void swsusp_set_page_forbidden(struct page *); - static void swsusp_unset_page_forbidden(struct page *); -@@ -1348,9 +1382,9 @@ static void safe_copy_page(void *dst, struct page *s_page) - if (kernel_page_present(s_page)) { - do_copy_page(dst, page_address(s_page)); - } else { -- kernel_map_pages(s_page, 1, 1); -+ hibernate_map_page(s_page); - do_copy_page(dst, page_address(s_page)); -- kernel_map_pages(s_page, 1, 0); -+ hibernate_unmap_page(s_page); - } - } - --- -2.43.0 - diff --git a/queue-5.10/riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch b/queue-5.10/riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch deleted file mode 100644 index 20a6df5bd57..00000000000 --- a/queue-5.10/riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch +++ /dev/null @@ -1,104 +0,0 @@ -From f4a9ab6c094bec464d2264ab51a88ce2fe172dd7 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 15 May 2024 07:50:40 +0200 -Subject: riscv: rewrite __kernel_map_pages() to fix sleeping in invalid - context - -From: Nam Cao - -[ Upstream commit fb1cf0878328fe75d47f0aed0a65b30126fcefc4 ] - -__kernel_map_pages() is a debug function which clears the valid bit in page -table entry for deallocated pages to detect illegal memory accesses to -freed pages. - -This function set/clear the valid bit using __set_memory(). __set_memory() -acquires init_mm's semaphore, and this operation may sleep. This is -problematic, because __kernel_map_pages() can be called in atomic context, -and thus is illegal to sleep. An example warning that this causes: - -BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1578 -in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2, name: kthreadd -preempt_count: 2, expected: 0 -CPU: 0 PID: 2 Comm: kthreadd Not tainted 6.9.0-g1d4c6d784ef6 #37 -Hardware name: riscv-virtio,qemu (DT) -Call Trace: -[] dump_backtrace+0x1c/0x24 -[] show_stack+0x2c/0x38 -[] dump_stack_lvl+0x5a/0x72 -[] dump_stack+0x14/0x1c -[] __might_resched+0x104/0x10e -[] __might_sleep+0x3e/0x62 -[] down_write+0x20/0x72 -[] __set_memory+0x82/0x2fa -[] __kernel_map_pages+0x5a/0xd4 -[] __alloc_pages_bulk+0x3b2/0x43a -[] __vmalloc_node_range+0x196/0x6ba -[] copy_process+0x72c/0x17ec -[] kernel_clone+0x60/0x2fe -[] kernel_thread+0x82/0xa0 -[] kthreadd+0x14a/0x1be -[] ret_from_fork+0xe/0x1c - -Rewrite this function with apply_to_existing_page_range(). It is fine to -not have any locking, because __kernel_map_pages() works with pages being -allocated/deallocated and those pages are not changed by anyone else in the -meantime. - -Fixes: 5fde3db5eb02 ("riscv: add ARCH_SUPPORTS_DEBUG_PAGEALLOC support") -Signed-off-by: Nam Cao -Cc: stable@vger.kernel.org -Reviewed-by: Alexandre Ghiti -Link: https://lore.kernel.org/r/1289ecba9606a19917bc12b6c27da8aa23e1e5ae.1715750938.git.namcao@linutronix.de -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/mm/pageattr.c | 28 ++++++++++++++++++++++------ - 1 file changed, 22 insertions(+), 6 deletions(-) - -diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c -index ae63a0227e2fb..ce4b73b4d0e42 100644 ---- a/arch/riscv/mm/pageattr.c -+++ b/arch/riscv/mm/pageattr.c -@@ -185,16 +185,32 @@ int set_direct_map_default_noflush(struct page *page) - } - - #ifdef CONFIG_DEBUG_PAGEALLOC -+static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data) -+{ -+ int enable = *(int *)data; -+ -+ unsigned long val = pte_val(ptep_get(pte)); -+ -+ if (enable) -+ val |= _PAGE_PRESENT; -+ else -+ val &= ~_PAGE_PRESENT; -+ -+ set_pte(pte, __pte(val)); -+ -+ return 0; -+} -+ - void __kernel_map_pages(struct page *page, int numpages, int enable) - { - if (!debug_pagealloc_enabled()) - return; - -- if (enable) -- __set_memory((unsigned long)page_address(page), numpages, -- __pgprot(_PAGE_PRESENT), __pgprot(0)); -- else -- __set_memory((unsigned long)page_address(page), numpages, -- __pgprot(0), __pgprot(_PAGE_PRESENT)); -+ unsigned long start = (unsigned long)page_address(page); -+ unsigned long size = PAGE_SIZE * numpages; -+ -+ apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable); -+ -+ flush_tlb_kernel_range(start, start + size); - } - #endif --- -2.43.0 - diff --git a/queue-5.10/series b/queue-5.10/series index ee7946e8413..7981c819e38 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -27,20 +27,10 @@ af_unix-use-skb_queue_len_lockless-in-sk_diag_show_r.patch af_unix-annotate-data-race-of-sk-sk_shutdown-in-sk_d.patch ipv6-fix-possible-race-in-__fib6_drop_pcpu_from.patch usb-gadget-f_fs-fix-race-between-aio_cancel-and-aio-.patch -pm-core-redefine-pm_ptr-macro.patch -pm-core-add-new-_pm_ops-macros-deprecate-old-ones.patch -mmc-jz4740-use-the-new-pm-macros.patch -mmc-mxc-use-the-new-pm-macros.patch -pm-core-remove-static-qualifier-in-define_simple_dev.patch -iio-accel-mxc4005-allow-module-autoloading-via-of-co.patch -iio-accel-mxc4005-reset-chip-on-probe-and-resume.patch drm-amd-display-handle-y-carry-over-in-vcp-x.y-calcu.patch serial-sc16is7xx-replace-hardcoded-divisor-value-wit.patch serial-sc16is7xx-fix-bug-in-sc16is7xx_set_baud-when-.patch mmc-davinci-don-t-strip-remove-function-when-driver-.patch -i2c-core-add-managed-function-for-adding-i2c-adapter.patch -i2c-add-fwnode-apis.patch -i2c-acpi-unbind-mux-adapters-before-delete.patch selftests-mm-compaction_test-fix-incorrect-write-of-.patch selftests-mm-conform-test-to-tap-format-output.patch selftests-mm-log-a-consistent-test-name-for-check_co.patch @@ -60,8 +50,6 @@ xhci-apply-broken-streams-quirk-to-etron-ej188-xhci-host.patch scsi-mpt3sas-avoid-test-set_bit-operating-in-non-allocated-memory.patch powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch input-try-trimming-too-long-modalias-strings.patch -clk-sifive-extract-prci-core-to-common-base.patch -clk-sifive-do-not-register-clkdevs-for-prci-clocks.patch sunrpc-return-proper-error-from-gss_wrap_req_priv.patch gpio-tqmx86-fix-typo-in-kconfig-label.patch hid-core-remove-unnecessary-warn_on-in-implement.patch @@ -113,10 +101,6 @@ greybus-fix-use-after-free-bug-in-gb_interface_release-due-to-race-condition.pat usb-storage-alauda-check-whether-the-media-is-initia.patch i2c-at91-fix-the-functionality-flags-of-the-slave-on.patch i2c-designware-fix-the-functionality-flags-of-the-sl.patch -perf-x86-avoid-tif_ia32-when-checking-64bit-mode.patch -x86-compat-simplify-compat-syscall-userspace-allocat.patch -x86-elf-use-e_machine-to-select-start_thread-for-x32.patch -x86-mm-convert-mmu-context-ia32_compat-into-a-proper.patch zap_pid_ns_processes-clear-tif_notify_signal-along-w.patch padata-disable-bh-when-taking-works-lock-on-mt-path.patch rcutorture-fix-rcu_torture_one_read-pipe_count-overf.patch @@ -207,10 +191,6 @@ drm-amdgpu-drop-config_drm_amd_dc_dcn3_01-from-atomf.patch drm-amdgpu-fix-vram-type-and-bandwidth-error-for-ddr.patch drm-amdgpu-update-atomfirmware-for-dcn3.1-phy-tuning.patch drm-amdgpu-atomfirmware-add-intergrated-info-v2.3-ta.patch -mm-introduce-debug_pagealloc_-map-unmap-_pages-helpe.patch -pm-hibernate-make-direct-map-manipulations-more-expl.patch -arch-mm-restore-dependency-of-__kernel_map_pages-on-.patch -riscv-rewrite-__kernel_map_pages-to-fix-sleeping-in-.patch r8169-remove-unneeded-memory-barrier-in-rtl_tx.patch r8169-improve-rtl_tx.patch r8169-improve-rtl8169_start_xmit.patch diff --git a/queue-5.10/x86-compat-simplify-compat-syscall-userspace-allocat.patch b/queue-5.10/x86-compat-simplify-compat-syscall-userspace-allocat.patch deleted file mode 100644 index b42d2aa28df..00000000000 --- a/queue-5.10/x86-compat-simplify-compat-syscall-userspace-allocat.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 48a9fc8b13722c354335c399cd8de298acb5b0df Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 3 Oct 2020 23:25:28 -0400 -Subject: x86/compat: Simplify compat syscall userspace allocation - -From: Gabriel Krisman Bertazi - -[ Upstream commit 214f0e804358cdd13b5cbe4445189f23e30618b4 ] - -When allocating user memory space for a compat system call, don't consider -whether the originating code is IA32 or X32, just allocate from a safe -region for both, beyond the redzone. This should be safe for IA32, and has -the benefit of avoiding TIF_IA32, which is about to be removed. - -Suggested-by: Andy Lutomirski -Signed-off-by: Gabriel Krisman Bertazi -Signed-off-by: Thomas Gleixner -Link: https://lore.kernel.org/r/20201004032536.1229030-3-krisman@collabora.com -Stable-dep-of: 7fea700e04bd ("zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING") -Signed-off-by: Sasha Levin ---- - arch/x86/include/asm/compat.h | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h -index 46a067bd7e0ba..8f7af1f890406 100644 ---- a/arch/x86/include/asm/compat.h -+++ b/arch/x86/include/asm/compat.h -@@ -175,14 +175,13 @@ typedef struct user_regs_struct compat_elf_gregset_t; - - static inline void __user *arch_compat_alloc_user_space(long len) - { -- compat_uptr_t sp; -- -- if (test_thread_flag(TIF_IA32)) { -- sp = task_pt_regs(current)->sp; -- } else { -- /* -128 for the x32 ABI redzone */ -- sp = task_pt_regs(current)->sp - 128; -- } -+ compat_uptr_t sp = task_pt_regs(current)->sp; -+ -+ /* -+ * -128 for the x32 ABI redzone. For IA32, it is not strictly -+ * necessary, but not harmful. -+ */ -+ sp -= 128; - - return (void __user *)round_down(sp - len, 16); - } --- -2.43.0 - diff --git a/queue-5.10/x86-elf-use-e_machine-to-select-start_thread-for-x32.patch b/queue-5.10/x86-elf-use-e_machine-to-select-start_thread-for-x32.patch deleted file mode 100644 index e7ac44e7860..00000000000 --- a/queue-5.10/x86-elf-use-e_machine-to-select-start_thread-for-x32.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b3fe0ecd86fb80ade5819a9271716fe1e04e9b1c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 3 Oct 2020 23:25:32 -0400 -Subject: x86/elf: Use e_machine to select start_thread for x32 - -From: Gabriel Krisman Bertazi - -[ Upstream commit 2424b14605c71a7187c14edd525044eb36bdea47 ] - -Since TIF_X32 is going away, avoid using it to find the ELF type in -compat_start_thread. - -According to SysV AMD64 ABI Draft, an AMD64 ELF object using ILP32 must -have ELFCLASS32 with (E_MACHINE == EM_X86_64), so use that ELF field to -differentiate a x32 object from a IA32 object when executing start_thread() -in compat mode. - -Signed-off-by: Gabriel Krisman Bertazi -Signed-off-by: Thomas Gleixner -Reviewed-by: Andy Lutomirski -Link: https://lore.kernel.org/r/20201004032536.1229030-7-krisman@collabora.com -Stable-dep-of: 7fea700e04bd ("zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING") -Signed-off-by: Sasha Levin ---- - arch/x86/include/asm/elf.h | 5 +++-- - arch/x86/kernel/process_64.c | 5 ++--- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h -index b9a5d488f1a5e..b7e3fa0dcd970 100644 ---- a/arch/x86/include/asm/elf.h -+++ b/arch/x86/include/asm/elf.h -@@ -186,8 +186,9 @@ static inline void elf_common_init(struct thread_struct *t, - #define COMPAT_ELF_PLAT_INIT(regs, load_addr) \ - elf_common_init(¤t->thread, regs, __USER_DS) - --void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp); --#define compat_start_thread compat_start_thread -+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32); -+#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp) \ -+ compat_start_thread(regs, new_ip, new_sp, ex->e_machine == EM_X86_64) - - void set_personality_ia32(bool); - #define COMPAT_SET_PERSONALITY(ex) \ -diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c -index 1d8bc4736fb79..997d6556f4be8 100644 ---- a/arch/x86/kernel/process_64.c -+++ b/arch/x86/kernel/process_64.c -@@ -511,11 +511,10 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) - EXPORT_SYMBOL_GPL(start_thread); - - #ifdef CONFIG_COMPAT --void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp) -+void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32) - { - start_thread_common(regs, new_ip, new_sp, -- test_thread_flag(TIF_X32) -- ? __USER_CS : __USER32_CS, -+ x32 ? __USER_CS : __USER32_CS, - __USER_DS, __USER_DS); - } - #endif --- -2.43.0 - diff --git a/queue-5.10/x86-mm-convert-mmu-context-ia32_compat-into-a-proper.patch b/queue-5.10/x86-mm-convert-mmu-context-ia32_compat-into-a-proper.patch deleted file mode 100644 index 646d0ffa24f..00000000000 --- a/queue-5.10/x86-mm-convert-mmu-context-ia32_compat-into-a-proper.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 1e6677766e249d2c21c8a5afde8e7dbb7da4cf70 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 3 Oct 2020 23:25:35 -0400 -Subject: x86/mm: Convert mmu context ia32_compat into a proper flags field - -From: Gabriel Krisman Bertazi - -[ Upstream commit ff170cd0595398a7b66cb40f249eb2f10c29b66d ] - -The ia32_compat attribute is a weird thing. It mirrors TIF_IA32 and -TIF_X32 and is used only in two very unrelated places: (1) to decide if -the vsyscall page is accessible (2) for uprobes to find whether the -patched instruction is 32 or 64 bit. - -In preparation to remove the TIF flags, a new mechanism is required for -ia32_compat, but given its odd semantics, adding a real flags field which -configures these specific behaviours is the best option. - -So, set_personality_x64() can ask for the vsyscall page, which is not -available in x32/ia32 and set_personality_ia32() can configure the uprobe -code as needed. - -uprobe cannot rely on other methods like user_64bit_mode() to decide how -to patch, so it needs some specific flag like this. - -Signed-off-by: Gabriel Krisman Bertazi -Signed-off-by: Thomas Gleixner -Acked-by: Andy Lutomirski -Link: https://lore.kernel.org/r/20201004032536.1229030-10-krisman@collabora.com -Stable-dep-of: 7fea700e04bd ("zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING") -Signed-off-by: Sasha Levin ---- - arch/x86/entry/vsyscall/vsyscall_64.c | 2 +- - arch/x86/include/asm/mmu.h | 9 +++++++-- - arch/x86/include/asm/mmu_context.h | 2 +- - arch/x86/kernel/process_64.c | 17 +++++++++++------ - 4 files changed, 20 insertions(+), 10 deletions(-) - -diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c -index f0b817eb6e8ba..c5d074f5627a4 100644 ---- a/arch/x86/entry/vsyscall/vsyscall_64.c -+++ b/arch/x86/entry/vsyscall/vsyscall_64.c -@@ -292,7 +292,7 @@ static struct vm_area_struct gate_vma __ro_after_init = { - struct vm_area_struct *get_gate_vma(struct mm_struct *mm) - { - #ifdef CONFIG_COMPAT -- if (!mm || mm->context.ia32_compat) -+ if (!mm || !(mm->context.flags & MM_CONTEXT_HAS_VSYSCALL)) - return NULL; - #endif - if (vsyscall_mode == NONE) -diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h -index 9257667d13c5e..5d7494631ea95 100644 ---- a/arch/x86/include/asm/mmu.h -+++ b/arch/x86/include/asm/mmu.h -@@ -6,6 +6,12 @@ - #include - #include - #include -+#include -+ -+/* Uprobes on this MM assume 32-bit code */ -+#define MM_CONTEXT_UPROBE_IA32 BIT(0) -+/* vsyscall page is accessible on this MM */ -+#define MM_CONTEXT_HAS_VSYSCALL BIT(1) - - /* - * x86 has arch-specific MMU state beyond what lives in mm_struct. -@@ -33,8 +39,7 @@ typedef struct { - #endif - - #ifdef CONFIG_X86_64 -- /* True if mm supports a task running in 32 bit compatibility mode. */ -- unsigned short ia32_compat; -+ unsigned short flags; - #endif - - struct mutex lock; -diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h -index d98016b837559..054a791573231 100644 ---- a/arch/x86/include/asm/mmu_context.h -+++ b/arch/x86/include/asm/mmu_context.h -@@ -177,7 +177,7 @@ static inline void arch_exit_mmap(struct mm_struct *mm) - static inline bool is_64bit_mm(struct mm_struct *mm) - { - return !IS_ENABLED(CONFIG_IA32_EMULATION) || -- !(mm->context.ia32_compat == TIF_IA32); -+ !(mm->context.flags & MM_CONTEXT_UPROBE_IA32); - } - #else - static inline bool is_64bit_mm(struct mm_struct *mm) -diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c -index 997d6556f4be8..8546dfd8683fc 100644 ---- a/arch/x86/kernel/process_64.c -+++ b/arch/x86/kernel/process_64.c -@@ -644,10 +644,8 @@ void set_personality_64bit(void) - /* Pretend that this comes from a 64bit execve */ - task_pt_regs(current)->orig_ax = __NR_execve; - current_thread_info()->status &= ~TS_COMPAT; -- -- /* Ensure the corresponding mm is not marked. */ - if (current->mm) -- current->mm->context.ia32_compat = 0; -+ current->mm->context.flags = MM_CONTEXT_HAS_VSYSCALL; - - /* TBD: overwrites user setup. Should have two bits. - But 64bit processes have always behaved this way, -@@ -662,7 +660,8 @@ static void __set_personality_x32(void) - clear_thread_flag(TIF_IA32); - set_thread_flag(TIF_X32); - if (current->mm) -- current->mm->context.ia32_compat = TIF_X32; -+ current->mm->context.flags = 0; -+ - current->personality &= ~READ_IMPLIES_EXEC; - /* - * in_32bit_syscall() uses the presence of the x32 syscall bit -@@ -682,8 +681,14 @@ static void __set_personality_ia32(void) - #ifdef CONFIG_IA32_EMULATION - set_thread_flag(TIF_IA32); - clear_thread_flag(TIF_X32); -- if (current->mm) -- current->mm->context.ia32_compat = TIF_IA32; -+ if (current->mm) { -+ /* -+ * uprobes applied to this MM need to know this and -+ * cannot use user_64bit_mode() at that time. -+ */ -+ current->mm->context.flags = MM_CONTEXT_UPROBE_IA32; -+ } -+ - current->personality |= force_personality32; - /* Prepare the first "return" to user space */ - task_pt_regs(current)->orig_ax = __NR_ia32_execve; --- -2.43.0 - -- 2.47.3