diff options
Diffstat (limited to 'include')
584 files changed, 23237 insertions, 6254 deletions
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a6affc0550b0..c941d99162c0 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -289,6 +289,8 @@ struct acpi_dep_data { acpi_handle supplier; acpi_handle consumer; bool honor_dep; + bool met; + bool free_when_met; }; /* Performance Management */ diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index e6098a08c914..9ffdc0425bc2 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -761,6 +761,7 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_event_status *event_status)) ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)) +ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_hw_disable_all_gpes(void)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void)) diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index e5dfb6f4de52..451f6276da49 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -307,7 +307,8 @@ enum acpi_preferred_pm_profiles { PM_SOHO_SERVER = 5, PM_APPLIANCE_PC = 6, PM_PERFORMANCE_SERVER = 7, - PM_TABLET = 8 + PM_TABLET = 8, + NR_PM_PROFILES = 9 }; /* Values for sleep_status and sleep_control registers (V5+ FADT) */ diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index f51c46f4e3e4..000764ab3985 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h @@ -86,7 +86,7 @@ struct acpi_table_slic { struct acpi_table_slit { struct acpi_table_header header; /* Common ACPI table header */ u64 locality_count; - u8 entry[1]; /* Real size = localities^2 */ + u8 entry[]; /* Real size = localities^2 */ }; /******************************************************************************* diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index e271d6708c87..22142c71d35a 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -130,7 +130,4 @@ ATOMIC_OP(xor, ^) #define arch_atomic_read(v) READ_ONCE((v)->counter) #define arch_atomic_set(v, i) WRITE_ONCE(((v)->counter), (i)) -#define arch_atomic_xchg(ptr, v) (arch_xchg(&(ptr)->counter, (u32)(v))) -#define arch_atomic_cmpxchg(v, old, new) (arch_cmpxchg(&((v)->counter), (u32)(old), (u32)(new))) - #endif /* __ASM_GENERIC_ATOMIC_H */ diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h index 71ab4ba9c25d..e076e079f6b2 100644 --- a/include/asm-generic/bitops/atomic.h +++ b/include/asm-generic/bitops/atomic.h @@ -15,21 +15,21 @@ static __always_inline void arch_set_bit(unsigned int nr, volatile unsigned long *p) { p += BIT_WORD(nr); - arch_atomic_long_or(BIT_MASK(nr), (atomic_long_t *)p); + raw_atomic_long_or(BIT_MASK(nr), (atomic_long_t *)p); } static __always_inline void arch_clear_bit(unsigned int nr, volatile unsigned long *p) { p += BIT_WORD(nr); - arch_atomic_long_andnot(BIT_MASK(nr), (atomic_long_t *)p); + raw_atomic_long_andnot(BIT_MASK(nr), (atomic_long_t *)p); } static __always_inline void arch_change_bit(unsigned int nr, volatile unsigned long *p) { p += BIT_WORD(nr); - arch_atomic_long_xor(BIT_MASK(nr), (atomic_long_t *)p); + raw_atomic_long_xor(BIT_MASK(nr), (atomic_long_t *)p); } static __always_inline int @@ -39,7 +39,7 @@ arch_test_and_set_bit(unsigned int nr, volatile unsigned long *p) unsigned long mask = BIT_MASK(nr); p += BIT_WORD(nr); - old = arch_atomic_long_fetch_or(mask, (atomic_long_t *)p); + old = raw_atomic_long_fetch_or(mask, (atomic_long_t *)p); return !!(old & mask); } @@ -50,7 +50,7 @@ arch_test_and_clear_bit(unsigned int nr, volatile unsigned long *p) unsigned long mask = BIT_MASK(nr); p += BIT_WORD(nr); - old = arch_atomic_long_fetch_andnot(mask, (atomic_long_t *)p); + old = raw_atomic_long_fetch_andnot(mask, (atomic_long_t *)p); return !!(old & mask); } @@ -61,7 +61,7 @@ arch_test_and_change_bit(unsigned int nr, volatile unsigned long *p) unsigned long mask = BIT_MASK(nr); p += BIT_WORD(nr); - old = arch_atomic_long_fetch_xor(mask, (atomic_long_t *)p); + old = raw_atomic_long_fetch_xor(mask, (atomic_long_t *)p); return !!(old & mask); } diff --git a/include/asm-generic/bitops/lock.h b/include/asm-generic/bitops/lock.h index 630f2f6b9595..40913516e654 100644 --- a/include/asm-generic/bitops/lock.h +++ b/include/asm-generic/bitops/lock.h @@ -25,7 +25,7 @@ arch_test_and_set_bit_lock(unsigned int nr, volatile unsigned long *p) if (READ_ONCE(*p) & mask) return 1; - old = arch_atomic_long_fetch_or_acquire(mask, (atomic_long_t *)p); + old = raw_atomic_long_fetch_or_acquire(mask, (atomic_long_t *)p); return !!(old & mask); } @@ -41,7 +41,7 @@ static __always_inline void arch_clear_bit_unlock(unsigned int nr, volatile unsigned long *p) { p += BIT_WORD(nr); - arch_atomic_long_fetch_andnot_release(BIT_MASK(nr), (atomic_long_t *)p); + raw_atomic_long_fetch_andnot_release(BIT_MASK(nr), (atomic_long_t *)p); } /** @@ -63,7 +63,7 @@ arch___clear_bit_unlock(unsigned int nr, volatile unsigned long *p) p += BIT_WORD(nr); old = READ_ONCE(*p); old &= ~BIT_MASK(nr); - arch_atomic_long_set_release((atomic_long_t *)p, old); + raw_atomic_long_set_release((atomic_long_t *)p, old); } /** @@ -83,7 +83,7 @@ static inline bool arch_clear_bit_unlock_is_negative_byte(unsigned int nr, unsigned long mask = BIT_MASK(nr); p += BIT_WORD(nr); - old = arch_atomic_long_fetch_andnot_release(mask, (atomic_long_t *)p); + old = raw_atomic_long_fetch_andnot_release(mask, (atomic_long_t *)p); return !!(old & BIT(7)); } #define arch_clear_bit_unlock_is_negative_byte arch_clear_bit_unlock_is_negative_byte diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 4050b191e1a9..6e794420bd39 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -87,10 +87,12 @@ struct bug_entry { * * Use the versions with printk format strings to provide better diagnostics. */ -#ifndef __WARN_FLAGS extern __printf(4, 5) void warn_slowpath_fmt(const char *file, const int line, unsigned taint, const char *fmt, ...); +extern __printf(1, 2) void __warn_printk(const char *fmt, ...); + +#ifndef __WARN_FLAGS #define __WARN() __WARN_printf(TAINT_WARN, NULL) #define __WARN_printf(taint, arg...) do { \ instrumentation_begin(); \ @@ -98,7 +100,6 @@ void warn_slowpath_fmt(const char *file, const int line, unsigned taint, instrumentation_end(); \ } while (0) #else -extern __printf(1, 2) void __warn_printk(const char *fmt, ...); #define __WARN() __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN)) #define __WARN_printf(taint, arg...) do { \ instrumentation_begin(); \ diff --git a/include/asm-generic/bugs.h b/include/asm-generic/bugs.h deleted file mode 100644 index 69021830f078..000000000000 --- a/include/asm-generic/bugs.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __ASM_GENERIC_BUGS_H -#define __ASM_GENERIC_BUGS_H -/* - * This file is included by 'init/main.c' to check for - * architecture-dependent bugs. - */ - -static inline void check_bugs(void) { } - -#endif /* __ASM_GENERIC_BUGS_H */ diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h index 5e4b1f2369d2..570cd4da7210 100644 --- a/include/asm-generic/export.h +++ b/include/asm-generic/export.h @@ -3,86 +3,9 @@ #define __ASM_GENERIC_EXPORT_H /* - * This comment block is used by fixdep. Please do not remove. - * - * When CONFIG_MODVERSIONS is changed from n to y, all source files having - * EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a - * side effect of the *.o build rule. + * <asm/export.h> and <asm-generic/export.h> are deprecated. + * Please include <linux/export.h> directly. */ - -#ifndef KSYM_FUNC -#define KSYM_FUNC(x) x -#endif -#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define KSYM_ALIGN 4 -#elif defined(CONFIG_64BIT) -#define KSYM_ALIGN 8 -#else -#define KSYM_ALIGN 4 -#endif - -.macro __put, val, name -#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS - .long \val - ., \name - ., 0 -#elif defined(CONFIG_64BIT) - .quad \val, \name, 0 -#else - .long \val, \name, 0 -#endif -.endm - -/* - * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) - * section flag requires it. Use '%progbits' instead of '@progbits' since the - * former apparently works on all arches according to the binutils source. - */ - -.macro ___EXPORT_SYMBOL name,val,sec -#if defined(CONFIG_MODULES) && !defined(__DISABLE_EXPORTS) - .section ___ksymtab\sec+\name,"a" - .balign KSYM_ALIGN -__ksymtab_\name: - __put \val, __kstrtab_\name - .previous - .section __ksymtab_strings,"aMS",%progbits,1 -__kstrtab_\name: - .asciz "\name" - .previous -#endif -.endm - -#if defined(CONFIG_TRIM_UNUSED_KSYMS) - -#include <linux/kconfig.h> -#include <generated/autoksyms.h> - -.macro __ksym_marker sym - .section ".discard.ksym","a" -__ksym_marker_\sym: - .previous -.endm - -#define __EXPORT_SYMBOL(sym, val, sec) \ - __ksym_marker sym; \ - __cond_export_sym(sym, val, sec, __is_defined(__KSYM_##sym)) -#define __cond_export_sym(sym, val, sec, conf) \ - ___cond_export_sym(sym, val, sec, conf) -#define ___cond_export_sym(sym, val, sec, enabled) \ - __cond_export_sym_##enabled(sym, val, sec) -#define __cond_export_sym_1(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec -#define __cond_export_sym_0(sym, val, sec) /* nothing */ - -#else -#define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec -#endif - -#define EXPORT_SYMBOL(name) \ - __EXPORT_SYMBOL(name, KSYM_FUNC(name),) -#define EXPORT_SYMBOL_GPL(name) \ - __EXPORT_SYMBOL(name, KSYM_FUNC(name), _gpl) -#define EXPORT_DATA_SYMBOL(name) \ - __EXPORT_SYMBOL(name, name,) -#define EXPORT_DATA_SYMBOL_GPL(name) \ - __EXPORT_SYMBOL(name, name,_gpl) +#include <linux/export.h> #endif diff --git a/include/asm-generic/fb.h b/include/asm-generic/fb.h index f9f18101ed36..bb7ee9c70e60 100644 --- a/include/asm-generic/fb.h +++ b/include/asm-generic/fb.h @@ -1,13 +1,135 @@ /* SPDX-License-Identifier: GPL-2.0 */ + #ifndef __ASM_GENERIC_FB_H_ #define __ASM_GENERIC_FB_H_ -#include <linux/fb.h> -#define fb_pgprotect(...) do {} while (0) +/* + * Only include this header file from your architecture's <asm/fb.h>. + */ + +#include <linux/io.h> +#include <linux/mm_types.h> +#include <linux/pgtable.h> + +struct fb_info; +struct file; + +#ifndef fb_pgprotect +#define fb_pgprotect fb_pgprotect +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +} +#endif +#ifndef fb_is_primary_device +#define fb_is_primary_device fb_is_primary_device static inline int fb_is_primary_device(struct fb_info *info) { return 0; } +#endif + +/* + * I/O helpers for the framebuffer. Prefer these functions over their + * regular counterparts. The regular I/O functions provide in-order + * access and swap bytes to/from little-endian ordering. Neither is + * required for framebuffers. Instead, the helpers read and write + * raw framebuffer data. Independent operations can be reordered for + * improved performance. + */ + +#ifndef fb_readb +static inline u8 fb_readb(const volatile void __iomem *addr) +{ + return __raw_readb(addr); +} +#define fb_readb fb_readb +#endif + +#ifndef fb_readw +static inline u16 fb_readw(const volatile void __iomem *addr) +{ + return __raw_readw(addr); +} +#define fb_readw fb_readw +#endif + +#ifndef fb_readl +static inline u32 fb_readl(const volatile void __iomem *addr) +{ + return __raw_readl(addr); +} +#define fb_readl fb_readl +#endif + +#ifndef fb_readq +#if defined(__raw_readq) +static inline u64 fb_readq(const volatile void __iomem *addr) +{ + return __raw_readq(addr); +} +#define fb_readq fb_readq +#endif +#endif + +#ifndef fb_writeb +static inline void fb_writeb(u8 b, volatile void __iomem *addr) +{ + __raw_writeb(b, addr); +} +#define fb_writeb fb_writeb +#endif + +#ifndef fb_writew +static inline void fb_writew(u16 b, volatile void __iomem *addr) +{ + __raw_writew(b, addr); +} +#define fb_writew fb_writew +#endif + +#ifndef fb_writel +static inline void fb_writel(u32 b, volatile void __iomem *addr) +{ + __raw_writel(b, addr); +} +#define fb_writel fb_writel +#endif + +#ifndef fb_writeq +#if defined(__raw_writeq) +static inline void fb_writeq(u64 b, volatile void __iomem *addr) +{ + __raw_writeq(b, addr); +} +#define fb_writeq fb_writeq +#endif +#endif + +#ifndef fb_memcpy_fromio +static inline void fb_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n) +{ + memcpy_fromio(to, from, n); +} +#define fb_memcpy_fromio fb_memcpy_fromio +#endif + +#ifndef fb_memcpy_toio +static inline void fb_memcpy_toio(volatile void __iomem *to, const void *from, size_t n) +{ + memcpy_toio(to, from, n); +} +#define fb_memcpy_toio fb_memcpy_toio +#endif + +#ifndef fb_memset +static inline void fb_memset_io(volatile void __iomem *addr, int c, size_t n) +{ + memset_io(addr, c, n); +} +#define fb_memset fb_memset_io +#endif #endif /* __ASM_GENERIC_FB_H_ */ diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 6432a7fade91..94cbd50cc870 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -89,27 +89,35 @@ do { \ __ret; \ }) -#define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ +#define __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, _cmpxchg) \ +({ \ + typeof(pcp) __val, __old = *(ovalp); \ + __val = _cmpxchg(pcp, __old, nval); \ + if (__val != __old) \ + *(ovalp) = __val; \ + __val == __old; \ +}) + +#define raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) \ ({ \ typeof(pcp) *__p = raw_cpu_ptr(&(pcp)); \ - typeof(pcp) __ret; \ - __ret = *__p; \ - if (__ret == (oval)) \ + typeof(pcp) __val = *__p, ___old = *(ovalp); \ + bool __ret; \ + if (__val == ___old) { \ *__p = nval; \ + __ret = true; \ + } else { \ + *(ovalp) = __val; \ + __ret = false; \ + } \ __ret; \ }) -#define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ +#define raw_cpu_generic_cmpxchg(pcp, oval, nval) \ ({ \ - typeof(pcp1) *__p1 = raw_cpu_ptr(&(pcp1)); \ - typeof(pcp2) *__p2 = raw_cpu_ptr(&(pcp2)); \ - int __ret = 0; \ - if (*__p1 == (oval1) && *__p2 == (oval2)) { \ - *__p1 = nval1; \ - *__p2 = nval2; \ - __ret = 1; \ - } \ - (__ret); \ + typeof(pcp) __old = (oval); \ + raw_cpu_generic_try_cmpxchg(pcp, &__old, nval); \ + __old; \ }) #define __this_cpu_generic_read_nopreempt(pcp) \ @@ -170,23 +178,22 @@ do { \ __ret; \ }) -#define this_cpu_generic_cmpxchg(pcp, oval, nval) \ +#define this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) \ ({ \ - typeof(pcp) __ret; \ + bool __ret; \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - __ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \ + __ret = raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval); \ raw_local_irq_restore(__flags); \ __ret; \ }) -#define this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ +#define this_cpu_generic_cmpxchg(pcp, oval, nval) \ ({ \ - int __ret; \ + typeof(pcp) __ret; \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - __ret = raw_cpu_generic_cmpxchg_double(pcp1, pcp2, \ - oval1, oval2, nval1, nval2); \ + __ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \ raw_local_irq_restore(__flags); \ __ret; \ }) @@ -282,6 +289,62 @@ do { \ #define raw_cpu_xchg_8(pcp, nval) raw_cpu_generic_xchg(pcp, nval) #endif +#ifndef raw_cpu_try_cmpxchg_1 +#ifdef raw_cpu_cmpxchg_1 +#define raw_cpu_try_cmpxchg_1(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg_1) +#else +#define raw_cpu_try_cmpxchg_1(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef raw_cpu_try_cmpxchg_2 +#ifdef raw_cpu_cmpxchg_2 +#define raw_cpu_try_cmpxchg_2(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg_2) +#else +#define raw_cpu_try_cmpxchg_2(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef raw_cpu_try_cmpxchg_4 +#ifdef raw_cpu_cmpxchg_4 +#define raw_cpu_try_cmpxchg_4(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg_4) +#else +#define raw_cpu_try_cmpxchg_4(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef raw_cpu_try_cmpxchg_8 +#ifdef raw_cpu_cmpxchg_8 +#define raw_cpu_try_cmpxchg_8(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg_8) +#else +#define raw_cpu_try_cmpxchg_8(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif + +#ifndef raw_cpu_try_cmpxchg64 +#ifdef raw_cpu_cmpxchg64 +#define raw_cpu_try_cmpxchg64(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg64) +#else +#define raw_cpu_try_cmpxchg64(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef raw_cpu_try_cmpxchg128 +#ifdef raw_cpu_cmpxchg128 +#define raw_cpu_try_cmpxchg128(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, raw_cpu_cmpxchg128) +#else +#define raw_cpu_try_cmpxchg128(pcp, ovalp, nval) \ + raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif + #ifndef raw_cpu_cmpxchg_1 #define raw_cpu_cmpxchg_1(pcp, oval, nval) \ raw_cpu_generic_cmpxchg(pcp, oval, nval) @@ -299,21 +362,13 @@ do { \ raw_cpu_generic_cmpxchg(pcp, oval, nval) #endif -#ifndef raw_cpu_cmpxchg_double_1 -#define raw_cpu_cmpxchg_double_1(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) -#endif -#ifndef raw_cpu_cmpxchg_double_2 -#define raw_cpu_cmpxchg_double_2(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) -#endif -#ifndef raw_cpu_cmpxchg_double_4 -#define raw_cpu_cmpxchg_double_4(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) +#ifndef raw_cpu_cmpxchg64 +#define raw_cpu_cmpxchg64(pcp, oval, nval) \ + raw_cpu_generic_cmpxchg(pcp, oval, nval) #endif -#ifndef raw_cpu_cmpxchg_double_8 -#define raw_cpu_cmpxchg_double_8(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) +#ifndef raw_cpu_cmpxchg128 +#define raw_cpu_cmpxchg128(pcp, oval, nval) \ + raw_cpu_generic_cmpxchg(pcp, oval, nval) #endif #ifndef this_cpu_read_1 @@ -407,6 +462,62 @@ do { \ #define this_cpu_xchg_8(pcp, nval) this_cpu_generic_xchg(pcp, nval) #endif +#ifndef this_cpu_try_cmpxchg_1 +#ifdef this_cpu_cmpxchg_1 +#define this_cpu_try_cmpxchg_1(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg_1) +#else +#define this_cpu_try_cmpxchg_1(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef this_cpu_try_cmpxchg_2 +#ifdef this_cpu_cmpxchg_2 +#define this_cpu_try_cmpxchg_2(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg_2) +#else +#define this_cpu_try_cmpxchg_2(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef this_cpu_try_cmpxchg_4 +#ifdef this_cpu_cmpxchg_4 +#define this_cpu_try_cmpxchg_4(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg_4) +#else +#define this_cpu_try_cmpxchg_4(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef this_cpu_try_cmpxchg_8 +#ifdef this_cpu_cmpxchg_8 +#define this_cpu_try_cmpxchg_8(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg_8) +#else +#define this_cpu_try_cmpxchg_8(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif + +#ifndef this_cpu_try_cmpxchg64 +#ifdef this_cpu_cmpxchg64 +#define this_cpu_try_cmpxchg64(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg64) +#else +#define this_cpu_try_cmpxchg64(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif +#ifndef this_cpu_try_cmpxchg128 +#ifdef this_cpu_cmpxchg128 +#define this_cpu_try_cmpxchg128(pcp, ovalp, nval) \ + __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, this_cpu_cmpxchg128) +#else +#define this_cpu_try_cmpxchg128(pcp, ovalp, nval) \ + this_cpu_generic_try_cmpxchg(pcp, ovalp, nval) +#endif +#endif + #ifndef this_cpu_cmpxchg_1 #define this_cpu_cmpxchg_1(pcp, oval, nval) \ this_cpu_generic_cmpxchg(pcp, oval, nval) @@ -424,21 +535,13 @@ do { \ this_cpu_generic_cmpxchg(pcp, oval, nval) #endif -#ifndef this_cpu_cmpxchg_double_1 -#define this_cpu_cmpxchg_double_1(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) -#endif -#ifndef this_cpu_cmpxchg_double_2 -#define this_cpu_cmpxchg_double_2(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) -#endif -#ifndef this_cpu_cmpxchg_double_4 -#define this_cpu_cmpxchg_double_4(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) +#ifndef this_cpu_cmpxchg64 +#define this_cpu_cmpxchg64(pcp, oval, nval) \ + this_cpu_generic_cmpxchg(pcp, oval, nval) #endif -#ifndef this_cpu_cmpxchg_double_8 -#define this_cpu_cmpxchg_double_8(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) +#ifndef this_cpu_cmpxchg128 +#define this_cpu_cmpxchg128(pcp, oval, nval) \ + this_cpu_generic_cmpxchg(pcp, oval, nval) #endif #endif /* _ASM_GENERIC_PERCPU_H_ */ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index d1f57e4868ed..45401f7a3548 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -839,6 +839,9 @@ #ifdef CONFIG_UNWINDER_ORC #define ORC_UNWIND_TABLE \ + .orc_header : AT(ADDR(.orc_header) - LOAD_OFFSET) { \ + BOUNDED_SECTION_BY(.orc_header, _orc_header) \ + } \ . = ALIGN(4); \ .orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) { \ BOUNDED_SECTION_BY(.orc_unwind_ip, _orc_unwind_ip) \ @@ -891,9 +894,16 @@ /* * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler. * Otherwise, the type of .notes section would become PROGBITS instead of NOTES. + * + * Also, discard .note.gnu.property, otherwise it forces the notes section to + * be 8-byte aligned which causes alignment mismatches with the kernel's custom + * 4-byte aligned notes. */ #define NOTES \ - /DISCARD/ : { *(.note.GNU-stack) } \ + /DISCARD/ : { \ + *(.note.GNU-stack) \ + *(.note.gnu.property) \ + } \ .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ BOUNDED_SECTION_BY(.note.*, _notes) \ } NOTES_HEADERS \ @@ -1006,6 +1016,7 @@ PATCHABLE_DISCARDS \ *(.discard) \ *(.discard.*) \ + *(.export_symbol) \ *(.modinfo) \ /* ld.bfd warns about .gnu.version* even when not emitted */ \ *(.gnu.version*) \ diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h index 536f897375d0..6cdc873ac907 100644 --- a/include/clocksource/hyperv_timer.h +++ b/include/clocksource/hyperv_timer.h @@ -38,8 +38,9 @@ extern void hv_remap_tsc_clocksource(void); extern unsigned long hv_get_tsc_pfn(void); extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void); -static inline notrace u64 -hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc) +static __always_inline bool +hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, + u64 *cur_tsc, u64 *time) { u64 scale, offset; u32 sequence; @@ -63,7 +64,7 @@ hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc) do { sequence = READ_ONCE(tsc_pg->tsc_sequence); if (!sequence) - return U64_MAX; + return false; /* * Make sure we read sequence before we read other values from * TSC page. @@ -82,15 +83,8 @@ hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc) } while (READ_ONCE(tsc_pg->tsc_sequence) != sequence); - return mul_u64_u64_shr(*cur_tsc, scale, 64) + offset; -} - -static inline notrace u64 -hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg) -{ - u64 cur_tsc; - - return hv_read_tsc_page_tsc(tsc_pg, &cur_tsc); + *time = mul_u64_u64_shr(*cur_tsc, scale, 64) + offset; + return true; } #else /* CONFIG_HYPERV_TIMER */ @@ -104,10 +98,10 @@ static inline struct ms_hyperv_tsc_page *hv_get_tsc_page(void) return NULL; } -static inline u64 hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, - u64 *cur_tsc) +static __always_inline bool +hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc, u64 *time) { - return U64_MAX; + return false; } static inline int hv_stimer_cleanup(unsigned int cpu) { return 0; } diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h index f35fd653e4e5..670508f1dca1 100644 --- a/include/crypto/akcipher.h +++ b/include/crypto/akcipher.h @@ -374,6 +374,42 @@ static inline int crypto_akcipher_decrypt(struct akcipher_request *req) } /** + * crypto_akcipher_sync_encrypt() - Invoke public key encrypt operation + * + * Function invokes the specific public key encrypt operation for a given + * public key algorithm + * + * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() + * @src: source buffer + * @slen: source length + * @dst: destinatino obuffer + * @dlen: destination length + * + * Return: zero on success; error code in case of error + */ +int crypto_akcipher_sync_encrypt(struct crypto_akcipher *tfm, + const void *src, unsigned int slen, + void *dst, unsigned int dlen); + +/** + * crypto_akcipher_sync_decrypt() - Invoke public key decrypt operation + * + * Function invokes the specific public key decrypt operation for a given + * public key algorithm + * + * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() + * @src: source buffer + * @slen: source length + * @dst: destinatino obuffer + * @dlen: destination length + * + * Return: Output length on success; error code in case of error + */ +int crypto_akcipher_sync_decrypt(struct crypto_akcipher *tfm, + const void *src, unsigned int slen, + void *dst, unsigned int dlen); + +/** * crypto_akcipher_sign() - Invoke public key sign operation * * Function invokes the specific public key sign operation for a given diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 016d5a302b84..6156161b181f 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -56,7 +56,6 @@ struct sk_buff; struct crypto_type { unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask); unsigned int (*extsize)(struct crypto_alg *alg); - int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); int (*init_tfm)(struct crypto_tfm *tfm); void (*show)(struct seq_file *m, struct crypto_alg *alg); int (*report)(struct sk_buff *skb, struct crypto_alg *alg); diff --git a/include/crypto/b128ops.h b/include/crypto/b128ops.h index 0b8e6bc55301..f3b37cbb3131 100644 --- a/include/crypto/b128ops.h +++ b/include/crypto/b128ops.h @@ -50,10 +50,6 @@ #include <linux/types.h> typedef struct { - u64 a, b; -} u128; - -typedef struct { __be64 a, b; } be128; @@ -61,20 +57,16 @@ typedef struct { __le64 b, a; } le128; -static inline void u128_xor(u128 *r, const u128 *p, const u128 *q) +static inline void be128_xor(be128 *r, const be128 *p, const be128 *q) { r->a = p->a ^ q->a; r->b = p->b ^ q->b; } -static inline void be128_xor(be128 *r, const be128 *p, const be128 *q) -{ - u128_xor((u128 *)r, (u128 *)p, (u128 *)q); -} - static inline void le128_xor(le128 *r, const le128 *p, const le128 *q) { - u128_xor((u128 *)r, (u128 *)p, (u128 *)q); + r->a = p->a ^ q->a; + r->b = p->b ^ q->b; } #endif /* _CRYPTO_B128OPS_H */ diff --git a/include/crypto/engine.h b/include/crypto/engine.h index ae133e98d813..2038764b30c2 100644 --- a/include/crypto/engine.h +++ b/include/crypto/engine.h @@ -78,7 +78,7 @@ struct crypto_engine { /* * struct crypto_engine_op - crypto hardware engine operations - * @prepare__request: do some prepare if need before handle the current request + * @prepare_request: do some preparation if needed before handling the current request * @unprepare_request: undo any work done by prepare_request() * @do_one_request: do encryption for current request */ diff --git a/include/crypto/hash.h b/include/crypto/hash.h index e69542d86a2b..f7c2a22cd776 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -260,6 +260,7 @@ struct crypto_ahash { int (*setkey)(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen); + unsigned int statesize; unsigned int reqsize; struct crypto_tfm base; }; @@ -400,7 +401,7 @@ static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm) */ static inline unsigned int crypto_ahash_statesize(struct crypto_ahash *tfm) { - return crypto_hash_alg_common(tfm)->statesize; + return tfm->statesize; } static inline u32 crypto_ahash_get_flags(struct crypto_ahash *tfm) diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index 7e76623f9ec3..ef8ce86b1f78 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -56,9 +56,9 @@ struct af_alg_type { }; struct af_alg_sgl { - struct scatterlist sg[ALG_MAX_PAGES + 1]; - struct page *pages[ALG_MAX_PAGES]; - unsigned int npages; + struct sg_table sgt; + struct scatterlist sgl[ALG_MAX_PAGES + 1]; + bool need_unpin; }; /* TX SGL entry */ @@ -163,7 +163,6 @@ int af_alg_release(struct socket *sock); void af_alg_release_parent(struct sock *sk); int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern); -int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len); void af_alg_free_sg(struct af_alg_sgl *sgl); static inline struct alg_sock *alg_sk(struct sock *sk) @@ -230,8 +229,6 @@ void af_alg_wmem_wakeup(struct sock *sk); int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min); int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, unsigned int ivsize); -ssize_t af_alg_sendpage(struct socket *sock, struct page *page, - int offset, size_t size, int flags); void af_alg_free_resources(struct af_alg_async_req *areq); void af_alg_async_cb(void *data, int err); __poll_t af_alg_poll(struct file *file, struct socket *sock, diff --git a/include/crypto/internal/cipher.h b/include/crypto/internal/cipher.h index a9174ba90250..5030f6d2df31 100644 --- a/include/crypto/internal/cipher.h +++ b/include/crypto/internal/cipher.h @@ -176,6 +176,8 @@ void crypto_cipher_encrypt_one(struct crypto_cipher *tfm, void crypto_cipher_decrypt_one(struct crypto_cipher *tfm, u8 *dst, const u8 *src); +struct crypto_cipher *crypto_clone_cipher(struct crypto_cipher *cipher); + struct crypto_cipher_spawn { struct crypto_spawn base; }; diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 37edf3f4e8af..cf65676e45f4 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -149,6 +149,18 @@ static inline struct ahash_alg *__crypto_ahash_alg(struct crypto_alg *alg) halg); } +static inline struct ahash_alg *crypto_ahash_alg(struct crypto_ahash *hash) +{ + return container_of(crypto_hash_alg_common(hash), struct ahash_alg, + halg); +} + +static inline void crypto_ahash_set_statesize(struct crypto_ahash *tfm, + unsigned int size) +{ + tfm->statesize = size; +} + static inline void crypto_ahash_set_reqsize(struct crypto_ahash *tfm, unsigned int reqsize) { diff --git a/include/crypto/internal/sig.h b/include/crypto/internal/sig.h new file mode 100644 index 000000000000..97cb26ef8115 --- /dev/null +++ b/include/crypto/internal/sig.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Public Key Signature Algorithm + * + * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au> + */ +#ifndef _CRYPTO_INTERNAL_SIG_H +#define _CRYPTO_INTERNAL_SIG_H + +#include <crypto/algapi.h> +#include <crypto/sig.h> + +static inline void *crypto_sig_ctx(struct crypto_sig *tfm) +{ + return crypto_tfm_ctx(&tfm->base); +} +#endif diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index 653992a6e941..8fadd561c50e 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -48,8 +48,6 @@ struct public_key_signature { const char *pkey_algo; const char *hash_algo; const char *encoding; - const void *data; - unsigned int data_size; }; extern void public_key_signature_free(struct public_key_signature *sig); diff --git a/include/crypto/sha2.h b/include/crypto/sha2.h index 2838f529f31e..b9e9281d76c9 100644 --- a/include/crypto/sha2.h +++ b/include/crypto/sha2.h @@ -128,7 +128,7 @@ static inline void sha224_init(struct sha256_state *sctx) sctx->state[7] = SHA224_H7; sctx->count = 0; } -void sha224_update(struct sha256_state *sctx, const u8 *data, unsigned int len); +/* Simply use sha256_update as it is equivalent to sha224_update. */ void sha224_final(struct sha256_state *sctx, u8 *out); #endif /* _CRYPTO_SHA2_H */ diff --git a/include/crypto/sha256_base.h b/include/crypto/sha256_base.h index 76173c613058..ab904d82236f 100644 --- a/include/crypto/sha256_base.h +++ b/include/crypto/sha256_base.h @@ -8,13 +8,12 @@ #ifndef _CRYPTO_SHA256_BASE_H #define _CRYPTO_SHA256_BASE_H +#include <asm/byteorder.h> +#include <asm/unaligned.h> #include <crypto/internal/hash.h> #include <crypto/sha2.h> -#include <linux/crypto.h> -#include <linux/module.h> #include <linux/string.h> - -#include <asm/unaligned.h> +#include <linux/types.h> typedef void (sha256_block_fn)(struct sha256_state *sst, u8 const *src, int blocks); @@ -35,12 +34,11 @@ static inline int sha256_base_init(struct shash_desc *desc) return 0; } -static inline int sha256_base_do_update(struct shash_desc *desc, - const u8 *data, - unsigned int len, - sha256_block_fn *block_fn) +static inline int lib_sha256_base_do_update(struct sha256_state *sctx, + const u8 *data, + unsigned int len, + sha256_block_fn *block_fn) { - struct sha256_state *sctx = shash_desc_ctx(desc); unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; sctx->count += len; @@ -73,11 +71,20 @@ static inline int sha256_base_do_update(struct shash_desc *desc, return 0; } -static inline int sha256_base_do_finalize(struct shash_desc *desc, - sha256_block_fn *block_fn) +static inline int sha256_base_do_update(struct shash_desc *desc, + const u8 *data, + unsigned int len, + sha256_block_fn *block_fn) { - const int bit_offset = SHA256_BLOCK_SIZE - sizeof(__be64); struct sha256_state *sctx = shash_desc_ctx(desc); + + return lib_sha256_base_do_update(sctx, data, len, block_fn); +} + +static inline int lib_sha256_base_do_finalize(struct sha256_state *sctx, + sha256_block_fn *block_fn) +{ + const int bit_offset = SHA256_BLOCK_SIZE - sizeof(__be64); __be64 *bits = (__be64 *)(sctx->buf + bit_offset); unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; @@ -96,10 +103,17 @@ static inline int sha256_base_do_finalize(struct shash_desc *desc, return 0; } -static inline int sha256_base_finish(struct shash_desc *desc, u8 *out) +static inline int sha256_base_do_finalize(struct shash_desc *desc, + sha256_block_fn *block_fn) { - unsigned int digest_size = crypto_shash_digestsize(desc->tfm); struct sha256_state *sctx = shash_desc_ctx(desc); + + return lib_sha256_base_do_finalize(sctx, block_fn); +} + +static inline int lib_sha256_base_finish(struct sha256_state *sctx, u8 *out, + unsigned int digest_size) +{ __be32 *digest = (__be32 *)out; int i; @@ -110,4 +124,12 @@ static inline int sha256_base_finish(struct shash_desc *desc, u8 *out) return 0; } +static inline int sha256_base_finish(struct shash_desc *desc, u8 *out) +{ + unsigned int digest_size = crypto_shash_digestsize(desc->tfm); + struct sha256_state *sctx = shash_desc_ctx(desc); + + return lib_sha256_base_finish(sctx, out, digest_size); +} + #endif /* _CRYPTO_SHA256_BASE_H */ diff --git a/include/crypto/sig.h b/include/crypto/sig.h new file mode 100644 index 000000000000..641b4714c448 --- /dev/null +++ b/include/crypto/sig.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Public Key Signature Algorithm + * + * Copyright (c) 2023 Herbert Xu <herbert@gondor.apana.org.au> + */ +#ifndef _CRYPTO_SIG_H +#define _CRYPTO_SIG_H + +#include <linux/crypto.h> + +/** + * struct crypto_sig - user-instantiated objects which encapsulate + * algorithms and core processing logic + * + * @base: Common crypto API algorithm data structure + */ +struct crypto_sig { + struct crypto_tfm base; +}; + +/** + * DOC: Generic Public Key Signature API + * + * The Public Key Signature API is used with the algorithms of type + * CRYPTO_ALG_TYPE_SIG (listed as type "sig" in /proc/crypto) + */ + +/** + * crypto_alloc_sig() - allocate signature tfm handle + * @alg_name: is the cra_name / name or cra_driver_name / driver name of the + * signing algorithm e.g. "ecdsa" + * @type: specifies the type of the algorithm + * @mask: specifies the mask for the algorithm + * + * Allocate a handle for public key signature algorithm. The returned struct + * crypto_sig is the handle that is required for any subsequent + * API invocation for signature operations. + * + * Return: allocated handle in case of success; IS_ERR() is true in case + * of an error, PTR_ERR() returns the error code. + */ +struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask); + +static inline struct crypto_tfm *crypto_sig_tfm(struct crypto_sig *tfm) +{ + return &tfm->base; +} + +/** + * crypto_free_sig() - free signature tfm handle + * + * @tfm: signature tfm handle allocated with crypto_alloc_sig() + * + * If @tfm is a NULL or error pointer, this function does nothing. + */ +static inline void crypto_free_sig(struct crypto_sig *tfm) +{ + crypto_destroy_tfm(tfm, crypto_sig_tfm(tfm)); +} + +/** + * crypto_sig_maxsize() - Get len for output buffer + * + * Function returns the dest buffer size required for a given key. + * Function assumes that the key is already set in the transformation. If this + * function is called without a setkey or with a failed setkey, you will end up + * in a NULL dereference. + * + * @tfm: signature tfm handle allocated with crypto_alloc_sig() + */ +int crypto_sig_maxsize(struct crypto_sig *tfm); + +/** + * crypto_sig_sign() - Invoke signing operation + * + * Function invokes the specific signing operation for a given algorithm + * + * @tfm: signature tfm handle allocated with crypto_alloc_sig() + * @src: source buffer + * @slen: source length + * @dst: destinatino obuffer + * @dlen: destination length + * + * Return: zero on success; error code in case of error + */ +int crypto_sig_sign(struct crypto_sig *tfm, + const void *src, unsigned int slen, + void *dst, unsigned int dlen); + +/** + * crypto_sig_verify() - Invoke signature verification + * + * Function invokes the specific signature verification operation + * for a given algorithm. + * + * @tfm: signature tfm handle allocated with crypto_alloc_sig() + * @src: source buffer + * @slen: source length + * @digest: digest + * @dlen: digest length + * + * Return: zero on verification success; error code in case of error. + */ +int crypto_sig_verify(struct crypto_sig *tfm, + const void *src, unsigned int slen, + const void *digest, unsigned int dlen); + +/** + * crypto_sig_set_pubkey() - Invoke set public key operation + * + * Function invokes the algorithm specific set key function, which knows + * how to decode and interpret the encoded key and parameters + * + * @tfm: tfm handle + * @key: BER encoded public key, algo OID, paramlen, BER encoded + * parameters + * @keylen: length of the key (not including other data) + * + * Return: zero on success; error code in case of error + */ +int crypto_sig_set_pubkey(struct crypto_sig *tfm, + const void *key, unsigned int keylen); + +/** + * crypto_sig_set_privkey() - Invoke set private key operation + * + * Function invokes the algorithm specific set key function, which knows + * how to decode and interpret the encoded key and parameters + * + * @tfm: tfm handle + * @key: BER encoded private key, algo OID, paramlen, BER encoded + * parameters + * @keylen: length of the key (not including other data) + * + * Return: zero on success; error code in case of error + */ +int crypto_sig_set_privkey(struct crypto_sig *tfm, + const void *key, unsigned int keylen); +#endif diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h index af452556dcd4..04a92c1013c8 100644 --- a/include/crypto/sm2.h +++ b/include/crypto/sm2.h @@ -11,15 +11,18 @@ #ifndef _CRYPTO_SM2_H #define _CRYPTO_SM2_H -#include <crypto/sm3.h> -#include <crypto/akcipher.h> +struct shash_desc; -/* The default user id as specified in GM/T 0009-2012 */ -#define SM2_DEFAULT_USERID "1234567812345678" -#define SM2_DEFAULT_USERID_LEN 16 - -extern int sm2_compute_z_digest(struct crypto_akcipher *tfm, - const unsigned char *id, size_t id_len, - unsigned char dgst[SM3_DIGEST_SIZE]); +#if IS_REACHABLE(CONFIG_CRYPTO_SM2) +int sm2_compute_z_digest(struct shash_desc *desc, + const void *key, unsigned int keylen, void *dgst); +#else +static inline int sm2_compute_z_digest(struct shash_desc *desc, + const void *key, unsigned int keylen, + void *dgst) +{ + return -ENOTSUPP; +} +#endif #endif /* _CRYPTO_SM2_H */ diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h index ba5484de2b30..05100e91ecb9 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -54,11 +54,14 @@ struct samsung_dsim_driver_data { unsigned int has_freqband:1; unsigned int has_clklane_stop:1; unsigned int num_clks; + unsigned int min_freq; unsigned int max_freq; unsigned int wait_for_reset; unsigned int num_bits_resol; unsigned int pll_p_offset; const unsigned int *reg_values; + u16 m_min; + u16 m_max; }; struct samsung_dsim_host_ops { @@ -90,11 +93,14 @@ struct samsung_dsim { u32 pll_clk_rate; u32 burst_clk_rate; + u32 hs_clock; u32 esc_clk_rate; u32 lanes; u32 mode_flags; u32 format; + bool swap_dn_dp_clk; + bool swap_dn_dp_data; int state; struct drm_property *brightness; struct completion completed; diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 358db4a9f167..02f2ac4dd2df 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -286,9 +286,8 @@ #define DP_DSC_MAX_BITS_PER_PIXEL_HI 0x068 /* eDP 1.4 */ # define DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK (0x3 << 0) -# define DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT 8 -# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK 0x06 -# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY 0x08 +# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK (0x3 << 5) /* eDP 1.5 & DP 2.0 */ +# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY (1 << 7) /* eDP 1.5 & DP 2.0 */ #define DP_DSC_DEC_COLOR_FORMAT_CAP 0x069 # define DP_DSC_RGB (1 << 0) @@ -983,6 +982,7 @@ #define DP_EDP_GENERAL_CAP_2 0x703 # define DP_EDP_OVERDRIVE_ENGINE_ENABLED (1 << 0) +# define DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE (1 << 4) #define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */ # define DP_EDP_X_REGION_CAP_MASK (0xf << 0) @@ -1008,6 +1008,7 @@ # define DP_EDP_DYNAMIC_BACKLIGHT_ENABLE (1 << 4) # define DP_EDP_REGIONAL_BACKLIGHT_ENABLE (1 << 5) # define DP_EDP_UPDATE_REGION_BRIGHTNESS (1 << 6) /* eDP 1.4 */ +# define DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE (1 << 7) #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722 #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723 @@ -1032,6 +1033,7 @@ #define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732 #define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733 +#define DP_EDP_PANEL_TARGET_LUMINANCE_VALUE 0x734 #define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */ #define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */ @@ -1633,7 +1635,7 @@ enum dp_pixelformat { * * This enum is used to indicate DP VSC SDP Colorimetry formats. * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through - * DB18] and a name of enum member follows DRM_MODE_COLORIMETRY definition. + * DB18] and a name of enum member follows enum drm_colorimetry definition. * * @DP_COLORIMETRY_DEFAULT: sRGB (IEC 61966-2-1) or * ITU-R BT.601 colorimetry format diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 533d3ee7fe05..86f24a759268 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -181,9 +181,8 @@ static inline u16 drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) { return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | - (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] & - DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK << - DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT); + ((dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] & + DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK) << 8); } static inline u32 diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 32c764fb9cb5..ed5c9660563c 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -138,12 +138,7 @@ struct drm_dp_mst_port { * @cached_edid: for DP logical ports - make tiling work by ensuring * that the EDID for all connectors is read immediately. */ - struct edid *cached_edid; - /** - * @has_audio: Tracks whether the sink connector to this port is - * audio-capable. - */ - bool has_audio; + const struct drm_edid *cached_edid; /** * @fec_capable: bool indicating if FEC can be supported up to that @@ -815,8 +810,11 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr); bool drm_dp_read_mst_cap(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE]); int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state); -int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled); - +int drm_dp_mst_hpd_irq_handle_event(struct drm_dp_mst_topology_mgr *mgr, + const u8 *esi, + u8 *ack, + bool *handled); +void drm_dp_mst_hpd_irq_send_new_request(struct drm_dp_mst_topology_mgr *mgr); int drm_dp_mst_detect_port(struct drm_connector *connector, @@ -824,7 +822,12 @@ drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); -struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); +const struct drm_edid *drm_dp_mst_edid_read(struct drm_connector *connector, + struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port); +struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, + struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port); int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr, int link_rate, int link_lane_count); diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index 8b41edbbabab..913aa2071232 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -10,11 +10,24 @@ #include <drm/display/drm_dsc.h> +enum drm_dsc_params_type { + DRM_DSC_1_2_444, + DRM_DSC_1_1_PRE_SCR, /* legacy params from DSC 1.1 */ + DRM_DSC_1_2_422, + DRM_DSC_1_2_420, +}; + void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header); int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size); void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp, const struct drm_dsc_config *dsc_cfg); +void drm_dsc_set_const_params(struct drm_dsc_config *vdsc_cfg); +void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); +int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); +u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc); +u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc); +u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg); #endif /* _DRM_DSC_HELPER_H_ */ diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h index 7096703c3949..cbe33b49fd5d 100644 --- a/include/drm/drm_aperture.h +++ b/include/drm/drm_aperture.h @@ -13,14 +13,13 @@ int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t resource_size_t size); int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - bool primary, const struct drm_driver *req_driver); + const struct drm_driver *req_driver); int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const struct drm_driver *req_driver); /** * drm_aperture_remove_framebuffers - remove all existing framebuffers - * @primary: also kick vga16fb if present * @req_driver: requesting DRM driver * * This function removes all graphics device drivers. Use this function on systems @@ -30,9 +29,9 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, * 0 on success, or a negative errno code otherwise */ static inline int -drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver) +drm_aperture_remove_framebuffers(const struct drm_driver *req_driver) { - return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, + return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, req_driver); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 7b5048516185..d300fde6c1a4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -30,6 +30,7 @@ #include <linux/notifier.h> #include <drm/drm_mode_object.h> #include <drm/drm_util.h> +#include <drm/drm_property.h> #include <uapi/drm/drm_mode.h> @@ -199,6 +200,11 @@ enum drm_connector_tv_mode { */ DRM_MODE_TV_MODE_SECAM, + /** + * @DRM_MODE_TV_MODE_MAX: Number of analog TV output modes. + * + * Internal implementation detail; this is not uABI. + */ DRM_MODE_TV_MODE_MAX, }; @@ -419,37 +425,106 @@ enum drm_privacy_screen_status { PRIVACY_SCREEN_ENABLED_LOCKED, }; -/* - * This is a consolidated colorimetry list supported by HDMI and +/** + * enum drm_colorspace - color space + * + * This enum is a consolidated colorimetry list supported by HDMI and * DP protocol standard. The respective connectors will register * a property with the subset of this list (supported by that * respective protocol). Userspace will set the colorspace through * a colorspace property which will be created and exposed to * userspace. + * + * DP definitions come from the DP v2.0 spec + * HDMI definitions come from the CTA-861-H spec + * + * A note on YCC and RGB variants: + * + * Since userspace is not aware of the encoding on the wire + * (RGB or YCbCr), drivers are free to pick the appropriate + * variant, regardless of what userspace selects. E.g., if + * BT2020_RGB is selected by userspace a driver will pick + * BT2020_YCC if the encoding on the wire is YUV444 or YUV420. + * + * @DRM_MODE_COLORIMETRY_DEFAULT: + * Driver specific behavior. + * @DRM_MODE_COLORIMETRY_NO_DATA: + * Driver specific behavior. + * @DRM_MODE_COLORIMETRY_SMPTE_170M_YCC: + * (HDMI) + * SMPTE ST 170M colorimetry format + * @DRM_MODE_COLORIMETRY_BT709_YCC: + * (HDMI, DP) + * ITU-R BT.709 colorimetry format + * @DRM_MODE_COLORIMETRY_XVYCC_601: + * (HDMI, DP) + * xvYCC601 colorimetry format + * @DRM_MODE_COLORIMETRY_XVYCC_709: + * (HDMI, DP) + * xvYCC709 colorimetry format + * @DRM_MODE_COLORIMETRY_SYCC_601: + * (HDMI, DP) + * sYCC601 colorimetry format + * @DRM_MODE_COLORIMETRY_OPYCC_601: + * (HDMI, DP) + * opYCC601 colorimetry format + * @DRM_MODE_COLORIMETRY_OPRGB: + * (HDMI, DP) + * opRGB colorimetry format + * @DRM_MODE_COLORIMETRY_BT2020_CYCC: + * (HDMI, DP) + * ITU-R BT.2020 Y'c C'bc C'rc (constant luminance) colorimetry format + * @DRM_MODE_COLORIMETRY_BT2020_RGB: + * (HDMI, DP) + * ITU-R BT.2020 R' G' B' colorimetry format + * @DRM_MODE_COLORIMETRY_BT2020_YCC: + * (HDMI, DP) + * ITU-R BT.2020 Y' C'b C'r colorimetry format + * @DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65: + * (HDMI) + * SMPTE ST 2113 P3D65 colorimetry format + * @DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER: + * (HDMI) + * SMPTE ST 2113 P3DCI colorimetry format + * @DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED: + * (DP) + * RGB wide gamut fixed point colorimetry format + * @DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT: + * (DP) + * RGB wide gamut floating point + * (scRGB (IEC 61966-2-2)) colorimetry format + * @DRM_MODE_COLORIMETRY_BT601_YCC: + * (DP) + * ITU-R BT.601 colorimetry format + * The DP spec does not say whether this is the 525 or the 625 + * line version. */ - -/* For Default case, driver will set the colorspace */ -#define DRM_MODE_COLORIMETRY_DEFAULT 0 -/* CEA 861 Normal Colorimetry options */ -#define DRM_MODE_COLORIMETRY_NO_DATA 0 -#define DRM_MODE_COLORIMETRY_SMPTE_170M_YCC 1 -#define DRM_MODE_COLORIMETRY_BT709_YCC 2 -/* CEA 861 Extended Colorimetry Options */ -#define DRM_MODE_COLORIMETRY_XVYCC_601 3 -#define DRM_MODE_COLORIMETRY_XVYCC_709 4 -#define DRM_MODE_COLORIMETRY_SYCC_601 5 -#define DRM_MODE_COLORIMETRY_OPYCC_601 6 -#define DRM_MODE_COLORIMETRY_OPRGB 7 -#define DRM_MODE_COLORIMETRY_BT2020_CYCC 8 -#define DRM_MODE_COLORIMETRY_BT2020_RGB 9 -#define DRM_MODE_COLORIMETRY_BT2020_YCC 10 -/* Additional Colorimetry extension added as part of CTA 861.G */ -#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65 11 -#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER 12 -/* Additional Colorimetry Options added for DP 1.4a VSC Colorimetry Format */ -#define DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED 13 -#define DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT 14 -#define DRM_MODE_COLORIMETRY_BT601_YCC 15 +enum drm_colorspace { + /* For Default case, driver will set the colorspace */ + DRM_MODE_COLORIMETRY_DEFAULT = 0, + /* CEA 861 Normal Colorimetry options */ + DRM_MODE_COLORIMETRY_NO_DATA = 0, + DRM_MODE_COLORIMETRY_SMPTE_170M_YCC = 1, + DRM_MODE_COLORIMETRY_BT709_YCC = 2, + /* CEA 861 Extended Colorimetry Options */ + DRM_MODE_COLORIMETRY_XVYCC_601 = 3, + DRM_MODE_COLORIMETRY_XVYCC_709 = 4, + DRM_MODE_COLORIMETRY_SYCC_601 = 5, + DRM_MODE_COLORIMETRY_OPYCC_601 = 6, + DRM_MODE_COLORIMETRY_OPRGB = 7, + DRM_MODE_COLORIMETRY_BT2020_CYCC = 8, + DRM_MODE_COLORIMETRY_BT2020_RGB = 9, + DRM_MODE_COLORIMETRY_BT2020_YCC = 10, + /* Additional Colorimetry extension added as part of CTA 861.G */ + DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65 = 11, + DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER = 12, + /* Additional Colorimetry Options added for DP 1.4a VSC Colorimetry Format */ + DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED = 13, + DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT = 14, + DRM_MODE_COLORIMETRY_BT601_YCC = 15, + /* not a valid value; merely used for counting */ + DRM_MODE_COLORIMETRY_COUNT +}; /** * enum drm_bus_flags - bus_flags info for &drm_display_info @@ -654,6 +729,14 @@ struct drm_display_info { bool is_hdmi; /** + * @has_audio: True if the sink supports audio. + * + * This field shall be used instead of calling + * drm_detect_monitor_audio() when possible. + */ + bool has_audio; + + /** * @has_hdmi_infoframe: Does the sink support the HDMI infoframe? */ bool has_hdmi_infoframe; @@ -901,7 +984,7 @@ struct drm_connector_state { * colorspace change on Sink. This is most commonly used to switch * to wider color gamuts like BT2020. */ - u32 colorspace; + enum drm_colorspace colorspace; /** * @writeback_job: Writeback job for writeback connectors @@ -1925,8 +2008,10 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state, struct drm_connector_state *new_state); int drm_mode_create_aspect_ratio_property(struct drm_device *dev); -int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector); -int drm_mode_create_dp_colorspace_property(struct drm_connector *connector); +int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector, + u32 supported_colorspaces); +int drm_mode_create_dp_colorspace_property(struct drm_connector *connector, + u32 supported_colorspaces); int drm_mode_create_content_type_property(struct drm_device *dev); int drm_mode_create_suggested_offset_properties(struct drm_device *dev); @@ -2009,6 +2094,7 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter); bool drm_connector_has_possible_encoder(struct drm_connector *connector, struct drm_encoder *encoder); +const char *drm_get_colorspace_name(enum drm_colorspace colorspace); /** * drm_for_each_connector_iter - connector_list iterator macro diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index b419c59c4bef..89e2706cac56 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -401,6 +401,13 @@ struct drm_driver { struct drm_device *dev, uint32_t handle, uint64_t *offset); + /** + * @show_fdinfo: + * + * Print device specific fdinfo. See Documentation/gpu/drm-usage-stats.rst. + */ + void (*show_fdinfo)(struct drm_printer *p, struct drm_file *f); + /** @major: driver major number */ int major; /** @minor: driver minor number */ diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 571885d32907..169755d3de19 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -613,6 +613,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector, const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector, int (*read_block)(void *context, u8 *buf, unsigned int block, size_t len), void *context); +const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector, + struct i2c_adapter *adapter); int drm_edid_connector_update(struct drm_connector *connector, const struct drm_edid *edid); int drm_edid_connector_add_modes(struct drm_connector *connector); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 72032c354a30..4863b0f8299e 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -253,31 +253,10 @@ void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes); -void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist); +void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len); +void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height); -ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf, - size_t count, loff_t *ppos); -ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos); - -void drm_fb_helper_sys_fillrect(struct fb_info *info, - const struct fb_fillrect *rect); -void drm_fb_helper_sys_copyarea(struct fb_info *info, - const struct fb_copyarea *area); -void drm_fb_helper_sys_imageblit(struct fb_info *info, - const struct fb_image *image); - -ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, - size_t count, loff_t *ppos); -ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos); - -void drm_fb_helper_cfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect); -void drm_fb_helper_cfb_copyarea(struct fb_info *info, - const struct fb_copyarea *area); -void drm_fb_helper_cfb_imageblit(struct fb_info *info, - const struct fb_image *image); +void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagereflist); void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend); void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, @@ -394,62 +373,6 @@ static inline int drm_fb_helper_defio_init(struct drm_fb_helper *fb_helper) return -ENODEV; } -static inline ssize_t drm_fb_helper_sys_read(struct fb_info *info, - char __user *buf, size_t count, - loff_t *ppos) -{ - return -ENODEV; -} - -static inline ssize_t drm_fb_helper_sys_write(struct fb_info *info, - const char __user *buf, - size_t count, loff_t *ppos) -{ - return -ENODEV; -} - -static inline void drm_fb_helper_sys_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ -} - -static inline void drm_fb_helper_sys_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ -} - -static inline void drm_fb_helper_sys_imageblit(struct fb_info *info, - const struct fb_image *image) -{ -} - -static inline ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf, - size_t count, loff_t *ppos) -{ - return -ENODEV; -} - -static inline ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) -{ - return -ENODEV; -} - -static inline void drm_fb_helper_cfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ -} - -static inline void drm_fb_helper_cfb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ -} - -static inline void drm_fb_helper_cfb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ -} - static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper, bool suspend) { diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index ecffe24e2b1b..966912053cb0 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -41,6 +41,7 @@ struct dma_fence; struct drm_file; struct drm_device; +struct drm_printer; struct device; struct file; @@ -258,6 +259,9 @@ struct drm_file { /** @pid: Process that opened this file. */ struct pid *pid; + /** @client_id: A unique id for fdinfo */ + u64 client_id; + /** @magic: Authentication magic, see @authenticated. */ drm_magic_t magic; @@ -439,6 +443,34 @@ void drm_send_event_timestamp_locked(struct drm_device *dev, struct drm_pending_event *e, ktime_t timestamp); +/** + * struct drm_memory_stats - GEM object stats associated + * @shared: Total size of GEM objects shared between processes + * @private: Total size of GEM objects + * @resident: Total size of GEM objects backing pages + * @purgeable: Total size of GEM objects that can be purged (resident and not active) + * @active: Total size of GEM objects active on one or more engines + * + * Used by drm_print_memory_stats() + */ +struct drm_memory_stats { + u64 shared; + u64 private; + u64 resident; + u64 purgeable; + u64 active; +}; + +enum drm_gem_object_status; + +void drm_print_memory_stats(struct drm_printer *p, + const struct drm_memory_stats *stats, + enum drm_gem_object_status supported_status, + const char *region); + +void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file); +void drm_show_fdinfo(struct seq_file *m, struct file *f); + struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); #endif /* _DRM_FILE_H_ */ diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 255645c1f9a8..6ea339d5de08 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -71,6 +71,7 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) } #define DRM_FIXED_POINT 32 +#define DRM_FIXED_POINT_HALF 16 #define DRM_FIXED_ONE (1ULL << DRM_FIXED_POINT) #define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1) #define DRM_FIXED_DIGITS_MASK (~DRM_FIXED_DECIMAL_MASK) @@ -87,6 +88,11 @@ static inline int drm_fixp2int(s64 a) return ((s64)a) >> DRM_FIXED_POINT; } +static inline int drm_fixp2int_round(s64 a) +{ + return drm_fixp2int(a + (1 << (DRM_FIXED_POINT_HALF - 1))); +} + static inline int drm_fixp2int_ceil(s64 a) { if (a > 0) diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index b8efd836edef..bbc721870c13 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -43,6 +43,25 @@ struct iosys_map; struct drm_gem_object; /** + * enum drm_gem_object_status - bitmask of object state for fdinfo reporting + * @DRM_GEM_OBJECT_RESIDENT: object is resident in memory (ie. not unpinned) + * @DRM_GEM_OBJECT_PURGEABLE: object marked as purgeable by userspace + * + * Bitmask of status used for fdinfo memory stats, see &drm_gem_object_funcs.status + * and drm_show_fdinfo(). Note that an object can DRM_GEM_OBJECT_PURGEABLE if + * it still active or not resident, in which case drm_show_fdinfo() will not + * account for it as purgeable. So drivers do not need to check if the buffer + * is idle and resident to return this bit. (Ie. userspace can mark a buffer + * as purgeable even while it is still busy on the GPU.. it does not _actually_ + * become puregeable until it becomes idle. The status gem object func does + * not need to consider this.) + */ +enum drm_gem_object_status { + DRM_GEM_OBJECT_RESIDENT = BIT(0), + DRM_GEM_OBJECT_PURGEABLE = BIT(1), +}; + +/** * struct drm_gem_object_funcs - GEM object functions */ struct drm_gem_object_funcs { @@ -175,6 +194,19 @@ struct drm_gem_object_funcs { int (*evict)(struct drm_gem_object *obj); /** + * @status: + * + * The optional status callback can return additional object state + * which determines which stats the object is counted against. The + * callback is called under table_lock. Racing against object status + * change is "harmless", and the callback can expect to not race + * against object destruction. + * + * Called by drm_show_memory_stats(). + */ + enum drm_gem_object_status (*status)(struct drm_gem_object *obj); + + /** * @vm_ops: * * Virtual memory operations used with mmap. diff --git a/include/drm/drm_managed.h b/include/drm/drm_managed.h index 359883942612..ad08f834af40 100644 --- a/include/drm/drm_managed.h +++ b/include/drm/drm_managed.h @@ -105,6 +105,22 @@ char *drmm_kstrdup(struct drm_device *dev, const char *s, gfp_t gfp); void drmm_kfree(struct drm_device *dev, void *data); -int drmm_mutex_init(struct drm_device *dev, struct mutex *lock); +void __drmm_mutex_release(struct drm_device *dev, void *res); + +/** + * drmm_mutex_init - &drm_device-managed mutex_init() + * @dev: DRM device + * @lock: lock to be initialized + * + * Returns: + * 0 on success, or a negative errno code otherwise. + * + * This is a &drm_device-managed version of mutex_init(). The initialized + * lock is automatically destroyed on the final drm_dev_put(). + */ +#define drmm_mutex_init(dev, lock) ({ \ + mutex_init(lock); \ + drmm_add_action_or_reset(dev, __drmm_mutex_release, lock); \ +}) \ #endif diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index c0586d832260..e95b4837e5a3 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -201,7 +201,7 @@ struct drm_sched_entity { * by the scheduler thread, can be accessed locklessly from * drm_sched_job_arm() iff the queue is empty. */ - struct dma_fence *last_scheduled; + struct dma_fence __rcu *last_scheduled; /** * @last_user: last group leader pushing a job into the entity. @@ -549,7 +549,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity, unsigned int num_sched_list); void drm_sched_job_cleanup(struct drm_sched_job *job); -void drm_sched_wakeup(struct drm_gpu_scheduler *sched); +void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched); void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad); void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery); void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched); @@ -581,6 +581,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job); void drm_sched_entity_set_priority(struct drm_sched_entity *entity, enum drm_sched_priority priority); bool drm_sched_entity_is_ready(struct drm_sched_entity *entity); +int drm_sched_entity_error(struct drm_sched_entity *entity); void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, struct dma_fence *fence); @@ -591,7 +592,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence, void drm_sched_fence_free(struct drm_sched_fence *fence); void drm_sched_fence_scheduled(struct drm_sched_fence *fence); -void drm_sched_fence_finished(struct drm_sched_fence *fence); +void drm_sched_fence_finished(struct drm_sched_fence *fence, int result); unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched, diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h index c1e2a43d2d1e..56a84ee1c64c 100644 --- a/include/drm/i915_component.h +++ b/include/drm/i915_component.h @@ -29,7 +29,8 @@ enum i915_component_type { I915_COMPONENT_AUDIO = 1, I915_COMPONENT_HDCP, - I915_COMPONENT_PXP + I915_COMPONENT_PXP, + I915_COMPONENT_GSC_PROXY, }; /* MAX_PORT is the number of port diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7adce327c1c2..adff68538484 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -42,7 +42,7 @@ extern struct resource intel_graphics_stolen_res; * The Bridge device's PCI config space has information about the * fb aperture size and the amount of pre-reserved memory. * This is all handled in the intel-gtt.ko module. i915.ko only - * cares about the vga bit for the vga rbiter. + * cares about the vga bit for the vga arbiter. */ #define INTEL_GMCH_CTRL 0x52 #define INTEL_GMCH_VGA_DISABLE (1 << 1) diff --git a/include/drm/i915_gsc_proxy_mei_interface.h b/include/drm/i915_gsc_proxy_mei_interface.h new file mode 100644 index 000000000000..9462341d3ae1 --- /dev/null +++ b/include/drm/i915_gsc_proxy_mei_interface.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (c) 2022-2023 Intel Corporation + */ + +#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_ +#define _I915_GSC_PROXY_MEI_INTERFACE_H_ + +#include <linux/types.h> + +struct device; +struct module; + +/** + * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services. + * @owner: Module providing the ops + * @send: sends a proxy message from GSC FW to ME FW + * @recv: receives a proxy message for GSC FW from ME FW + */ +struct i915_gsc_proxy_component_ops { + struct module *owner; + + /** + * send - Sends a proxy message to ME FW. + * @dev: device struct corresponding to the mei device + * @buf: message buffer to send + * @size: size of the message + * Return: bytes sent on success, negative errno value on failure + */ + int (*send)(struct device *dev, const void *buf, size_t size); + + /** + * recv - Receives a proxy message from ME FW. + * @dev: device struct corresponding to the mei device + * @buf: message buffer to contain the received message + * @size: size of the buffer + * Return: bytes received on success, negative errno value on failure + */ + int (*recv)(struct device *dev, void *buf, size_t size); +}; + +/** + * struct i915_gsc_proxy_component - Used for communication between i915 and + * MEI drivers for GSC proxy services + * @mei_dev: device that provide the GSC proxy service. + * @ops: Ops implemented by GSC proxy driver, used by i915 driver. + */ +struct i915_gsc_proxy_component { + struct device *mei_dev; + const struct i915_gsc_proxy_component_ops *ops; +}; + +#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */ diff --git a/include/drm/i915_hdcp_interface.h b/include/drm/i915_hdcp_interface.h index 2059b066f8a1..4c9c8167c2d5 100644 --- a/include/drm/i915_hdcp_interface.h +++ b/include/drm/i915_hdcp_interface.h @@ -168,12 +168,12 @@ struct i915_hdcp_ops { }; /** - * struct i915_hdcp_master - Used for communication between i915 + * struct i915_hdcp_arbiter - Used for communication between i915 * and hdcp drivers for the HDCP2.2 services * @hdcp_dev: device that provide the HDCP2.2 service from MEI Bus. * @hdcp_ops: Ops implemented by hdcp driver or intel_hdcp_gsc , used by i915 driver. */ -struct i915_hdcp_master { +struct i915_hdcp_arbiter { struct device *hdcp_dev; const struct i915_hdcp_ops *ops; diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 56e82ba2d046..c22f30535c84 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -223,7 +223,7 @@ struct ttm_device { * @funcs: Function table for the device. * Constant after bo device init */ - struct ttm_device_funcs *funcs; + const struct ttm_device_funcs *funcs; /** * @sysman: Resource manager for the system domain. @@ -287,7 +287,7 @@ static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type, bdev->man_drv[type] = manager; } -int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs, +int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs, struct device *dev, struct address_space *mapping, struct drm_vma_offset_manager *vma_manager, bool use_dma_alloc, bool use_dma32); diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h index 8ce14f9d202a..30a347e5aa11 100644 --- a/include/drm/ttm/ttm_pool.h +++ b/include/drm/ttm/ttm_pool.h @@ -61,12 +61,14 @@ struct ttm_pool_type { * struct ttm_pool - Pool for all caching and orders * * @dev: the device we allocate pages for + * @nid: which numa node to use * @use_dma_alloc: if coherent DMA allocations should be used * @use_dma32: if GFP_DMA32 should be used * @caching: pools for each caching/order */ struct ttm_pool { struct device *dev; + int nid; bool use_dma_alloc; bool use_dma32; @@ -81,7 +83,7 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt, void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt); void ttm_pool_init(struct ttm_pool *pool, struct device *dev, - bool use_dma_alloc, bool use_dma32); + int nid, bool use_dma_alloc, bool use_dma32); void ttm_pool_fini(struct ttm_pool *pool); int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m); diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 977ca195a536..a4eff85b1f44 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -222,7 +222,7 @@ void ttm_tt_mgr_init(unsigned long num_pages, unsigned long num_dma32_pages); struct ttm_kmap_iter *ttm_kmap_iter_tt_init(struct ttm_kmap_iter_tt *iter_tt, struct ttm_tt *tt); - +unsigned long ttm_tt_pages_limit(void); #if IS_ENABLED(CONFIG_AGP) #include <linux/agp_backend.h> diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 802495b20276..bcbe9ee2cdaf 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -216,6 +216,9 @@ #define QCOM_ID_SM8350 439 #define QCOM_ID_QCM2290 441 #define QCOM_ID_SM6115 444 +#define QCOM_ID_IPQ5010 446 +#define QCOM_ID_IPQ5018 447 +#define QCOM_ID_IPQ5028 448 #define QCOM_ID_SC8280XP 449 #define QCOM_ID_IPQ6005 453 #define QCOM_ID_QRB5165 455 @@ -229,6 +232,9 @@ #define QCOM_ID_SM8450_3 482 #define QCOM_ID_SC7280 487 #define QCOM_ID_SC7180P 495 +#define QCOM_ID_IPQ5000 503 +#define QCOM_ID_IPQ0509 504 +#define QCOM_ID_IPQ0518 505 #define QCOM_ID_SM6375 507 #define QCOM_ID_IPQ9514 510 #define QCOM_ID_IPQ9550 511 @@ -236,6 +242,7 @@ #define QCOM_ID_IPQ9570 513 #define QCOM_ID_IPQ9574 514 #define QCOM_ID_SM8550 519 +#define QCOM_ID_IPQ5016 520 #define QCOM_ID_IPQ9510 521 #define QCOM_ID_QRB4210 523 #define QCOM_ID_QRB2210 524 @@ -243,11 +250,15 @@ #define QCOM_ID_QRU1000 539 #define QCOM_ID_QDU1000 545 #define QCOM_ID_QDU1010 587 +#define QCOM_ID_IPQ5019 569 #define QCOM_ID_QRU1032 588 #define QCOM_ID_QRU1052 589 #define QCOM_ID_QRU1062 590 #define QCOM_ID_IPQ5332 592 #define QCOM_ID_IPQ5322 593 +#define QCOM_ID_IPQ5312 594 +#define QCOM_ID_IPQ5302 595 +#define QCOM_ID_IPQ5300 624 /* * The board type and revision information, used by Qualcomm bootloaders and diff --git a/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h new file mode 100644 index 000000000000..ff2730f398a6 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a1-peripherals-clkc.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu <jian.hu@amlogic.com> + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru> + */ + +#ifndef __A1_PERIPHERALS_CLKC_H +#define __A1_PERIPHERALS_CLKC_H + +#define CLKID_FIXPLL_IN 1 +#define CLKID_USB_PHY_IN 2 +#define CLKID_USB_CTRL_IN 3 +#define CLKID_HIFIPLL_IN 4 +#define CLKID_SYSPLL_IN 5 +#define CLKID_DDS_IN 6 +#define CLKID_SYS 7 +#define CLKID_CLKTREE 8 +#define CLKID_RESET_CTRL 9 +#define CLKID_ANALOG_CTRL 10 +#define CLKID_PWR_CTRL 11 +#define CLKID_PAD_CTRL 12 +#define CLKID_SYS_CTRL 13 +#define CLKID_TEMP_SENSOR 14 +#define CLKID_AM2AXI_DIV 15 +#define CLKID_SPICC_B 16 +#define CLKID_SPICC_A 17 +#define CLKID_MSR 18 +#define CLKID_AUDIO 19 +#define CLKID_JTAG_CTRL 20 +#define CLKID_SARADC_EN 21 +#define CLKID_PWM_EF 22 +#define CLKID_PWM_CD 23 +#define CLKID_PWM_AB 24 +#define CLKID_CEC 25 +#define CLKID_I2C_S 26 +#define CLKID_IR_CTRL 27 +#define CLKID_I2C_M_D 28 +#define CLKID_I2C_M_C 29 +#define CLKID_I2C_M_B 30 +#define CLKID_I2C_M_A 31 +#define CLKID_ACODEC 32 +#define CLKID_OTP 33 +#define CLKID_SD_EMMC_A 34 +#define CLKID_USB_PHY 35 +#define CLKID_USB_CTRL 36 +#define CLKID_SYS_DSPB 37 +#define CLKID_SYS_DSPA 38 +#define CLKID_DMA 39 +#define CLKID_IRQ_CTRL 40 +#define CLKID_NIC 41 +#define CLKID_GIC 42 +#define CLKID_UART_C 43 +#define CLKID_UART_B 44 +#define CLKID_UART_A 45 +#define CLKID_SYS_PSRAM 46 +#define CLKID_RSA 47 +#define CLKID_CORESIGHT 48 +#define CLKID_AM2AXI_VAD 49 +#define CLKID_AUDIO_VAD 50 +#define CLKID_AXI_DMC 51 +#define CLKID_AXI_PSRAM 52 +#define CLKID_RAMB 53 +#define CLKID_RAMA 54 +#define CLKID_AXI_SPIFC 55 +#define CLKID_AXI_NIC 56 +#define CLKID_AXI_DMA 57 +#define CLKID_CPU_CTRL 58 +#define CLKID_ROM 59 +#define CLKID_PROC_I2C 60 +#define CLKID_DSPA_EN 63 +#define CLKID_DSPA_EN_NIC 64 +#define CLKID_DSPB_EN 65 +#define CLKID_DSPB_EN_NIC 66 +#define CLKID_RTC 67 +#define CLKID_CECA_32K 68 +#define CLKID_CECB_32K 69 +#define CLKID_24M 70 +#define CLKID_12M 71 +#define CLKID_FCLK_DIV2_DIVN 72 +#define CLKID_GEN 73 +#define CLKID_SARADC 75 +#define CLKID_PWM_A 76 +#define CLKID_PWM_B 77 +#define CLKID_PWM_C 78 +#define CLKID_PWM_D 79 +#define CLKID_PWM_E 80 +#define CLKID_PWM_F 81 +#define CLKID_SPICC 82 +#define CLKID_TS 83 +#define CLKID_SPIFC 84 +#define CLKID_USB_BUS 85 +#define CLKID_SD_EMMC 86 +#define CLKID_PSRAM 87 +#define CLKID_DMC 88 +#define CLKID_DSPA_A_SEL 95 +#define CLKID_DSPA_B_SEL 98 +#define CLKID_DSPB_A_SEL 101 +#define CLKID_DSPB_B_SEL 104 +#define CLKID_CECB_32K_SEL_PRE 113 +#define CLKID_CECB_32K_SEL 114 +#define CLKID_CECA_32K_SEL_PRE 117 +#define CLKID_CECA_32K_SEL 118 +#define CLKID_GEN_SEL 121 +#define CLKID_PWM_A_SEL 124 +#define CLKID_PWM_B_SEL 126 +#define CLKID_PWM_C_SEL 128 +#define CLKID_PWM_D_SEL 130 +#define CLKID_PWM_E_SEL 132 +#define CLKID_PWM_F_SEL 134 +#define CLKID_SD_EMMC_SEL2 147 + +#endif /* __A1_PERIPHERALS_CLKC_H */ diff --git a/include/dt-bindings/clock/amlogic,a1-pll-clkc.h b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h new file mode 100644 index 000000000000..01fb8164ac29 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,a1-pll-clkc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + * Author: Jian Hu <jian.hu@amlogic.com> + * + * Copyright (c) 2023, SberDevices. All Rights Reserved. + * Author: Dmitry Rokosov <ddrokosov@sberdevices.ru> + */ + +#ifndef __A1_PLL_CLKC_H +#define __A1_PLL_CLKC_H + +#define CLKID_FIXED_PLL 1 +#define CLKID_FCLK_DIV2 6 +#define CLKID_FCLK_DIV3 7 +#define CLKID_FCLK_DIV5 8 +#define CLKID_FCLK_DIV7 9 +#define CLKID_HIFI_PLL 10 + +#endif /* __A1_PLL_CLKC_H */ diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h new file mode 100644 index 000000000000..ba2d70f776a6 --- /dev/null +++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h @@ -0,0 +1,253 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */ +/* + * Copyright (C) 2023 Nuvoton Technologies. + */ + +#ifndef __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H +#define __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H + +/* external and internal oscillator clocks */ +#define HXT 0 +#define HXT_GATE 1 +#define LXT 2 +#define LXT_GATE 3 +#define HIRC 4 +#define HIRC_GATE 5 +#define LIRC 6 +#define LIRC_GATE 7 +/* PLLs */ +#define CAPLL 8 +#define SYSPLL 9 +#define DDRPLL 10 +#define APLL 11 +#define EPLL 12 +#define VPLL 13 +/* EPLL divider */ +#define EPLL_DIV2 14 +#define EPLL_DIV4 15 +#define EPLL_DIV8 16 +/* CPU clock, system clock, AXI, HCLK and PCLK */ +#define CA35CLK_MUX 17 +#define AXICLK_DIV2 18 +#define AXICLK_DIV4 19 +#define AXICLK_MUX 20 +#define SYSCLK0_MUX 21 +#define SYSCLK1_MUX 22 +#define SYSCLK1_DIV2 23 +#define HCLK0 24 +#define HCLK1 25 +#define HCLK2 26 +#define PCLK0 27 +#define PCLK1 28 +#define PCLK2 29 +#define HCLK3 30 +#define PCLK3 31 +#define PCLK4 32 +/* AXI and AHB peripheral clocks */ +#define USBPHY0 33 +#define USBPHY1 34 +#define DDR0_GATE 35 +#define DDR6_GATE 36 +#define CAN0_MUX 37 +#define CAN0_DIV 38 +#define CAN0_GATE 39 +#define CAN1_MUX 40 +#define CAN1_DIV 41 +#define CAN1_GATE 42 +#define CAN2_MUX 43 +#define CAN2_DIV 44 +#define CAN2_GATE 45 +#define CAN3_MUX 46 +#define CAN3_DIV 47 +#define CAN3_GATE 48 +#define SDH0_MUX 49 +#define SDH0_GATE 50 +#define SDH1_MUX 51 +#define SDH1_GATE 52 +#define NAND_GATE 53 +#define USBD_GATE 54 +#define USBH_GATE 55 +#define HUSBH0_GATE 56 +#define HUSBH1_GATE 57 +#define GFX_MUX 58 +#define GFX_GATE 59 +#define VC8K_GATE 60 +#define DCU_MUX 61 +#define DCU_GATE 62 +#define DCUP_DIV 63 +#define EMAC0_GATE 64 +#define EMAC1_GATE 65 +#define CCAP0_MUX 66 +#define CCAP0_DIV 67 +#define CCAP0_GATE 68 +#define CCAP1_MUX 69 +#define CCAP1_DIV 70 +#define CCAP1_GATE 71 +#define PDMA0_GATE 72 +#define PDMA1_GATE 73 +#define PDMA2_GATE 74 +#define PDMA3_GATE 75 +#define WH0_GATE 76 +#define WH1_GATE 77 +#define HWS_GATE 78 +#define EBI_GATE 79 +#define SRAM0_GATE 80 +#define SRAM1_GATE 81 +#define ROM_GATE 82 +#define TRA_GATE 83 +#define DBG_MUX 84 +#define DBG_GATE 85 +#define CKO_MUX 86 +#define CKO_DIV 87 +#define CKO_GATE 88 +#define GTMR_GATE 89 +#define GPA_GATE 90 +#define GPB_GATE 91 +#define GPC_GATE 92 +#define GPD_GATE 93 +#define GPE_GATE 94 +#define GPF_GATE 95 +#define GPG_GATE 96 +#define GPH_GATE 97 +#define GPI_GATE 98 +#define GPJ_GATE 99 +#define GPK_GATE 100 +#define GPL_GATE 101 +#define GPM_GATE 102 +#define GPN_GATE 103 +/* APB peripheral clocks */ +#define TMR0_MUX 104 +#define TMR0_GATE 105 +#define TMR1_MUX 106 +#define TMR1_GATE 107 +#define TMR2_MUX 108 +#define TMR2_GATE 109 +#define TMR3_MUX 110 +#define TMR3_GATE 111 +#define TMR4_MUX 112 +#define TMR4_GATE 113 +#define TMR5_MUX 114 +#define TMR5_GATE 115 +#define TMR6_MUX 116 +#define TMR6_GATE 117 +#define TMR7_MUX 118 +#define TMR7_GATE 119 +#define TMR8_MUX 120 +#define TMR8_GATE 121 +#define TMR9_MUX 122 +#define TMR9_GATE 123 +#define TMR10_MUX 124 +#define TMR10_GATE 125 +#define TMR11_MUX 126 +#define TMR11_GATE 127 +#define UART0_MUX 128 +#define UART0_DIV 129 +#define UART0_GATE 130 +#define UART1_MUX 131 +#define UART1_DIV 132 +#define UART1_GATE 133 +#define UART2_MUX 134 +#define UART2_DIV 135 +#define UART2_GATE 136 +#define UART3_MUX 137 +#define UART3_DIV 138 +#define UART3_GATE 139 +#define UART4_MUX 140 +#define UART4_DIV 141 +#define UART4_GATE 142 +#define UART5_MUX 143 +#define UART5_DIV 144 +#define UART5_GATE 145 +#define UART6_MUX 146 +#define UART6_DIV 147 +#define UART6_GATE 148 +#define UART7_MUX 149 +#define UART7_DIV 150 +#define UART7_GATE 151 +#define UART8_MUX 152 +#define UART8_DIV 153 +#define UART8_GATE 154 +#define UART9_MUX 155 +#define UART9_DIV 156 +#define UART9_GATE 157 +#define UART10_MUX 158 +#define UART10_DIV 159 +#define UART10_GATE 160 +#define UART11_MUX 161 +#define UART11_DIV 162 +#define UART11_GATE 163 +#define UART12_MUX 164 +#define UART12_DIV 165 +#define UART12_GATE 166 +#define UART13_MUX 167 +#define UART13_DIV 168 +#define UART13_GATE 169 +#define UART14_MUX 170 +#define UART14_DIV 171 +#define UART14_GATE 172 +#define UART15_MUX 173 +#define UART15_DIV 174 +#define UART15_GATE 175 +#define UART16_MUX 176 +#define UART16_DIV 177 +#define UART16_GATE 178 +#define RTC_GATE 179 +#define DDR_GATE 180 +#define KPI_MUX 181 +#define KPI_DIV 182 +#define KPI_GATE 183 +#define I2C0_GATE 184 +#define I2C1_GATE 185 +#define I2C2_GATE 186 +#define I2C3_GATE 187 +#define I2C4_GATE 188 +#define I2C5_GATE 189 +#define QSPI0_MUX 190 +#define QSPI0_GATE 191 +#define QSPI1_MUX 192 +#define QSPI1_GATE 193 +#define SMC0_MUX 194 +#define SMC0_DIV 195 +#define SMC0_GATE 196 +#define SMC1_MUX 197 +#define SMC1_DIV 198 +#define SMC1_GATE 199 +#define WDT0_MUX 200 +#define WDT0_GATE 201 +#define WDT1_MUX 202 +#define WDT1_GATE 203 +#define WDT2_MUX 204 +#define WDT2_GATE 205 +#define WWDT0_MUX 206 +#define WWDT1_MUX 207 +#define WWDT2_MUX 208 +#define EPWM0_GATE 209 +#define EPWM1_GATE 210 +#define EPWM2_GATE 211 +#define I2S0_MUX 212 +#define I2S0_GATE 213 +#define I2S1_MUX 214 +#define I2S1_GATE 215 +#define SSMCC_GATE 216 +#define SSPCC_GATE 217 +#define SPI0_MUX 218 +#define SPI0_GATE 219 +#define SPI1_MUX 220 +#define SPI1_GATE 221 +#define SPI2_MUX 222 +#define SPI2_GATE 223 +#define SPI3_MUX 224 +#define SPI3_GATE 225 +#define ECAP0_GATE 226 +#define ECAP1_GATE 227 +#define ECAP2_GATE 228 +#define QEI0_GATE 229 +#define QEI1_GATE 230 +#define QEI2_GATE 231 +#define ADC_DIV 232 +#define ADC_GATE 233 +#define EADC_DIV 234 +#define EADC_GATE 235 +#define CLK_MAX_IDX 236 + +#endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */ diff --git a/include/dt-bindings/clock/qcom,ipq9574-gcc.h b/include/dt-bindings/clock/qcom,ipq9574-gcc.h index 5a2961bfe893..b32a7aa65349 100644 --- a/include/dt-bindings/clock/qcom,ipq9574-gcc.h +++ b/include/dt-bindings/clock/qcom,ipq9574-gcc.h @@ -210,4 +210,8 @@ #define GCC_SNOC_PCIE1_1LANE_S_CLK 201 #define GCC_SNOC_PCIE2_2LANE_S_CLK 202 #define GCC_SNOC_PCIE3_2LANE_S_CLK 203 +#define GCC_CRYPTO_CLK_SRC 204 +#define GCC_CRYPTO_CLK 205 +#define GCC_CRYPTO_AXI_CLK 206 +#define GCC_CRYPTO_AHB_CLK 207 #endif diff --git a/include/dt-bindings/clock/qcom,sc8280xp-lpasscc.h b/include/dt-bindings/clock/qcom,sc8280xp-lpasscc.h new file mode 100644 index 000000000000..d190d57fc81a --- /dev/null +++ b/include/dt-bindings/clock/qcom,sc8280xp-lpasscc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, Linaro Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_LPASSCC_SC8280XP_H +#define _DT_BINDINGS_CLK_QCOM_LPASSCC_SC8280XP_H + +/* LPASS AUDIO CC CSR */ +#define LPASS_AUDIO_SWR_RX_CGCR 0 +#define LPASS_AUDIO_SWR_WSA_CGCR 1 +#define LPASS_AUDIO_SWR_WSA2_CGCR 2 + +/* LPASS TCSR */ +#define LPASS_AUDIO_SWR_TX_CGCR 0 + +#endif diff --git a/include/dt-bindings/clock/qcom,sdx75-gcc.h b/include/dt-bindings/clock/qcom,sdx75-gcc.h new file mode 100644 index 000000000000..a470e8c4fd41 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sdx75-gcc.h @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SDX75_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SDX75_H + +/* GCC clocks */ +#define GPLL0 0 +#define GPLL0_OUT_EVEN 1 +#define GPLL4 2 +#define GPLL5 3 +#define GPLL6 4 +#define GPLL8 5 +#define GCC_AHB_PCIE_LINK_CLK 6 +#define GCC_BOOT_ROM_AHB_CLK 7 +#define GCC_EEE_EMAC0_CLK 8 +#define GCC_EEE_EMAC0_CLK_SRC 9 +#define GCC_EEE_EMAC1_CLK 10 +#define GCC_EEE_EMAC1_CLK_SRC 11 +#define GCC_EMAC0_AXI_CLK 12 +#define GCC_EMAC0_CC_SGMIIPHY_RX_CLK 13 +#define GCC_EMAC0_CC_SGMIIPHY_RX_CLK_SRC 14 +#define GCC_EMAC0_CC_SGMIIPHY_TX_CLK 15 +#define GCC_EMAC0_CC_SGMIIPHY_TX_CLK_SRC 16 +#define GCC_EMAC0_PHY_AUX_CLK 17 +#define GCC_EMAC0_PHY_AUX_CLK_SRC 18 +#define GCC_EMAC0_PTP_CLK 19 +#define GCC_EMAC0_PTP_CLK_SRC 20 +#define GCC_EMAC0_RGMII_CLK 21 +#define GCC_EMAC0_RGMII_CLK_SRC 22 +#define GCC_EMAC0_RPCS_RX_CLK 23 +#define GCC_EMAC0_RPCS_TX_CLK 24 +#define GCC_EMAC0_SGMIIPHY_MAC_RCLK_SRC 25 +#define GCC_EMAC0_SGMIIPHY_MAC_TCLK_SRC 26 +#define GCC_EMAC0_SLV_AHB_CLK 27 +#define GCC_EMAC0_XGXS_RX_CLK 28 +#define GCC_EMAC0_XGXS_TX_CLK 29 +#define GCC_EMAC1_AXI_CLK 30 +#define GCC_EMAC1_CC_SGMIIPHY_RX_CLK 31 +#define GCC_EMAC1_CC_SGMIIPHY_RX_CLK_SRC 32 +#define GCC_EMAC1_CC_SGMIIPHY_TX_CLK 33 +#define GCC_EMAC1_CC_SGMIIPHY_TX_CLK_SRC 34 +#define GCC_EMAC1_PHY_AUX_CLK 35 +#define GCC_EMAC1_PHY_AUX_CLK_SRC 36 +#define GCC_EMAC1_PTP_CLK 37 +#define GCC_EMAC1_PTP_CLK_SRC 38 +#define GCC_EMAC1_RGMII_CLK 39 +#define GCC_EMAC1_RGMII_CLK_SRC 40 +#define GCC_EMAC1_RPCS_RX_CLK 41 +#define GCC_EMAC1_RPCS_TX_CLK 42 +#define GCC_EMAC1_SGMIIPHY_MAC_RCLK_SRC 43 +#define GCC_EMAC1_SGMIIPHY_MAC_TCLK_SRC 44 +#define GCC_EMAC1_SLV_AHB_CLK 45 +#define GCC_EMAC1_XGXS_RX_CLK 46 +#define GCC_EMAC1_XGXS_TX_CLK 47 +#define GCC_EMAC_0_CLKREF_EN 48 +#define GCC_EMAC_1_CLKREF_EN 49 +#define GCC_GP1_CLK 50 +#define GCC_GP1_CLK_SRC 51 +#define GCC_GP2_CLK 52 +#define GCC_GP2_CLK_SRC 53 +#define GCC_GP3_CLK 54 +#define GCC_GP3_CLK_SRC 55 +#define GCC_PCIE_0_CLKREF_EN 56 +#define GCC_PCIE_1_AUX_CLK 57 +#define GCC_PCIE_1_AUX_PHY_CLK_SRC 58 +#define GCC_PCIE_1_CFG_AHB_CLK 59 +#define GCC_PCIE_1_CLKREF_EN 60 +#define GCC_PCIE_1_MSTR_AXI_CLK 61 +#define GCC_PCIE_1_PHY_RCHNG_CLK 62 +#define GCC_PCIE_1_PHY_RCHNG_CLK_SRC 63 +#define GCC_PCIE_1_PIPE_CLK 64 +#define GCC_PCIE_1_PIPE_CLK_SRC 65 +#define GCC_PCIE_1_PIPE_DIV2_CLK 66 +#define GCC_PCIE_1_PIPE_DIV2_CLK_SRC 67 +#define GCC_PCIE_1_SLV_AXI_CLK 68 +#define GCC_PCIE_1_SLV_Q2A_AXI_CLK 69 +#define GCC_PCIE_2_AUX_CLK 70 +#define GCC_PCIE_2_AUX_PHY_CLK_SRC 71 +#define GCC_PCIE_2_CFG_AHB_CLK 72 +#define GCC_PCIE_2_CLKREF_EN 73 +#define GCC_PCIE_2_MSTR_AXI_CLK 74 +#define GCC_PCIE_2_PHY_RCHNG_CLK 75 +#define GCC_PCIE_2_PHY_RCHNG_CLK_SRC 76 +#define GCC_PCIE_2_PIPE_CLK 77 +#define GCC_PCIE_2_PIPE_CLK_SRC 78 +#define GCC_PCIE_2_PIPE_DIV2_CLK 79 +#define GCC_PCIE_2_PIPE_DIV2_CLK_SRC 80 +#define GCC_PCIE_2_SLV_AXI_CLK 81 +#define GCC_PCIE_2_SLV_Q2A_AXI_CLK 82 +#define GCC_PCIE_AUX_CLK 83 +#define GCC_PCIE_AUX_CLK_SRC 84 +#define GCC_PCIE_AUX_PHY_CLK_SRC 85 +#define GCC_PCIE_CFG_AHB_CLK 86 +#define GCC_PCIE_MSTR_AXI_CLK 87 +#define GCC_PCIE_PIPE_CLK 88 +#define GCC_PCIE_PIPE_CLK_SRC 89 +#define GCC_PCIE_RCHNG_PHY_CLK 90 +#define GCC_PCIE_RCHNG_PHY_CLK_SRC 91 +#define GCC_PCIE_SLEEP_CLK 92 +#define GCC_PCIE_SLV_AXI_CLK 93 +#define GCC_PCIE_SLV_Q2A_AXI_CLK 94 +#define GCC_PDM2_CLK 95 +#define GCC_PDM2_CLK_SRC 96 +#define GCC_PDM_AHB_CLK 97 +#define GCC_PDM_XO4_CLK 98 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 99 +#define GCC_QUPV3_WRAP0_CORE_CLK 100 +#define GCC_QUPV3_WRAP0_S0_CLK 101 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 102 +#define GCC_QUPV3_WRAP0_S1_CLK 103 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 104 +#define GCC_QUPV3_WRAP0_S2_CLK 105 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 106 +#define GCC_QUPV3_WRAP0_S3_CLK 107 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 108 +#define GCC_QUPV3_WRAP0_S4_CLK 109 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 110 +#define GCC_QUPV3_WRAP0_S5_CLK 111 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 112 +#define GCC_QUPV3_WRAP0_S6_CLK 113 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 114 +#define GCC_QUPV3_WRAP0_S7_CLK 115 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 116 +#define GCC_QUPV3_WRAP0_S8_CLK 117 +#define GCC_QUPV3_WRAP0_S8_CLK_SRC 118 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 119 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 120 +#define GCC_SDCC1_AHB_CLK 121 +#define GCC_SDCC1_APPS_CLK 122 +#define GCC_SDCC1_APPS_CLK_SRC 123 +#define GCC_SDCC2_AHB_CLK 124 +#define GCC_SDCC2_APPS_CLK 125 +#define GCC_SDCC2_APPS_CLK_SRC 126 +#define GCC_USB2_CLKREF_EN 127 +#define GCC_USB30_MASTER_CLK 128 +#define GCC_USB30_MASTER_CLK_SRC 129 +#define GCC_USB30_MOCK_UTMI_CLK 130 +#define GCC_USB30_MOCK_UTMI_CLK_SRC 131 +#define GCC_USB30_MOCK_UTMI_POSTDIV_CLK_SRC 132 +#define GCC_USB30_MSTR_AXI_CLK 133 +#define GCC_USB30_SLEEP_CLK 134 +#define GCC_USB30_SLV_AHB_CLK 135 +#define GCC_USB3_PHY_AUX_CLK 136 +#define GCC_USB3_PHY_AUX_CLK_SRC 137 +#define GCC_USB3_PHY_PIPE_CLK 138 +#define GCC_USB3_PHY_PIPE_CLK_SRC 139 +#define GCC_USB3_PRIM_CLKREF_EN 140 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 141 +#define GCC_XO_PCIE_LINK_CLK 142 + +/* GCC power domains */ +#define GCC_EMAC0_GDSC 0 +#define GCC_EMAC1_GDSC 1 +#define GCC_PCIE_1_GDSC 2 +#define GCC_PCIE_1_PHY_GDSC 3 +#define GCC_PCIE_2_GDSC 4 +#define GCC_PCIE_2_PHY_GDSC 5 +#define GCC_PCIE_GDSC 6 +#define GCC_PCIE_PHY_GDSC 7 +#define GCC_USB30_GDSC 8 +#define GCC_USB3_PHY_GDSC 9 + +/* GCC resets */ +#define GCC_EMAC0_BCR 0 +#define GCC_EMAC1_BCR 1 +#define GCC_EMMC_BCR 2 +#define GCC_PCIE_1_BCR 3 +#define GCC_PCIE_1_LINK_DOWN_BCR 4 +#define GCC_PCIE_1_NOCSR_COM_PHY_BCR 5 +#define GCC_PCIE_1_PHY_BCR 6 +#define GCC_PCIE_2_BCR 7 +#define GCC_PCIE_2_LINK_DOWN_BCR 8 +#define GCC_PCIE_2_NOCSR_COM_PHY_BCR 9 +#define GCC_PCIE_2_PHY_BCR 10 +#define GCC_PCIE_BCR 11 +#define GCC_PCIE_LINK_DOWN_BCR 12 +#define GCC_PCIE_NOCSR_COM_PHY_BCR 13 +#define GCC_PCIE_PHY_BCR 14 +#define GCC_PCIE_PHY_CFG_AHB_BCR 15 +#define GCC_PCIE_PHY_COM_BCR 16 +#define GCC_PCIE_PHY_NOCSR_COM_PHY_BCR 17 +#define GCC_QUSB2PHY_BCR 18 +#define GCC_TCSR_PCIE_BCR 19 +#define GCC_USB30_BCR 20 +#define GCC_USB3_PHY_BCR 21 +#define GCC_USB3PHY_PHY_BCR 22 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 23 +#define GCC_EMAC0_RGMII_CLK_ARES 24 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8350-videocc.h b/include/dt-bindings/clock/qcom,sm8350-videocc.h new file mode 100644 index 000000000000..b6945a448676 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8350-videocc.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8350_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8350_H + +/* Clocks */ +#define VIDEO_CC_AHB_CLK_SRC 0 +#define VIDEO_CC_MVS0_CLK 1 +#define VIDEO_CC_MVS0_CLK_SRC 2 +#define VIDEO_CC_MVS0_DIV_CLK_SRC 3 +#define VIDEO_CC_MVS0C_CLK 4 +#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 5 +#define VIDEO_CC_MVS1_CLK 6 +#define VIDEO_CC_MVS1_CLK_SRC 7 +#define VIDEO_CC_MVS1_DIV2_CLK 8 +#define VIDEO_CC_MVS1_DIV_CLK_SRC 9 +#define VIDEO_CC_MVS1C_CLK 10 +#define VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC 11 +#define VIDEO_CC_SLEEP_CLK 12 +#define VIDEO_CC_SLEEP_CLK_SRC 13 +#define VIDEO_CC_XO_CLK_SRC 14 +#define VIDEO_PLL0 15 +#define VIDEO_PLL1 16 + +/* GDSCs */ +#define MVS0C_GDSC 0 +#define MVS1C_GDSC 1 +#define MVS0_GDSC 2 +#define MVS1_GDSC 3 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8450-gpucc.h b/include/dt-bindings/clock/qcom,sm8450-gpucc.h new file mode 100644 index 000000000000..712b171503d6 --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8450-gpucc.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8450_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8450_H + +/* Clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CRC_AHB_CLK 1 +#define GPU_CC_CX_APB_CLK 2 +#define GPU_CC_CX_FF_CLK 3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CX_SNOC_DVM_CLK 5 +#define GPU_CC_CXO_AON_CLK 6 +#define GPU_CC_CXO_CLK 7 +#define GPU_CC_DEMET_CLK 8 +#define GPU_CC_DEMET_DIV_CLK_SRC 9 +#define GPU_CC_FF_CLK_SRC 10 +#define GPU_CC_FREQ_MEASURE_CLK 11 +#define GPU_CC_GMU_CLK_SRC 12 +#define GPU_CC_GX_FF_CLK 13 +#define GPU_CC_GX_GFX3D_CLK 14 +#define GPU_CC_GX_GFX3D_RDVM_CLK 15 +#define GPU_CC_GX_GMU_CLK 16 +#define GPU_CC_GX_VSENSE_CLK 17 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 18 +#define GPU_CC_HUB_AHB_DIV_CLK_SRC 19 +#define GPU_CC_HUB_AON_CLK 20 +#define GPU_CC_HUB_CLK_SRC 21 +#define GPU_CC_HUB_CX_INT_CLK 22 +#define GPU_CC_HUB_CX_INT_DIV_CLK_SRC 23 +#define GPU_CC_MEMNOC_GFX_CLK 24 +#define GPU_CC_MND1X_0_GFX3D_CLK 25 +#define GPU_CC_MND1X_1_GFX3D_CLK 26 +#define GPU_CC_PLL0 27 +#define GPU_CC_PLL1 28 +#define GPU_CC_SLEEP_CLK 29 +#define GPU_CC_XO_CLK_SRC 30 +#define GPU_CC_XO_DIV_CLK_SRC 31 + +/* GDSCs */ +#define GPU_GX_GDSC 0 +#define GPU_CX_GDSC 1 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8450-videocc.h b/include/dt-bindings/clock/qcom,sm8450-videocc.h new file mode 100644 index 000000000000..9d795adfe4eb --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8450-videocc.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8450_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM8450_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_MVS0_CLK 0 +#define VIDEO_CC_MVS0_CLK_SRC 1 +#define VIDEO_CC_MVS0_DIV_CLK_SRC 2 +#define VIDEO_CC_MVS0C_CLK 3 +#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 4 +#define VIDEO_CC_MVS1_CLK 5 +#define VIDEO_CC_MVS1_CLK_SRC 6 +#define VIDEO_CC_MVS1_DIV_CLK_SRC 7 +#define VIDEO_CC_MVS1C_CLK 8 +#define VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC 9 +#define VIDEO_CC_PLL0 10 +#define VIDEO_CC_PLL1 11 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0C_GDSC 0 +#define VIDEO_CC_MVS0_GDSC 1 +#define VIDEO_CC_MVS1C_GDSC 2 +#define VIDEO_CC_MVS1_GDSC 3 + +/* VIDEO_CC resets */ +#define CVP_VIDEO_CC_INTERFACE_BCR 0 +#define CVP_VIDEO_CC_MVS0_BCR 1 +#define CVP_VIDEO_CC_MVS0C_BCR 2 +#define CVP_VIDEO_CC_MVS1_BCR 3 +#define CVP_VIDEO_CC_MVS1C_BCR 4 +#define VIDEO_CC_MVS0C_CLK_ARES 5 +#define VIDEO_CC_MVS1C_CLK_ARES 6 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8550-gpucc.h b/include/dt-bindings/clock/qcom,sm8550-gpucc.h new file mode 100644 index 000000000000..a6760547a3ab --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8550-gpucc.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8550_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SM8550_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CRC_AHB_CLK 1 +#define GPU_CC_CX_FF_CLK 2 +#define GPU_CC_CX_GMU_CLK 3 +#define GPU_CC_CXO_AON_CLK 4 +#define GPU_CC_CXO_CLK 5 +#define GPU_CC_DEMET_CLK 6 +#define GPU_CC_DEMET_DIV_CLK_SRC 7 +#define GPU_CC_FF_CLK_SRC 8 +#define GPU_CC_FREQ_MEASURE_CLK 9 +#define GPU_CC_GMU_CLK_SRC 10 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 11 +#define GPU_CC_HUB_AON_CLK 12 +#define GPU_CC_HUB_CLK_SRC 13 +#define GPU_CC_HUB_CX_INT_CLK 14 +#define GPU_CC_MEMNOC_GFX_CLK 15 +#define GPU_CC_MND1X_0_GFX3D_CLK 16 +#define GPU_CC_MND1X_1_GFX3D_CLK 17 +#define GPU_CC_PLL0 18 +#define GPU_CC_PLL1 19 +#define GPU_CC_SLEEP_CLK 20 +#define GPU_CC_XO_CLK_SRC 21 +#define GPU_CC_XO_DIV_CLK_SRC 22 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +/* GPU_CC resets */ +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR 1 +#define GPUCC_GPU_CC_FAST_HUB_BCR 2 +#define GPUCC_GPU_CC_FF_BCR 3 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 4 +#define GPUCC_GPU_CC_GMU_BCR 5 +#define GPUCC_GPU_CC_GX_BCR 6 +#define GPUCC_GPU_CC_XO_BCR 7 + +#endif diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h index 02befd25edce..0bd7b54c65ff 100644 --- a/include/dt-bindings/clock/stm32mp13-clks.h +++ b/include/dt-bindings/clock/stm32mp13-clks.h @@ -1,7 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ /* * Copyright (C) STMicroelectronics 2020 - All Rights Reserved - * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics. + * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. */ #ifndef _DT_BINDINGS_STM32MP13_CLKS_H_ @@ -64,7 +64,7 @@ #define CK_MCO1 38 #define CK_MCO2 39 -/* IP clocks */ +/* IP clocks */ #define SYSCFG 40 #define VREF 41 #define DTS 42 diff --git a/include/dt-bindings/gpio/tegra234-gpio.h b/include/dt-bindings/gpio/tegra234-gpio.h index d7a1f2e298e8..784673c2c752 100644 --- a/include/dt-bindings/gpio/tegra234-gpio.h +++ b/include/dt-bindings/gpio/tegra234-gpio.h @@ -33,18 +33,14 @@ #define TEGRA234_MAIN_GPIO_PORT_P 14 #define TEGRA234_MAIN_GPIO_PORT_Q 15 #define TEGRA234_MAIN_GPIO_PORT_R 16 -#define TEGRA234_MAIN_GPIO_PORT_S 17 -#define TEGRA234_MAIN_GPIO_PORT_T 18 -#define TEGRA234_MAIN_GPIO_PORT_U 19 -#define TEGRA234_MAIN_GPIO_PORT_V 20 -#define TEGRA234_MAIN_GPIO_PORT_X 21 -#define TEGRA234_MAIN_GPIO_PORT_Y 22 -#define TEGRA234_MAIN_GPIO_PORT_Z 23 -#define TEGRA234_MAIN_GPIO_PORT_AC 24 -#define TEGRA234_MAIN_GPIO_PORT_AD 25 -#define TEGRA234_MAIN_GPIO_PORT_AE 26 -#define TEGRA234_MAIN_GPIO_PORT_AF 27 -#define TEGRA234_MAIN_GPIO_PORT_AG 28 +#define TEGRA234_MAIN_GPIO_PORT_X 17 +#define TEGRA234_MAIN_GPIO_PORT_Y 18 +#define TEGRA234_MAIN_GPIO_PORT_Z 19 +#define TEGRA234_MAIN_GPIO_PORT_AC 20 +#define TEGRA234_MAIN_GPIO_PORT_AD 21 +#define TEGRA234_MAIN_GPIO_PORT_AE 22 +#define TEGRA234_MAIN_GPIO_PORT_AF 23 +#define TEGRA234_MAIN_GPIO_PORT_AG 24 #define TEGRA234_MAIN_GPIO(port, offset) \ ((TEGRA234_MAIN_GPIO_PORT_##port * 8) + offset) diff --git a/include/dt-bindings/interconnect/qcom,msm8996-cbf.h b/include/dt-bindings/interconnect/qcom,msm8996-cbf.h new file mode 100644 index 000000000000..aac5e69f6bd5 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,msm8996-cbf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2023 Linaro Ltd. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8996_CBF_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8996_CBF_H + +#define MASTER_CBF_M4M 0 +#define SLAVE_CBF_M4M 1 + +#endif diff --git a/include/dt-bindings/leds/leds-lp55xx.h b/include/dt-bindings/leds/leds-lp55xx.h new file mode 100644 index 000000000000..a4fb4567715d --- /dev/null +++ b/include/dt-bindings/leds/leds-lp55xx.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +#ifndef _DT_BINDINGS_LEDS_LP55XX_H +#define _DT_BINDINGS_LEDS_LP55XX_H + +#define LP55XX_CP_OFF 0 +#define LP55XX_CP_BYPASS 1 +#define LP55XX_CP_BOOST 2 +#define LP55XX_CP_AUTO 3 + +#endif /* _DT_BINDINGS_LEDS_LP55XX_H */ diff --git a/include/dt-bindings/memory/tegra234-mc.h b/include/dt-bindings/memory/tegra234-mc.h index 347e55e89a2a..6e60d55491b3 100644 --- a/include/dt-bindings/memory/tegra234-mc.h +++ b/include/dt-bindings/memory/tegra234-mc.h @@ -536,4 +536,9 @@ #define TEGRA234_MEMORY_CLIENT_NVJPG1SRD 0x123 #define TEGRA234_MEMORY_CLIENT_NVJPG1SWR 0x124 +/* ICC ID's for dummy MC clients used to represent CPU Clusters */ +#define TEGRA_ICC_MC_CPU_CLUSTER0 1003 +#define TEGRA_ICC_MC_CPU_CLUSTER1 1004 +#define TEGRA_ICC_MC_CPU_CLUSTER2 1005 + #endif diff --git a/include/dt-bindings/mfd/stm32f7-rcc.h b/include/dt-bindings/mfd/stm32f7-rcc.h index a90f3613c584..8d73a9c51e2b 100644 --- a/include/dt-bindings/mfd/stm32f7-rcc.h +++ b/include/dt-bindings/mfd/stm32f7-rcc.h @@ -64,6 +64,7 @@ #define STM32F7_RCC_APB1_TIM14 8 #define STM32F7_RCC_APB1_LPTIM1 9 #define STM32F7_RCC_APB1_WWDG 11 +#define STM32F7_RCC_APB1_CAN3 13 #define STM32F7_RCC_APB1_SPI2 14 #define STM32F7_RCC_APB1_SPI3 15 #define STM32F7_RCC_APB1_SPDIFRX 16 diff --git a/include/dt-bindings/mux/ti-serdes.h b/include/dt-bindings/mux/ti-serdes.h index d3116c52ab72..669ca2d6abce 100644 --- a/include/dt-bindings/mux/ti-serdes.h +++ b/include/dt-bindings/mux/ti-serdes.h @@ -117,4 +117,66 @@ #define J721S2_SERDES0_LANE3_USB 0x2 #define J721S2_SERDES0_LANE3_IP4_UNUSED 0x3 +/* J784S4 */ + +#define J784S4_SERDES0_LANE0_IP1_UNUSED 0x0 +#define J784S4_SERDES0_LANE0_PCIE1_LANE0 0x1 +#define J784S4_SERDES0_LANE0_IP3_UNUSED 0x2 +#define J784S4_SERDES0_LANE0_IP4_UNUSED 0x3 + +#define J784S4_SERDES0_LANE1_IP1_UNUSED 0x0 +#define J784S4_SERDES0_LANE1_PCIE1_LANE1 0x1 +#define J784S4_SERDES0_LANE1_IP3_UNUSED 0x2 +#define J784S4_SERDES0_LANE1_IP4_UNUSED 0x3 + +#define J784S4_SERDES0_LANE2_PCIE3_LANE0 0x0 +#define J784S4_SERDES0_LANE2_PCIE1_LANE2 0x1 +#define J784S4_SERDES0_LANE2_IP3_UNUSED 0x2 +#define J784S4_SERDES0_LANE2_IP4_UNUSED 0x3 + +#define J784S4_SERDES0_LANE3_PCIE3_LANE1 0x0 +#define J784S4_SERDES0_LANE3_PCIE1_LANE3 0x1 +#define J784S4_SERDES0_LANE3_USB 0x2 +#define J784S4_SERDES0_LANE3_IP4_UNUSED 0x3 + +#define J784S4_SERDES1_LANE0_QSGMII_LANE3 0x0 +#define J784S4_SERDES1_LANE0_PCIE0_LANE0 0x1 +#define J784S4_SERDES1_LANE0_IP3_UNUSED 0x2 +#define J784S4_SERDES1_LANE0_IP4_UNUSED 0x3 + +#define J784S4_SERDES1_LANE1_QSGMII_LANE4 0x0 +#define J784S4_SERDES1_LANE1_PCIE0_LANE1 0x1 +#define J784S4_SERDES1_LANE1_IP3_UNUSED 0x2 +#define J784S4_SERDES1_LANE1_IP4_UNUSED 0x3 + +#define J784S4_SERDES1_LANE2_QSGMII_LANE1 0x0 +#define J784S4_SERDES1_LANE2_PCIE0_LANE2 0x1 +#define J784S4_SERDES1_LANE2_PCIE2_LANE0 0x2 +#define J784S4_SERDES1_LANE2_IP4_UNUSED 0x3 + +#define J784S4_SERDES1_LANE3_QSGMII_LANE2 0x0 +#define J784S4_SERDES1_LANE3_PCIE0_LANE3 0x1 +#define J784S4_SERDES1_LANE3_PCIE2_LANE1 0x2 +#define J784S4_SERDES1_LANE3_IP4_UNUSED 0x3 + +#define J784S4_SERDES2_LANE0_QSGMII_LANE5 0x0 +#define J784S4_SERDES2_LANE0_IP2_UNUSED 0x1 +#define J784S4_SERDES2_LANE0_IP3_UNUSED 0x2 +#define J784S4_SERDES2_LANE0_IP4_UNUSED 0x3 + +#define J784S4_SERDES2_LANE1_QSGMII_LANE6 0x0 +#define J784S4_SERDES2_LANE1_IP2_UNUSED 0x1 +#define J784S4_SERDES2_LANE1_IP3_UNUSED 0x2 +#define J784S4_SERDES2_LANE1_IP4_UNUSED 0x3 + +#define J784S4_SERDES2_LANE2_QSGMII_LANE7 0x0 +#define J784S4_SERDES2_LANE2_QSGMII_LANE1 0x1 +#define J784S4_SERDES2_LANE2_IP3_UNUSED 0x2 +#define J784S4_SERDES2_LANE2_IP4_UNUSED 0x3 + +#define J784S4_SERDES2_LANE3_QSGMII_LANE8 0x0 +#define J784S4_SERDES2_LANE3_QSGMII_LANE2 0x1 +#define J784S4_SERDES2_LANE3_IP3_UNUSED 0x2 +#define J784S4_SERDES2_LANE3_IP4_UNUSED 0x3 + #endif /* _DT_BINDINGS_MUX_TI_SERDES */ diff --git a/include/dt-bindings/pinctrl/k3.h b/include/dt-bindings/pinctrl/k3.h deleted file mode 100644 index b5aca149664e..000000000000 --- a/include/dt-bindings/pinctrl/k3.h +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This header provides constants for pinctrl bindings for TI's K3 SoC - * family. - * - * Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/ - */ -#ifndef _DT_BINDINGS_PINCTRL_TI_K3_H -#define _DT_BINDINGS_PINCTRL_TI_K3_H - -/* - * These bindings are deprecated, because they do not match the actual - * concept of bindings but rather contain pure register values. - * Instead include the header in the DTS source directory. - */ -#warning "These bindings are deprecated. Instead, use the header in the DTS source directory." - -#define PULLUDEN_SHIFT (16) -#define PULLTYPESEL_SHIFT (17) -#define RXACTIVE_SHIFT (18) - -#define PULL_DISABLE (1 << PULLUDEN_SHIFT) -#define PULL_ENABLE (0 << PULLUDEN_SHIFT) - -#define PULL_UP (1 << PULLTYPESEL_SHIFT | PULL_ENABLE) -#define PULL_DOWN (0 << PULLTYPESEL_SHIFT | PULL_ENABLE) - -#define INPUT_EN (1 << RXACTIVE_SHIFT) -#define INPUT_DISABLE (0 << RXACTIVE_SHIFT) - -/* Only these macros are expected be used directly in device tree files */ -#define PIN_OUTPUT (INPUT_DISABLE | PULL_DISABLE) -#define PIN_OUTPUT_PULLUP (INPUT_DISABLE | PULL_UP) -#define PIN_OUTPUT_PULLDOWN (INPUT_DISABLE | PULL_DOWN) -#define PIN_INPUT (INPUT_EN | PULL_DISABLE) -#define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) -#define PIN_INPUT_PULLDOWN (INPUT_EN | PULL_DOWN) - -#define AM62AX_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define AM62AX_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define AM62X_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define AM62X_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define AM64X_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define AM64X_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define AM65X_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define AM65X_WKUP_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define J721E_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define J721E_WKUP_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define J721S2_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define J721S2_WKUP_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#define J784S4_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) -#define J784S4_WKUP_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode)) - -#endif diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h index e6fb8ada3f4d..28ad0235086a 100644 --- a/include/dt-bindings/pinctrl/stm32-pinfunc.h +++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h @@ -37,6 +37,9 @@ #define STM32MP_PKG_AB 0x2 #define STM32MP_PKG_AC 0x4 #define STM32MP_PKG_AD 0x8 +#define STM32MP_PKG_AI 0x100 +#define STM32MP_PKG_AK 0x400 +#define STM32MP_PKG_AL 0x800 #endif /* _DT_BINDINGS_STM32_PINFUNC_H */ diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index 1bf8e87ecd7e..83be996cb5eb 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -90,6 +90,15 @@ #define SM8150_MMCX 9 #define SM8150_MMCX_AO 10 +/* SA8155P is a special case, kept for backwards compatibility */ +#define SA8155P_CX SM8150_CX +#define SA8155P_CX_AO SM8150_CX_AO +#define SA8155P_EBI SM8150_EBI +#define SA8155P_GFX SM8150_GFX +#define SA8155P_MSS SM8150_MSS +#define SA8155P_MX SM8150_MX +#define SA8155P_MX_AO SM8150_MX_AO + /* SM8250 Power Domain Indexes */ #define SM8250_CX 0 #define SM8250_CX_AO 1 @@ -207,20 +216,30 @@ #define SC8280XP_XO 15 /* SDM845 Power Domain performance levels */ -#define RPMH_REGULATOR_LEVEL_RETENTION 16 -#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 -#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 -#define RPMH_REGULATOR_LEVEL_SVS 128 -#define RPMH_REGULATOR_LEVEL_SVS_L0 144 -#define RPMH_REGULATOR_LEVEL_SVS_L1 192 -#define RPMH_REGULATOR_LEVEL_SVS_L2 224 -#define RPMH_REGULATOR_LEVEL_NOM 256 -#define RPMH_REGULATOR_LEVEL_NOM_L1 320 -#define RPMH_REGULATOR_LEVEL_NOM_L2 336 -#define RPMH_REGULATOR_LEVEL_TURBO 384 -#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +#define RPMH_REGULATOR_LEVEL_RETENTION 16 +#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 +#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96 +#define RPMH_REGULATOR_LEVEL_SVS 128 +#define RPMH_REGULATOR_LEVEL_SVS_L0 144 +#define RPMH_REGULATOR_LEVEL_SVS_L1 192 +#define RPMH_REGULATOR_LEVEL_SVS_L2 224 +#define RPMH_REGULATOR_LEVEL_NOM 256 +#define RPMH_REGULATOR_LEVEL_NOM_L0 288 +#define RPMH_REGULATOR_LEVEL_NOM_L1 320 +#define RPMH_REGULATOR_LEVEL_NOM_L2 336 +#define RPMH_REGULATOR_LEVEL_TURBO 384 +#define RPMH_REGULATOR_LEVEL_TURBO_L0 400 +#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +#define RPMH_REGULATOR_LEVEL_TURBO_L2 432 +#define RPMH_REGULATOR_LEVEL_TURBO_L3 448 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 /* MDM9607 Power Domains */ #define MDM9607_VDDCX 0 diff --git a/include/dt-bindings/reset/mt8188-resets.h b/include/dt-bindings/reset/mt8188-resets.h index 377cdfda82a9..ba9a5e9b8899 100644 --- a/include/dt-bindings/reset/mt8188-resets.h +++ b/include/dt-bindings/reset/mt8188-resets.h @@ -33,4 +33,9 @@ #define MT8188_TOPRGU_SW_RST_NUM 24 +/* INFRA resets */ +#define MT8188_INFRA_RST1_THERMAL_MCU_RST 0 +#define MT8188_INFRA_RST1_THERMAL_CTRL_RST 1 +#define MT8188_INFRA_RST3_PTP_CTRL_RST 2 + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8188 */ diff --git a/include/dt-bindings/reset/nuvoton,ma35d1-reset.h b/include/dt-bindings/reset/nuvoton,ma35d1-reset.h new file mode 100644 index 000000000000..2e99ee0d68c5 --- /dev/null +++ b/include/dt-bindings/reset/nuvoton,ma35d1-reset.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2023 Nuvoton Technologies. + * Author: Chi-Fen Li <cfli0@nuvoton.com> + * + * Device Tree binding constants for MA35D1 reset controller. + */ + +#ifndef __DT_BINDINGS_RESET_MA35D1_H +#define __DT_BINDINGS_RESET_MA35D1_H + +#define MA35D1_RESET_CHIP 0 +#define MA35D1_RESET_CA35CR0 1 +#define MA35D1_RESET_CA35CR1 2 +#define MA35D1_RESET_CM4 3 +#define MA35D1_RESET_PDMA0 4 +#define MA35D1_RESET_PDMA1 5 +#define MA35D1_RESET_PDMA2 6 +#define MA35D1_RESET_PDMA3 7 +#define MA35D1_RESET_DISP 8 +#define MA35D1_RESET_VCAP0 9 +#define MA35D1_RESET_VCAP1 10 +#define MA35D1_RESET_GFX 11 +#define MA35D1_RESET_VDEC 12 +#define MA35D1_RESET_WHC0 13 +#define MA35D1_RESET_WHC1 14 +#define MA35D1_RESET_GMAC0 15 +#define MA35D1_RESET_GMAC1 16 +#define MA35D1_RESET_HWSEM 17 +#define MA35D1_RESET_EBI 18 +#define MA35D1_RESET_HSUSBH0 19 +#define MA35D1_RESET_HSUSBH1 20 +#define MA35D1_RESET_HSUSBD 21 +#define MA35D1_RESET_USBHL 22 +#define MA35D1_RESET_SDH0 23 +#define MA35D1_RESET_SDH1 24 +#define MA35D1_RESET_NAND 25 +#define MA35D1_RESET_GPIO 26 +#define MA35D1_RESET_MCTLP 27 +#define MA35D1_RESET_MCTLC 28 +#define MA35D1_RESET_DDRPUB 29 +#define MA35D1_RESET_TMR0 30 +#define MA35D1_RESET_TMR1 31 +#define MA35D1_RESET_TMR2 32 +#define MA35D1_RESET_TMR3 33 +#define MA35D1_RESET_I2C0 34 +#define MA35D1_RESET_I2C1 35 +#define MA35D1_RESET_I2C2 36 +#define MA35D1_RESET_I2C3 37 +#define MA35D1_RESET_QSPI0 38 +#define MA35D1_RESET_SPI0 39 +#define MA35D1_RESET_SPI1 40 +#define MA35D1_RESET_SPI2 41 +#define MA35D1_RESET_UART0 42 +#define MA35D1_RESET_UART1 43 +#define MA35D1_RESET_UART2 44 +#define MA35D1_RESET_UART3 45 +#define MA35D1_RESET_UART4 46 +#define MA35D1_RESET_UART5 47 +#define MA35D1_RESET_UART6 48 +#define MA35D1_RESET_UART7 49 +#define MA35D1_RESET_CANFD0 50 +#define MA35D1_RESET_CANFD1 51 +#define MA35D1_RESET_EADC0 52 +#define MA35D1_RESET_I2S0 53 +#define MA35D1_RESET_SC0 54 +#define MA35D1_RESET_SC1 55 +#define MA35D1_RESET_QSPI1 56 +#define MA35D1_RESET_SPI3 57 +#define MA35D1_RESET_EPWM0 58 +#define MA35D1_RESET_EPWM1 59 +#define MA35D1_RESET_QEI0 60 +#define MA35D1_RESET_QEI1 61 +#define MA35D1_RESET_ECAP0 62 +#define MA35D1_RESET_ECAP1 63 +#define MA35D1_RESET_CANFD2 64 +#define MA35D1_RESET_ADC0 65 +#define MA35D1_RESET_TMR4 66 +#define MA35D1_RESET_TMR5 67 +#define MA35D1_RESET_TMR6 68 +#define MA35D1_RESET_TMR7 69 +#define MA35D1_RESET_TMR8 70 +#define MA35D1_RESET_TMR9 71 +#define MA35D1_RESET_TMR10 72 +#define MA35D1_RESET_TMR11 73 +#define MA35D1_RESET_UART8 74 +#define MA35D1_RESET_UART9 75 +#define MA35D1_RESET_UART10 76 +#define MA35D1_RESET_UART11 77 +#define MA35D1_RESET_UART12 78 +#define MA35D1_RESET_UART13 79 +#define MA35D1_RESET_UART14 80 +#define MA35D1_RESET_UART15 81 +#define MA35D1_RESET_UART16 82 +#define MA35D1_RESET_I2S1 83 +#define MA35D1_RESET_I2C4 84 +#define MA35D1_RESET_I2C5 85 +#define MA35D1_RESET_EPWM2 86 +#define MA35D1_RESET_ECAP2 87 +#define MA35D1_RESET_QEI2 88 +#define MA35D1_RESET_CANFD3 89 +#define MA35D1_RESET_KPI 90 +#define MA35D1_RESET_GIC 91 +#define MA35D1_RESET_SSMCC 92 +#define MA35D1_RESET_SSPCC 93 +#define MA35D1_RESET_COUNT 94 + +#endif diff --git a/include/dt-bindings/reset/qcom,ipq9574-gcc.h b/include/dt-bindings/reset/qcom,ipq9574-gcc.h index d01dc6a24cf1..c709d103673d 100644 --- a/include/dt-bindings/reset/qcom,ipq9574-gcc.h +++ b/include/dt-bindings/reset/qcom,ipq9574-gcc.h @@ -160,5 +160,6 @@ #define GCC_WCSS_Q6_BCR 151 #define GCC_WCSS_Q6_TBU_BCR 152 #define GCC_TCSR_BCR 153 +#define GCC_CRYPTO_BCR 154 #endif diff --git a/include/dt-bindings/reset/qcom,sm8350-videocc.h b/include/dt-bindings/reset/qcom,sm8350-videocc.h new file mode 100644 index 000000000000..cd356b207a4a --- /dev/null +++ b/include/dt-bindings/reset/qcom,sm8350-videocc.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DT_BINDINGS_RESET_QCOM_VIDEO_CC_SM8350_H +#define _DT_BINDINGS_RESET_QCOM_VIDEO_CC_SM8350_H + +#define VIDEO_CC_CVP_INTERFACE_BCR 0 +#define VIDEO_CC_CVP_MVS0_BCR 1 +#define VIDEO_CC_MVS0C_CLK_ARES 2 +#define VIDEO_CC_CVP_MVS0C_BCR 3 +#define VIDEO_CC_CVP_MVS1_BCR 4 +#define VIDEO_CC_MVS1C_CLK_ARES 5 +#define VIDEO_CC_CVP_MVS1C_BCR 6 + +#endif diff --git a/include/dt-bindings/reset/qcom,sm8450-gpucc.h b/include/dt-bindings/reset/qcom,sm8450-gpucc.h new file mode 100644 index 000000000000..58ba8f987107 --- /dev/null +++ b/include/dt-bindings/reset/qcom,sm8450-gpucc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DT_BINDINGS_RESET_QCOM_GPU_CC_SM8450_H +#define _DT_BINDINGS_RESET_QCOM_GPU_CC_SM8450_H + +#define GPUCC_GPU_CC_ACD_BCR 0 +#define GPUCC_GPU_CC_CX_BCR 1 +#define GPUCC_GPU_CC_FAST_HUB_BCR 2 +#define GPUCC_GPU_CC_FF_BCR 3 +#define GPUCC_GPU_CC_GFX3D_AON_BCR 4 +#define GPUCC_GPU_CC_GMU_BCR 5 +#define GPUCC_GPU_CC_GX_BCR 6 +#define GPUCC_GPU_CC_XO_BCR 7 +#define GPUCC_GPU_CC_GX_ACD_IROOT_BCR 8 + +#endif diff --git a/include/dt-bindings/reset/stm32mp13-resets.h b/include/dt-bindings/reset/stm32mp13-resets.h index 934864e90da6..ecb37c7ddde1 100644 --- a/include/dt-bindings/reset/stm32mp13-resets.h +++ b/include/dt-bindings/reset/stm32mp13-resets.h @@ -1,7 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ /* * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics. + * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. */ #ifndef _DT_BINDINGS_STM32MP13_RESET_H_ diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h index 9f7c5103bc82..39f203256c4f 100644 --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h @@ -131,6 +131,14 @@ #define RX_CODEC_DMA_RX_7 126 #define QUINARY_MI2S_RX 127 #define QUINARY_MI2S_TX 128 +#define DISPLAY_PORT_RX_0 DISPLAY_PORT_RX +#define DISPLAY_PORT_RX_1 129 +#define DISPLAY_PORT_RX_2 130 +#define DISPLAY_PORT_RX_3 131 +#define DISPLAY_PORT_RX_4 132 +#define DISPLAY_PORT_RX_5 133 +#define DISPLAY_PORT_RX_6 134 +#define DISPLAY_PORT_RX_7 135 #define LPASS_CLK_ID_PRI_MI2S_IBIT 1 #define LPASS_CLK_ID_PRI_MI2S_EBIT 2 diff --git a/include/dt-bindings/thermal/tegra234-bpmp-thermal.h b/include/dt-bindings/thermal/tegra234-bpmp-thermal.h new file mode 100644 index 000000000000..934787950932 --- /dev/null +++ b/include/dt-bindings/thermal/tegra234-bpmp-thermal.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides constants for binding nvidia,tegra234-bpmp-thermal. + */ + +#ifndef _DT_BINDINGS_THERMAL_TEGRA234_BPMP_THERMAL_H +#define _DT_BINDINGS_THERMAL_TEGRA234_BPMP_THERMAL_H + +#define TEGRA234_BPMP_THERMAL_ZONE_CPU 0 +#define TEGRA234_BPMP_THERMAL_ZONE_GPU 1 +#define TEGRA234_BPMP_THERMAL_ZONE_CV0 2 +#define TEGRA234_BPMP_THERMAL_ZONE_CV1 3 +#define TEGRA234_BPMP_THERMAL_ZONE_CV2 4 +#define TEGRA234_BPMP_THERMAL_ZONE_SOC0 5 +#define TEGRA234_BPMP_THERMAL_ZONE_SOC1 6 +#define TEGRA234_BPMP_THERMAL_ZONE_SOC2 7 +#define TEGRA234_BPMP_THERMAL_ZONE_TJ_MAX 8 + +#endif diff --git a/include/keys/asymmetric-parser.h b/include/keys/asymmetric-parser.h index c47dc5405f79..516a3f51179e 100644 --- a/include/keys/asymmetric-parser.h +++ b/include/keys/asymmetric-parser.h @@ -10,6 +10,8 @@ #ifndef _KEYS_ASYMMETRIC_PARSER_H #define _KEYS_ASYMMETRIC_PARSER_H +struct key_preparsed_payload; + /* * Key data parser. Called during key instantiation. */ diff --git a/include/kunit/resource.h b/include/kunit/resource.h index c0d88b318e90..c7383e90f5c9 100644 --- a/include/kunit/resource.h +++ b/include/kunit/resource.h @@ -387,4 +387,96 @@ static inline int kunit_destroy_named_resource(struct kunit *test, */ void kunit_remove_resource(struct kunit *test, struct kunit_resource *res); +/* A 'deferred action' function to be used with kunit_add_action. */ +typedef void (kunit_action_t)(void *); + +/** + * kunit_add_action() - Call a function when the test ends. + * @test: Test case to associate the action with. + * @action: The function to run on test exit + * @ctx: Data passed into @func + * + * Defer the execution of a function until the test exits, either normally or + * due to a failure. @ctx is passed as additional context. All functions + * registered with kunit_add_action() will execute in the opposite order to that + * they were registered in. + * + * This is useful for cleaning up allocated memory and resources, as these + * functions are called even if the test aborts early due to, e.g., a failed + * assertion. + * + * See also: devm_add_action() for the devres equivalent. + * + * Returns: + * 0 on success, an error if the action could not be deferred. + */ +int kunit_add_action(struct kunit *test, kunit_action_t *action, void *ctx); + +/** + * kunit_add_action_or_reset() - Call a function when the test ends. + * @test: Test case to associate the action with. + * @action: The function to run on test exit + * @ctx: Data passed into @func + * + * Defer the execution of a function until the test exits, either normally or + * due to a failure. @ctx is passed as additional context. All functions + * registered with kunit_add_action() will execute in the opposite order to that + * they were registered in. + * + * This is useful for cleaning up allocated memory and resources, as these + * functions are called even if the test aborts early due to, e.g., a failed + * assertion. + * + * If the action cannot be created (e.g., due to the system being out of memory), + * then action(ctx) will be called immediately, and an error will be returned. + * + * See also: devm_add_action_or_reset() for the devres equivalent. + * + * Returns: + * 0 on success, an error if the action could not be deferred. + */ +int kunit_add_action_or_reset(struct kunit *test, kunit_action_t *action, + void *ctx); + +/** + * kunit_remove_action() - Cancel a matching deferred action. + * @test: Test case the action is associated with. + * @action: The deferred function to cancel. + * @ctx: The context passed to the deferred function to trigger. + * + * Prevent an action deferred via kunit_add_action() from executing when the + * test terminates. + * + * If the function/context pair was deferred multiple times, only the most + * recent one will be cancelled. + * + * See also: devm_remove_action() for the devres equivalent. + */ +void kunit_remove_action(struct kunit *test, + kunit_action_t *action, + void *ctx); + +/** + * kunit_release_action() - Run a matching action call immediately. + * @test: Test case the action is associated with. + * @action: The deferred function to trigger. + * @ctx: The context passed to the deferred function to trigger. + * + * Execute a function deferred via kunit_add_action()) immediately, rather than + * when the test ends. + * + * If the function/context pair was deferred multiple times, it will only be + * executed once here. The most recent deferral will no longer execute when + * the test ends. + * + * kunit_release_action(test, func, ctx); + * is equivalent to + * func(ctx); + * kunit_remove_action(test, func, ctx); + * + * See also: devm_release_action() for the devres equivalent. + */ +void kunit_release_action(struct kunit *test, + kunit_action_t *action, + void *ctx); #endif /* _KUNIT_RESOURCE_H */ diff --git a/include/kunit/test.h b/include/kunit/test.h index 57b309c6ca27..23120d50499e 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -47,6 +47,7 @@ struct kunit; * sub-subtest. See the "Subtests" section in * https://node-tap.org/tap-protocol/ */ +#define KUNIT_INDENT_LEN 4 #define KUNIT_SUBTEST_INDENT " " #define KUNIT_SUBSUBTEST_INDENT " " @@ -168,6 +169,9 @@ static inline char *kunit_status_to_ok_not_ok(enum kunit_status status) * test case, similar to the notion of a *test fixture* or a *test class* * in other unit testing frameworks like JUnit or Googletest. * + * Note that @exit and @suite_exit will run even if @init or @suite_init + * fail: make sure they can handle any inconsistent state which may result. + * * Every &struct kunit_case must be associated with a kunit_suite for KUnit * to run it. */ @@ -321,8 +325,11 @@ enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite); * @gfp: flags passed to underlying kmalloc(). * * Just like `kmalloc_array(...)`, except the allocation is managed by the test case - * and is automatically cleaned up after the test case concludes. See &struct - * kunit_resource for more information. + * and is automatically cleaned up after the test case concludes. See kunit_add_action() + * for more information. + * + * Note that some internal context data is also allocated with GFP_KERNEL, + * regardless of the gfp passed in. */ void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp); @@ -333,6 +340,9 @@ void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp); * @gfp: flags passed to underlying kmalloc(). * * See kmalloc() and kunit_kmalloc_array() for more information. + * + * Note that some internal context data is also allocated with GFP_KERNEL, + * regardless of the gfp passed in. */ static inline void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp) { @@ -472,7 +482,9 @@ void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...); */ #define KUNIT_SUCCEED(test) do {} while (0) -void kunit_do_failed_assertion(struct kunit *test, +void __noreturn __kunit_abort(struct kunit *test); + +void __kunit_do_failed_assertion(struct kunit *test, const struct kunit_loc *loc, enum kunit_assert_type type, const struct kunit_assert *assert, @@ -482,13 +494,15 @@ void kunit_do_failed_assertion(struct kunit *test, #define _KUNIT_FAILED(test, assert_type, assert_class, assert_format, INITIALIZER, fmt, ...) do { \ static const struct kunit_loc __loc = KUNIT_CURRENT_LOC; \ const struct assert_class __assertion = INITIALIZER; \ - kunit_do_failed_assertion(test, \ - &__loc, \ - assert_type, \ - &__assertion.assert, \ - assert_format, \ - fmt, \ - ##__VA_ARGS__); \ + __kunit_do_failed_assertion(test, \ + &__loc, \ + assert_type, \ + &__assertion.assert, \ + assert_format, \ + fmt, \ + ##__VA_ARGS__); \ + if (assert_type == KUNIT_ASSERTION) \ + __kunit_abort(test); \ } while (0) diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h index 1a6a695ca67a..847da6fc2713 100644 --- a/include/kvm/arm_pmu.h +++ b/include/kvm/arm_pmu.h @@ -92,8 +92,12 @@ void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu); /* * Evaluates as true when emulating PMUv3p5, and false otherwise. */ -#define kvm_pmu_is_3p5(vcpu) \ - (vcpu->kvm->arch.dfr0_pmuver.imp >= ID_AA64DFR0_EL1_PMUVer_V3P5) +#define kvm_pmu_is_3p5(vcpu) ({ \ + u64 val = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1); \ + u8 pmuver = SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val); \ + \ + pmuver >= ID_AA64DFR0_EL1_PMUVer_V3P5; \ +}) u8 kvm_arm_pmu_get_pmuver_limit(void); diff --git a/include/kvm/iodev.h b/include/kvm/iodev.h index d75fc4365746..56619e33251e 100644 --- a/include/kvm/iodev.h +++ b/include/kvm/iodev.h @@ -55,10 +55,4 @@ static inline int kvm_iodevice_write(struct kvm_vcpu *vcpu, : -EOPNOTSUPP; } -static inline void kvm_iodevice_destructor(struct kvm_io_device *dev) -{ - if (dev->ops->destructor) - dev->ops->destructor(dev); -} - #endif /* __KVM_IODEV_H__ */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 7b71dd74baeb..640f1c07c894 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -70,19 +70,6 @@ static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) kfree(fwnode); } -/** - * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with - * the PCI-defined class-code information - * - * @_cls : the class, subclass, prog-if triple for this device - * @_msk : the class mask for this device - * - * This macro is used to create a struct acpi_device_id that matches a - * specific PCI class. The .id and .driver_data fields will be left - * initialized with the default value. - */ -#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk), - static inline bool has_acpi_companion(struct device *dev) { return is_acpi_device_node(dev->fwnode); @@ -414,6 +401,8 @@ extern bool acpi_is_pnp_device(struct acpi_device *); typedef void (*wmi_notify_handler) (u32 value, void *context); +int wmi_instance_count(const char *guid); + extern acpi_status wmi_evaluate_method(const char *guid, u8 instance, u32 method_id, const struct acpi_buffer *in, @@ -712,7 +701,6 @@ int acpi_match_platform_list(const struct acpi_platform_list *plat); extern void acpi_early_init(void); extern void acpi_subsystem_init(void); -extern void arch_post_acpi_subsys_init(void); extern int acpi_nvs_register(__u64 start, __u64 size); @@ -781,7 +769,6 @@ const char *acpi_get_subsystem_id(acpi_handle handle); #define ACPI_COMPANION_SET(dev, adev) do { } while (0) #define ACPI_HANDLE(dev) (NULL) #define ACPI_HANDLE_FWNODE(fwnode) (NULL) -#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (0), .cls_msk = (0), #include <acpi/acpi_numa.h> @@ -1084,6 +1071,8 @@ static inline bool acpi_sleep_state_supported(u8 sleep_state) #endif /* !CONFIG_ACPI */ +extern void arch_post_acpi_subsys_init(void); + #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC int acpi_ioapic_add(acpi_handle root); #else @@ -1507,6 +1496,12 @@ static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu) } #endif +#ifdef CONFIG_ARM64 +void acpi_arm_init(void); +#else +static inline void acpi_arm_init(void) { } +#endif + #ifdef CONFIG_ACPI_PCC void acpi_init_pcc(void); #else diff --git a/include/linux/acpi_agdi.h b/include/linux/acpi_agdi.h deleted file mode 100644 index f477f0b452fa..000000000000 --- a/include/linux/acpi_agdi.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __ACPI_AGDI_H__ -#define __ACPI_AGDI_H__ - -#include <linux/acpi.h> - -#ifdef CONFIG_ACPI_AGDI -void __init acpi_agdi_init(void); -#else -static inline void acpi_agdi_init(void) {} -#endif -#endif /* __ACPI_AGDI_H__ */ diff --git a/include/linux/acpi_apmt.h b/include/linux/acpi_apmt.h deleted file mode 100644 index 40bd634d082f..000000000000 --- a/include/linux/acpi_apmt.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * ARM CoreSight PMU driver. - * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. - * - */ - -#ifndef __ACPI_APMT_H__ -#define __ACPI_APMT_H__ - -#include <linux/acpi.h> - -#ifdef CONFIG_ACPI_APMT -void acpi_apmt_init(void); -#else -static inline void acpi_apmt_init(void) { } -#endif /* CONFIG_ACPI_APMT */ - -#endif /* __ACPI_APMT_H__ */ diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index b43be0987b19..ee7cb6aaff71 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -26,13 +26,13 @@ int iort_register_domain_token(int trans_id, phys_addr_t base, struct fwnode_handle *fw_node); void iort_deregister_domain_token(int trans_id); struct fwnode_handle *iort_find_domain_token(int trans_id); +int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); + #ifdef CONFIG_ACPI_IORT -void acpi_iort_init(void); u32 iort_msi_map_id(struct device *dev, u32 id); struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, enum irq_domain_bus_token bus_token); void acpi_configure_pmsi_domain(struct device *dev); -int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head); void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, @@ -43,7 +43,6 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in); void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head); phys_addr_t acpi_iort_dma_get_max_cpu_address(void); #else -static inline void acpi_iort_init(void) { } static inline u32 iort_msi_map_id(struct device *dev, u32 id) { return id; } static inline struct irq_domain *iort_get_device_domain( diff --git a/include/linux/aer.h b/include/linux/aer.h index 97f64ba1b34a..3a3ab05e13fd 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -45,8 +45,6 @@ struct aer_capability_regs { int pci_enable_pcie_error_reporting(struct pci_dev *dev); int pci_disable_pcie_error_reporting(struct pci_dev *dev); int pci_aer_clear_nonfatal_status(struct pci_dev *dev); -void pci_save_aer_state(struct pci_dev *dev); -void pci_restore_aer_state(struct pci_dev *dev); #else static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev) { @@ -60,8 +58,6 @@ static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev) { return -EINVAL; } -static inline void pci_save_aer_state(struct pci_dev *dev) {} -static inline void pci_restore_aer_state(struct pci_dev *dev) {} #endif void cper_print_aer(struct pci_dev *dev, int aer_severity, diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 5001e14c5c06..c60a6a14638c 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -107,7 +107,7 @@ enum amba_vendor { extern struct bus_type amba_bustype; -#define to_amba_device(d) container_of(d, struct amba_device, dev) +#define to_amba_device(d) container_of_const(d, struct amba_device, dev) #define amba_get_drvdata(d) dev_get_drvdata(&d->dev) #define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p) diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h index c10ebf8c42e6..446394f84606 100644 --- a/include/linux/amd-pstate.h +++ b/include/linux/amd-pstate.h @@ -94,7 +94,8 @@ struct amd_cpudata { * enum amd_pstate_mode - driver working mode of amd pstate */ enum amd_pstate_mode { - AMD_PSTATE_DISABLE = 0, + AMD_PSTATE_UNDEFINED = 0, + AMD_PSTATE_DISABLE, AMD_PSTATE_PASSIVE, AMD_PSTATE_ACTIVE, AMD_PSTATE_GUIDED, @@ -102,6 +103,7 @@ enum amd_pstate_mode { }; static const char * const amd_pstate_mode_string[] = { + [AMD_PSTATE_UNDEFINED] = "undefined", [AMD_PSTATE_DISABLE] = "disable", [AMD_PSTATE_PASSIVE] = "passive", [AMD_PSTATE_ACTIVE] = "active", diff --git a/include/linux/aperture.h b/include/linux/aperture.h index 442f15a57cad..1a9a88b11584 100644 --- a/include/linux/aperture.h +++ b/include/linux/aperture.h @@ -14,7 +14,9 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, resource_size_t size); int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name); + const char *name); + +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev); int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name); #else @@ -26,7 +28,12 @@ static inline int devm_aperture_acquire_for_platform_device(struct platform_devi } static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) +{ + return 0; +} + +static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) { return 0; } @@ -39,7 +46,6 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, /** * aperture_remove_all_conflicting_devices - remove all existing framebuffers - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes all graphics device drivers. Use this function on systems @@ -48,9 +54,9 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, * Returns: * 0 on success, or a negative errno code otherwise */ -static inline int aperture_remove_all_conflicting_devices(bool primary, const char *name) +static inline int aperture_remove_all_conflicting_devices(const char *name) { - return aperture_remove_conflicting_devices(0, (resource_size_t)-1, primary, name); + return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name); } #endif diff --git a/include/linux/arm-cci.h b/include/linux/arm-cci.h index d0e44201d855..7f7a576267bc 100644 --- a/include/linux/arm-cci.h +++ b/include/linux/arm-cci.h @@ -43,6 +43,8 @@ static inline int __cci_control_port_by_index(u32 port, bool enable) } #endif +void cci_enable_port_for_self(void); + #define cci_disable_port_by_device(dev) \ __cci_control_port_by_device(dev, false) #define cci_enable_port_by_device(dev) \ diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index c87aeecaa9b2..cc060da51bec 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -94,8 +94,17 @@ */ #define FFA_PAGE_SIZE SZ_4K +/* + * Minimum buffer size/alignment encodings returned by an FFA_FEATURES + * query for FFA_RXTX_MAP. + */ +#define FFA_FEAT_RXTX_MIN_SZ_4K 0 +#define FFA_FEAT_RXTX_MIN_SZ_64K 1 +#define FFA_FEAT_RXTX_MIN_SZ_16K 2 + /* FFA Bus/Device/Driver related */ struct ffa_device { + u32 id; int vm_id; bool mode_32bit; uuid_t uuid; diff --git a/include/linux/ata.h b/include/linux/ata.h index c224dbddb9b2..792e10a09787 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -322,15 +322,21 @@ enum { ATA_LOG_SATA_NCQ = 0x10, ATA_LOG_NCQ_NON_DATA = 0x12, ATA_LOG_NCQ_SEND_RECV = 0x13, + ATA_LOG_CDL = 0x18, + ATA_LOG_CDL_SIZE = ATA_SECT_SIZE, ATA_LOG_IDENTIFY_DEVICE = 0x30, + ATA_LOG_SENSE_NCQ = 0x0F, + ATA_LOG_SENSE_NCQ_SIZE = ATA_SECT_SIZE * 2, ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47, /* Identify device log pages: */ + ATA_LOG_SUPPORTED_CAPABILITIES = 0x03, + ATA_LOG_CURRENT_SETTINGS = 0x04, ATA_LOG_SECURITY = 0x06, ATA_LOG_SATA_SETTINGS = 0x08, ATA_LOG_ZONED_INFORMATION = 0x09, - /* Identify device SATA settings log:*/ + /* Identify device SATA settings log: */ ATA_LOG_DEVSLP_OFFSET = 0x30, ATA_LOG_DEVSLP_SIZE = 0x08, ATA_LOG_DEVSLP_MDAT = 0x00, @@ -415,6 +421,8 @@ enum { SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */ SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */ + SETFEATURES_CDL = 0x0d, /* Enable/disable cmd duration limits */ + /* SETFEATURE Sector counts for SATA features */ SATA_FPDMA_OFFSET = 0x01, /* FPDMA non-zero buffer offsets */ SATA_FPDMA_AA = 0x02, /* FPDMA Setup FIS Auto-Activate */ @@ -425,6 +433,7 @@ enum { SATA_DEVSLP = 0x09, /* Device Sleep */ SETFEATURE_SENSE_DATA = 0xC3, /* Sense Data Reporting feature */ + SETFEATURE_SENSE_DATA_SUCC_NCQ = 0xC4, /* Sense Data for successful NCQ commands */ /* feature values for SET_MAX */ ATA_SET_MAX_ADDR = 0x00, diff --git a/include/linux/atomic/atomic-arch-fallback.h b/include/linux/atomic/atomic-arch-fallback.h index a6e4437c5f36..18f5744dfb5d 100644 --- a/include/linux/atomic/atomic-arch-fallback.h +++ b/include/linux/atomic/atomic-arch-fallback.h @@ -8,2664 +8,4653 @@ #include <linux/compiler.h> -#ifndef arch_xchg_relaxed -#define arch_xchg_acquire arch_xchg -#define arch_xchg_release arch_xchg -#define arch_xchg_relaxed arch_xchg -#else /* arch_xchg_relaxed */ - -#ifndef arch_xchg_acquire -#define arch_xchg_acquire(...) \ - __atomic_op_acquire(arch_xchg, __VA_ARGS__) +#if defined(arch_xchg) +#define raw_xchg arch_xchg +#elif defined(arch_xchg_relaxed) +#define raw_xchg(...) \ + __atomic_op_fence(arch_xchg, __VA_ARGS__) +#else +extern void raw_xchg_not_implemented(void); +#define raw_xchg(...) raw_xchg_not_implemented() #endif -#ifndef arch_xchg_release -#define arch_xchg_release(...) \ - __atomic_op_release(arch_xchg, __VA_ARGS__) +#if defined(arch_xchg_acquire) +#define raw_xchg_acquire arch_xchg_acquire +#elif defined(arch_xchg_relaxed) +#define raw_xchg_acquire(...) \ + __atomic_op_acquire(arch_xchg, __VA_ARGS__) +#elif defined(arch_xchg) +#define raw_xchg_acquire arch_xchg +#else +extern void raw_xchg_acquire_not_implemented(void); +#define raw_xchg_acquire(...) raw_xchg_acquire_not_implemented() #endif -#ifndef arch_xchg -#define arch_xchg(...) \ - __atomic_op_fence(arch_xchg, __VA_ARGS__) +#if defined(arch_xchg_release) +#define raw_xchg_release arch_xchg_release +#elif defined(arch_xchg_relaxed) +#define raw_xchg_release(...) \ + __atomic_op_release(arch_xchg, __VA_ARGS__) +#elif defined(arch_xchg) +#define raw_xchg_release arch_xchg +#else +extern void raw_xchg_release_not_implemented(void); +#define raw_xchg_release(...) raw_xchg_release_not_implemented() +#endif + +#if defined(arch_xchg_relaxed) +#define raw_xchg_relaxed arch_xchg_relaxed +#elif defined(arch_xchg) +#define raw_xchg_relaxed arch_xchg +#else +extern void raw_xchg_relaxed_not_implemented(void); +#define raw_xchg_relaxed(...) raw_xchg_relaxed_not_implemented() +#endif + +#if defined(arch_cmpxchg) +#define raw_cmpxchg arch_cmpxchg +#elif defined(arch_cmpxchg_relaxed) +#define raw_cmpxchg(...) \ + __atomic_op_fence(arch_cmpxchg, __VA_ARGS__) +#else +extern void raw_cmpxchg_not_implemented(void); +#define raw_cmpxchg(...) raw_cmpxchg_not_implemented() #endif -#endif /* arch_xchg_relaxed */ - -#ifndef arch_cmpxchg_relaxed -#define arch_cmpxchg_acquire arch_cmpxchg -#define arch_cmpxchg_release arch_cmpxchg -#define arch_cmpxchg_relaxed arch_cmpxchg -#else /* arch_cmpxchg_relaxed */ - -#ifndef arch_cmpxchg_acquire -#define arch_cmpxchg_acquire(...) \ +#if defined(arch_cmpxchg_acquire) +#define raw_cmpxchg_acquire arch_cmpxchg_acquire +#elif defined(arch_cmpxchg_relaxed) +#define raw_cmpxchg_acquire(...) \ __atomic_op_acquire(arch_cmpxchg, __VA_ARGS__) +#elif defined(arch_cmpxchg) +#define raw_cmpxchg_acquire arch_cmpxchg +#else +extern void raw_cmpxchg_acquire_not_implemented(void); +#define raw_cmpxchg_acquire(...) raw_cmpxchg_acquire_not_implemented() #endif -#ifndef arch_cmpxchg_release -#define arch_cmpxchg_release(...) \ +#if defined(arch_cmpxchg_release) +#define raw_cmpxchg_release arch_cmpxchg_release +#elif defined(arch_cmpxchg_relaxed) +#define raw_cmpxchg_release(...) \ __atomic_op_release(arch_cmpxchg, __VA_ARGS__) +#elif defined(arch_cmpxchg) +#define raw_cmpxchg_release arch_cmpxchg +#else +extern void raw_cmpxchg_release_not_implemented(void); +#define raw_cmpxchg_release(...) raw_cmpxchg_release_not_implemented() +#endif + +#if defined(arch_cmpxchg_relaxed) +#define raw_cmpxchg_relaxed arch_cmpxchg_relaxed +#elif defined(arch_cmpxchg) +#define raw_cmpxchg_relaxed arch_cmpxchg +#else +extern void raw_cmpxchg_relaxed_not_implemented(void); +#define raw_cmpxchg_relaxed(...) raw_cmpxchg_relaxed_not_implemented() +#endif + +#if defined(arch_cmpxchg64) +#define raw_cmpxchg64 arch_cmpxchg64 +#elif defined(arch_cmpxchg64_relaxed) +#define raw_cmpxchg64(...) \ + __atomic_op_fence(arch_cmpxchg64, __VA_ARGS__) +#else +extern void raw_cmpxchg64_not_implemented(void); +#define raw_cmpxchg64(...) raw_cmpxchg64_not_implemented() #endif -#ifndef arch_cmpxchg -#define arch_cmpxchg(...) \ - __atomic_op_fence(arch_cmpxchg, __VA_ARGS__) -#endif - -#endif /* arch_cmpxchg_relaxed */ - -#ifndef arch_cmpxchg64_relaxed -#define arch_cmpxchg64_acquire arch_cmpxchg64 -#define arch_cmpxchg64_release arch_cmpxchg64 -#define arch_cmpxchg64_relaxed arch_cmpxchg64 -#else /* arch_cmpxchg64_relaxed */ - -#ifndef arch_cmpxchg64_acquire -#define arch_cmpxchg64_acquire(...) \ +#if defined(arch_cmpxchg64_acquire) +#define raw_cmpxchg64_acquire arch_cmpxchg64_acquire +#elif defined(arch_cmpxchg64_relaxed) +#define raw_cmpxchg64_acquire(...) \ __atomic_op_acquire(arch_cmpxchg64, __VA_ARGS__) +#elif defined(arch_cmpxchg64) +#define raw_cmpxchg64_acquire arch_cmpxchg64 +#else +extern void raw_cmpxchg64_acquire_not_implemented(void); +#define raw_cmpxchg64_acquire(...) raw_cmpxchg64_acquire_not_implemented() #endif -#ifndef arch_cmpxchg64_release -#define arch_cmpxchg64_release(...) \ +#if defined(arch_cmpxchg64_release) +#define raw_cmpxchg64_release arch_cmpxchg64_release +#elif defined(arch_cmpxchg64_relaxed) +#define raw_cmpxchg64_release(...) \ __atomic_op_release(arch_cmpxchg64, __VA_ARGS__) +#elif defined(arch_cmpxchg64) +#define raw_cmpxchg64_release arch_cmpxchg64 +#else +extern void raw_cmpxchg64_release_not_implemented(void); +#define raw_cmpxchg64_release(...) raw_cmpxchg64_release_not_implemented() +#endif + +#if defined(arch_cmpxchg64_relaxed) +#define raw_cmpxchg64_relaxed arch_cmpxchg64_relaxed +#elif defined(arch_cmpxchg64) +#define raw_cmpxchg64_relaxed arch_cmpxchg64 +#else +extern void raw_cmpxchg64_relaxed_not_implemented(void); +#define raw_cmpxchg64_relaxed(...) raw_cmpxchg64_relaxed_not_implemented() +#endif + +#if defined(arch_cmpxchg128) +#define raw_cmpxchg128 arch_cmpxchg128 +#elif defined(arch_cmpxchg128_relaxed) +#define raw_cmpxchg128(...) \ + __atomic_op_fence(arch_cmpxchg128, __VA_ARGS__) +#else +extern void raw_cmpxchg128_not_implemented(void); +#define raw_cmpxchg128(...) raw_cmpxchg128_not_implemented() +#endif + +#if defined(arch_cmpxchg128_acquire) +#define raw_cmpxchg128_acquire arch_cmpxchg128_acquire +#elif defined(arch_cmpxchg128_relaxed) +#define raw_cmpxchg128_acquire(...) \ + __atomic_op_acquire(arch_cmpxchg128, __VA_ARGS__) +#elif defined(arch_cmpxchg128) +#define raw_cmpxchg128_acquire arch_cmpxchg128 +#else +extern void raw_cmpxchg128_acquire_not_implemented(void); +#define raw_cmpxchg128_acquire(...) raw_cmpxchg128_acquire_not_implemented() +#endif + +#if defined(arch_cmpxchg128_release) +#define raw_cmpxchg128_release arch_cmpxchg128_release +#elif defined(arch_cmpxchg128_relaxed) +#define raw_cmpxchg128_release(...) \ + __atomic_op_release(arch_cmpxchg128, __VA_ARGS__) +#elif defined(arch_cmpxchg128) +#define raw_cmpxchg128_release arch_cmpxchg128 +#else +extern void raw_cmpxchg128_release_not_implemented(void); +#define raw_cmpxchg128_release(...) raw_cmpxchg128_release_not_implemented() +#endif + +#if defined(arch_cmpxchg128_relaxed) +#define raw_cmpxchg128_relaxed arch_cmpxchg128_relaxed +#elif defined(arch_cmpxchg128) +#define raw_cmpxchg128_relaxed arch_cmpxchg128 +#else +extern void raw_cmpxchg128_relaxed_not_implemented(void); +#define raw_cmpxchg128_relaxed(...) raw_cmpxchg128_relaxed_not_implemented() +#endif + +#if defined(arch_try_cmpxchg) +#define raw_try_cmpxchg arch_try_cmpxchg +#elif defined(arch_try_cmpxchg_relaxed) +#define raw_try_cmpxchg(...) \ + __atomic_op_fence(arch_try_cmpxchg, __VA_ARGS__) +#else +#define raw_try_cmpxchg(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = raw_cmpxchg((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) #endif -#ifndef arch_cmpxchg64 -#define arch_cmpxchg64(...) \ - __atomic_op_fence(arch_cmpxchg64, __VA_ARGS__) +#if defined(arch_try_cmpxchg_acquire) +#define raw_try_cmpxchg_acquire arch_try_cmpxchg_acquire +#elif defined(arch_try_cmpxchg_relaxed) +#define raw_try_cmpxchg_acquire(...) \ + __atomic_op_acquire(arch_try_cmpxchg, __VA_ARGS__) +#elif defined(arch_try_cmpxchg) +#define raw_try_cmpxchg_acquire arch_try_cmpxchg +#else +#define raw_try_cmpxchg_acquire(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = raw_cmpxchg_acquire((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) #endif -#endif /* arch_cmpxchg64_relaxed */ - -#ifndef arch_try_cmpxchg_relaxed -#ifdef arch_try_cmpxchg -#define arch_try_cmpxchg_acquire arch_try_cmpxchg -#define arch_try_cmpxchg_release arch_try_cmpxchg -#define arch_try_cmpxchg_relaxed arch_try_cmpxchg -#endif /* arch_try_cmpxchg */ - -#ifndef arch_try_cmpxchg -#define arch_try_cmpxchg(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg_release) +#define raw_try_cmpxchg_release arch_try_cmpxchg_release +#elif defined(arch_try_cmpxchg_relaxed) +#define raw_try_cmpxchg_release(...) \ + __atomic_op_release(arch_try_cmpxchg, __VA_ARGS__) +#elif defined(arch_try_cmpxchg) +#define raw_try_cmpxchg_release arch_try_cmpxchg +#else +#define raw_try_cmpxchg_release(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg_release((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg */ +#endif -#ifndef arch_try_cmpxchg_acquire -#define arch_try_cmpxchg_acquire(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg_relaxed) +#define raw_try_cmpxchg_relaxed arch_try_cmpxchg_relaxed +#elif defined(arch_try_cmpxchg) +#define raw_try_cmpxchg_relaxed arch_try_cmpxchg +#else +#define raw_try_cmpxchg_relaxed(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg_acquire((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg_relaxed((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg_acquire */ +#endif -#ifndef arch_try_cmpxchg_release -#define arch_try_cmpxchg_release(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg64) +#define raw_try_cmpxchg64 arch_try_cmpxchg64 +#elif defined(arch_try_cmpxchg64_relaxed) +#define raw_try_cmpxchg64(...) \ + __atomic_op_fence(arch_try_cmpxchg64, __VA_ARGS__) +#else +#define raw_try_cmpxchg64(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg_release((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg64((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg_release */ +#endif -#ifndef arch_try_cmpxchg_relaxed -#define arch_try_cmpxchg_relaxed(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg64_acquire) +#define raw_try_cmpxchg64_acquire arch_try_cmpxchg64_acquire +#elif defined(arch_try_cmpxchg64_relaxed) +#define raw_try_cmpxchg64_acquire(...) \ + __atomic_op_acquire(arch_try_cmpxchg64, __VA_ARGS__) +#elif defined(arch_try_cmpxchg64) +#define raw_try_cmpxchg64_acquire arch_try_cmpxchg64 +#else +#define raw_try_cmpxchg64_acquire(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg_relaxed((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg64_acquire((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg_relaxed */ - -#else /* arch_try_cmpxchg_relaxed */ - -#ifndef arch_try_cmpxchg_acquire -#define arch_try_cmpxchg_acquire(...) \ - __atomic_op_acquire(arch_try_cmpxchg, __VA_ARGS__) #endif -#ifndef arch_try_cmpxchg_release -#define arch_try_cmpxchg_release(...) \ - __atomic_op_release(arch_try_cmpxchg, __VA_ARGS__) +#if defined(arch_try_cmpxchg64_release) +#define raw_try_cmpxchg64_release arch_try_cmpxchg64_release +#elif defined(arch_try_cmpxchg64_relaxed) +#define raw_try_cmpxchg64_release(...) \ + __atomic_op_release(arch_try_cmpxchg64, __VA_ARGS__) +#elif defined(arch_try_cmpxchg64) +#define raw_try_cmpxchg64_release arch_try_cmpxchg64 +#else +#define raw_try_cmpxchg64_release(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = raw_cmpxchg64_release((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) #endif -#ifndef arch_try_cmpxchg -#define arch_try_cmpxchg(...) \ - __atomic_op_fence(arch_try_cmpxchg, __VA_ARGS__) +#if defined(arch_try_cmpxchg64_relaxed) +#define raw_try_cmpxchg64_relaxed arch_try_cmpxchg64_relaxed +#elif defined(arch_try_cmpxchg64) +#define raw_try_cmpxchg64_relaxed arch_try_cmpxchg64 +#else +#define raw_try_cmpxchg64_relaxed(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = raw_cmpxchg64_relaxed((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) #endif -#endif /* arch_try_cmpxchg_relaxed */ - -#ifndef arch_try_cmpxchg64_relaxed -#ifdef arch_try_cmpxchg64 -#define arch_try_cmpxchg64_acquire arch_try_cmpxchg64 -#define arch_try_cmpxchg64_release arch_try_cmpxchg64 -#define arch_try_cmpxchg64_relaxed arch_try_cmpxchg64 -#endif /* arch_try_cmpxchg64 */ - -#ifndef arch_try_cmpxchg64 -#define arch_try_cmpxchg64(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg128) +#define raw_try_cmpxchg128 arch_try_cmpxchg128 +#elif defined(arch_try_cmpxchg128_relaxed) +#define raw_try_cmpxchg128(...) \ + __atomic_op_fence(arch_try_cmpxchg128, __VA_ARGS__) +#else +#define raw_try_cmpxchg128(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg64((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg128((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg64 */ +#endif -#ifndef arch_try_cmpxchg64_acquire -#define arch_try_cmpxchg64_acquire(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg128_acquire) +#define raw_try_cmpxchg128_acquire arch_try_cmpxchg128_acquire +#elif defined(arch_try_cmpxchg128_relaxed) +#define raw_try_cmpxchg128_acquire(...) \ + __atomic_op_acquire(arch_try_cmpxchg128, __VA_ARGS__) +#elif defined(arch_try_cmpxchg128) +#define raw_try_cmpxchg128_acquire arch_try_cmpxchg128 +#else +#define raw_try_cmpxchg128_acquire(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg64_acquire((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg128_acquire((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg64_acquire */ +#endif -#ifndef arch_try_cmpxchg64_release -#define arch_try_cmpxchg64_release(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg128_release) +#define raw_try_cmpxchg128_release arch_try_cmpxchg128_release +#elif defined(arch_try_cmpxchg128_relaxed) +#define raw_try_cmpxchg128_release(...) \ + __atomic_op_release(arch_try_cmpxchg128, __VA_ARGS__) +#elif defined(arch_try_cmpxchg128) +#define raw_try_cmpxchg128_release arch_try_cmpxchg128 +#else +#define raw_try_cmpxchg128_release(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg64_release((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg128_release((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg64_release */ +#endif -#ifndef arch_try_cmpxchg64_relaxed -#define arch_try_cmpxchg64_relaxed(_ptr, _oldp, _new) \ +#if defined(arch_try_cmpxchg128_relaxed) +#define raw_try_cmpxchg128_relaxed arch_try_cmpxchg128_relaxed +#elif defined(arch_try_cmpxchg128) +#define raw_try_cmpxchg128_relaxed arch_try_cmpxchg128 +#else +#define raw_try_cmpxchg128_relaxed(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg64_relaxed((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg128_relaxed((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg64_relaxed */ - -#else /* arch_try_cmpxchg64_relaxed */ - -#ifndef arch_try_cmpxchg64_acquire -#define arch_try_cmpxchg64_acquire(...) \ - __atomic_op_acquire(arch_try_cmpxchg64, __VA_ARGS__) #endif -#ifndef arch_try_cmpxchg64_release -#define arch_try_cmpxchg64_release(...) \ - __atomic_op_release(arch_try_cmpxchg64, __VA_ARGS__) -#endif +#define raw_cmpxchg_local arch_cmpxchg_local -#ifndef arch_try_cmpxchg64 -#define arch_try_cmpxchg64(...) \ - __atomic_op_fence(arch_try_cmpxchg64, __VA_ARGS__) +#ifdef arch_try_cmpxchg_local +#define raw_try_cmpxchg_local arch_try_cmpxchg_local +#else +#define raw_try_cmpxchg_local(_ptr, _oldp, _new) \ +({ \ + typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ + ___r = raw_cmpxchg_local((_ptr), ___o, (_new)); \ + if (unlikely(___r != ___o)) \ + *___op = ___r; \ + likely(___r == ___o); \ +}) #endif -#endif /* arch_try_cmpxchg64_relaxed */ +#define raw_cmpxchg64_local arch_cmpxchg64_local -#ifndef arch_try_cmpxchg_local -#define arch_try_cmpxchg_local(_ptr, _oldp, _new) \ +#ifdef arch_try_cmpxchg64_local +#define raw_try_cmpxchg64_local arch_try_cmpxchg64_local +#else +#define raw_try_cmpxchg64_local(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg_local((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg64_local((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg_local */ +#endif + +#define raw_cmpxchg128_local arch_cmpxchg128_local -#ifndef arch_try_cmpxchg64_local -#define arch_try_cmpxchg64_local(_ptr, _oldp, _new) \ +#ifdef arch_try_cmpxchg128_local +#define raw_try_cmpxchg128_local arch_try_cmpxchg128_local +#else +#define raw_try_cmpxchg128_local(_ptr, _oldp, _new) \ ({ \ typeof(*(_ptr)) *___op = (_oldp), ___o = *___op, ___r; \ - ___r = arch_cmpxchg64_local((_ptr), ___o, (_new)); \ + ___r = raw_cmpxchg128_local((_ptr), ___o, (_new)); \ if (unlikely(___r != ___o)) \ *___op = ___r; \ likely(___r == ___o); \ }) -#endif /* arch_try_cmpxchg64_local */ +#endif + +#define raw_sync_cmpxchg arch_sync_cmpxchg + +/** + * raw_atomic_read() - atomic load with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_read() elsewhere. + * + * Return: The value loaded from @v. + */ +static __always_inline int +raw_atomic_read(const atomic_t *v) +{ + return arch_atomic_read(v); +} -#ifndef arch_atomic_read_acquire +/** + * raw_atomic_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_read_acquire() elsewhere. + * + * Return: The value loaded from @v. + */ static __always_inline int -arch_atomic_read_acquire(const atomic_t *v) +raw_atomic_read_acquire(const atomic_t *v) { +#if defined(arch_atomic_read_acquire) + return arch_atomic_read_acquire(v); +#elif defined(arch_atomic_read) + return arch_atomic_read(v); +#else int ret; if (__native_word(atomic_t)) { ret = smp_load_acquire(&(v)->counter); } else { - ret = arch_atomic_read(v); + ret = raw_atomic_read(v); __atomic_acquire_fence(); } return ret; -} -#define arch_atomic_read_acquire arch_atomic_read_acquire #endif +} -#ifndef arch_atomic_set_release +/** + * raw_atomic_set() - atomic set with relaxed ordering + * @v: pointer to atomic_t + * @i: int value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_set() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_set_release(atomic_t *v, int i) +raw_atomic_set(atomic_t *v, int i) { + arch_atomic_set(v, i); +} + +/** + * raw_atomic_set_release() - atomic set with release ordering + * @v: pointer to atomic_t + * @i: int value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Safe to use in noinstr code; prefer atomic_set_release() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_set_release(atomic_t *v, int i) +{ +#if defined(arch_atomic_set_release) + arch_atomic_set_release(v, i); +#elif defined(arch_atomic_set) + arch_atomic_set(v, i); +#else if (__native_word(atomic_t)) { smp_store_release(&(v)->counter, i); } else { __atomic_release_fence(); - arch_atomic_set(v, i); + raw_atomic_set(v, i); } -} -#define arch_atomic_set_release arch_atomic_set_release #endif - -#ifndef arch_atomic_add_return_relaxed -#define arch_atomic_add_return_acquire arch_atomic_add_return -#define arch_atomic_add_return_release arch_atomic_add_return -#define arch_atomic_add_return_relaxed arch_atomic_add_return -#else /* arch_atomic_add_return_relaxed */ - -#ifndef arch_atomic_add_return_acquire -static __always_inline int -arch_atomic_add_return_acquire(int i, atomic_t *v) -{ - int ret = arch_atomic_add_return_relaxed(i, v); - __atomic_acquire_fence(); - return ret; } -#define arch_atomic_add_return_acquire arch_atomic_add_return_acquire -#endif -#ifndef arch_atomic_add_return_release -static __always_inline int -arch_atomic_add_return_release(int i, atomic_t *v) +/** + * raw_atomic_add() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_add() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_add(int i, atomic_t *v) { - __atomic_release_fence(); - return arch_atomic_add_return_relaxed(i, v); + arch_atomic_add(i, v); } -#define arch_atomic_add_return_release arch_atomic_add_return_release -#endif -#ifndef arch_atomic_add_return +/** + * raw_atomic_add_return() - atomic add with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_add_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_add_return(int i, atomic_t *v) +raw_atomic_add_return(int i, atomic_t *v) { +#if defined(arch_atomic_add_return) + return arch_atomic_add_return(i, v); +#elif defined(arch_atomic_add_return_relaxed) int ret; __atomic_pre_full_fence(); ret = arch_atomic_add_return_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_add_return arch_atomic_add_return +#else +#error "Unable to define raw_atomic_add_return" #endif +} -#endif /* arch_atomic_add_return_relaxed */ - -#ifndef arch_atomic_fetch_add_relaxed -#define arch_atomic_fetch_add_acquire arch_atomic_fetch_add -#define arch_atomic_fetch_add_release arch_atomic_fetch_add -#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add -#else /* arch_atomic_fetch_add_relaxed */ - -#ifndef arch_atomic_fetch_add_acquire +/** + * raw_atomic_add_return_acquire() - atomic add with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_add_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_add_acquire(int i, atomic_t *v) +raw_atomic_add_return_acquire(int i, atomic_t *v) { - int ret = arch_atomic_fetch_add_relaxed(i, v); +#if defined(arch_atomic_add_return_acquire) + return arch_atomic_add_return_acquire(i, v); +#elif defined(arch_atomic_add_return_relaxed) + int ret = arch_atomic_add_return_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_add_acquire arch_atomic_fetch_add_acquire +#elif defined(arch_atomic_add_return) + return arch_atomic_add_return(i, v); +#else +#error "Unable to define raw_atomic_add_return_acquire" #endif +} -#ifndef arch_atomic_fetch_add_release +/** + * raw_atomic_add_return_release() - atomic add with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_add_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_add_release(int i, atomic_t *v) +raw_atomic_add_return_release(int i, atomic_t *v) { +#if defined(arch_atomic_add_return_release) + return arch_atomic_add_return_release(i, v); +#elif defined(arch_atomic_add_return_relaxed) __atomic_release_fence(); - return arch_atomic_fetch_add_relaxed(i, v); + return arch_atomic_add_return_relaxed(i, v); +#elif defined(arch_atomic_add_return) + return arch_atomic_add_return(i, v); +#else +#error "Unable to define raw_atomic_add_return_release" +#endif } -#define arch_atomic_fetch_add_release arch_atomic_fetch_add_release + +/** + * raw_atomic_add_return_relaxed() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_add_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline int +raw_atomic_add_return_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_add_return_relaxed) + return arch_atomic_add_return_relaxed(i, v); +#elif defined(arch_atomic_add_return) + return arch_atomic_add_return(i, v); +#else +#error "Unable to define raw_atomic_add_return_relaxed" #endif +} -#ifndef arch_atomic_fetch_add +/** + * raw_atomic_fetch_add() - atomic add with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_add() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_add(int i, atomic_t *v) +raw_atomic_fetch_add(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_add) + return arch_atomic_fetch_add(i, v); +#elif defined(arch_atomic_fetch_add_relaxed) int ret; __atomic_pre_full_fence(); ret = arch_atomic_fetch_add_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_add arch_atomic_fetch_add +#else +#error "Unable to define raw_atomic_fetch_add" #endif +} -#endif /* arch_atomic_fetch_add_relaxed */ - -#ifndef arch_atomic_sub_return_relaxed -#define arch_atomic_sub_return_acquire arch_atomic_sub_return -#define arch_atomic_sub_return_release arch_atomic_sub_return -#define arch_atomic_sub_return_relaxed arch_atomic_sub_return -#else /* arch_atomic_sub_return_relaxed */ - -#ifndef arch_atomic_sub_return_acquire +/** + * raw_atomic_fetch_add_acquire() - atomic add with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_add_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_sub_return_acquire(int i, atomic_t *v) +raw_atomic_fetch_add_acquire(int i, atomic_t *v) { - int ret = arch_atomic_sub_return_relaxed(i, v); +#if defined(arch_atomic_fetch_add_acquire) + return arch_atomic_fetch_add_acquire(i, v); +#elif defined(arch_atomic_fetch_add_relaxed) + int ret = arch_atomic_fetch_add_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_sub_return_acquire arch_atomic_sub_return_acquire +#elif defined(arch_atomic_fetch_add) + return arch_atomic_fetch_add(i, v); +#else +#error "Unable to define raw_atomic_fetch_add_acquire" #endif +} -#ifndef arch_atomic_sub_return_release +/** + * raw_atomic_fetch_add_release() - atomic add with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_add_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_sub_return_release(int i, atomic_t *v) +raw_atomic_fetch_add_release(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_add_release) + return arch_atomic_fetch_add_release(i, v); +#elif defined(arch_atomic_fetch_add_relaxed) __atomic_release_fence(); - return arch_atomic_sub_return_relaxed(i, v); + return arch_atomic_fetch_add_relaxed(i, v); +#elif defined(arch_atomic_fetch_add) + return arch_atomic_fetch_add(i, v); +#else +#error "Unable to define raw_atomic_fetch_add_release" +#endif } -#define arch_atomic_sub_return_release arch_atomic_sub_return_release + +/** + * raw_atomic_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_add_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline int +raw_atomic_fetch_add_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_fetch_add_relaxed) + return arch_atomic_fetch_add_relaxed(i, v); +#elif defined(arch_atomic_fetch_add) + return arch_atomic_fetch_add(i, v); +#else +#error "Unable to define raw_atomic_fetch_add_relaxed" #endif +} -#ifndef arch_atomic_sub_return +/** + * raw_atomic_sub() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_sub() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_sub(int i, atomic_t *v) +{ + arch_atomic_sub(i, v); +} + +/** + * raw_atomic_sub_return() - atomic subtract with full ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_sub_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_sub_return(int i, atomic_t *v) +raw_atomic_sub_return(int i, atomic_t *v) { +#if defined(arch_atomic_sub_return) + return arch_atomic_sub_return(i, v); +#elif defined(arch_atomic_sub_return_relaxed) int ret; __atomic_pre_full_fence(); ret = arch_atomic_sub_return_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_sub_return arch_atomic_sub_return +#else +#error "Unable to define raw_atomic_sub_return" #endif +} -#endif /* arch_atomic_sub_return_relaxed */ - -#ifndef arch_atomic_fetch_sub_relaxed -#define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub -#define arch_atomic_fetch_sub_release arch_atomic_fetch_sub -#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub -#else /* arch_atomic_fetch_sub_relaxed */ - -#ifndef arch_atomic_fetch_sub_acquire +/** + * raw_atomic_sub_return_acquire() - atomic subtract with acquire ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_sub_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_sub_acquire(int i, atomic_t *v) +raw_atomic_sub_return_acquire(int i, atomic_t *v) { - int ret = arch_atomic_fetch_sub_relaxed(i, v); +#if defined(arch_atomic_sub_return_acquire) + return arch_atomic_sub_return_acquire(i, v); +#elif defined(arch_atomic_sub_return_relaxed) + int ret = arch_atomic_sub_return_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_sub_acquire arch_atomic_fetch_sub_acquire +#elif defined(arch_atomic_sub_return) + return arch_atomic_sub_return(i, v); +#else +#error "Unable to define raw_atomic_sub_return_acquire" #endif +} -#ifndef arch_atomic_fetch_sub_release +/** + * raw_atomic_sub_return_release() - atomic subtract with release ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_sub_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_sub_release(int i, atomic_t *v) +raw_atomic_sub_return_release(int i, atomic_t *v) { +#if defined(arch_atomic_sub_return_release) + return arch_atomic_sub_return_release(i, v); +#elif defined(arch_atomic_sub_return_relaxed) __atomic_release_fence(); - return arch_atomic_fetch_sub_relaxed(i, v); + return arch_atomic_sub_return_relaxed(i, v); +#elif defined(arch_atomic_sub_return) + return arch_atomic_sub_return(i, v); +#else +#error "Unable to define raw_atomic_sub_return_release" +#endif } -#define arch_atomic_fetch_sub_release arch_atomic_fetch_sub_release + +/** + * raw_atomic_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_sub_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline int +raw_atomic_sub_return_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_sub_return_relaxed) + return arch_atomic_sub_return_relaxed(i, v); +#elif defined(arch_atomic_sub_return) + return arch_atomic_sub_return(i, v); +#else +#error "Unable to define raw_atomic_sub_return_relaxed" #endif +} -#ifndef arch_atomic_fetch_sub +/** + * raw_atomic_fetch_sub() - atomic subtract with full ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_sub() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_sub(int i, atomic_t *v) +raw_atomic_fetch_sub(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_sub) + return arch_atomic_fetch_sub(i, v); +#elif defined(arch_atomic_fetch_sub_relaxed) int ret; __atomic_pre_full_fence(); ret = arch_atomic_fetch_sub_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_sub arch_atomic_fetch_sub +#else +#error "Unable to define raw_atomic_fetch_sub" #endif - -#endif /* arch_atomic_fetch_sub_relaxed */ - -#ifndef arch_atomic_inc -static __always_inline void -arch_atomic_inc(atomic_t *v) -{ - arch_atomic_add(1, v); } -#define arch_atomic_inc arch_atomic_inc -#endif - -#ifndef arch_atomic_inc_return_relaxed -#ifdef arch_atomic_inc_return -#define arch_atomic_inc_return_acquire arch_atomic_inc_return -#define arch_atomic_inc_return_release arch_atomic_inc_return -#define arch_atomic_inc_return_relaxed arch_atomic_inc_return -#endif /* arch_atomic_inc_return */ -#ifndef arch_atomic_inc_return +/** + * raw_atomic_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_sub_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_inc_return(atomic_t *v) +raw_atomic_fetch_sub_acquire(int i, atomic_t *v) { - return arch_atomic_add_return(1, v); -} -#define arch_atomic_inc_return arch_atomic_inc_return +#if defined(arch_atomic_fetch_sub_acquire) + return arch_atomic_fetch_sub_acquire(i, v); +#elif defined(arch_atomic_fetch_sub_relaxed) + int ret = arch_atomic_fetch_sub_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic_fetch_sub) + return arch_atomic_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic_fetch_sub_acquire" #endif - -#ifndef arch_atomic_inc_return_acquire -static __always_inline int -arch_atomic_inc_return_acquire(atomic_t *v) -{ - return arch_atomic_add_return_acquire(1, v); } -#define arch_atomic_inc_return_acquire arch_atomic_inc_return_acquire -#endif -#ifndef arch_atomic_inc_return_release +/** + * raw_atomic_fetch_sub_release() - atomic subtract with release ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_sub_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_inc_return_release(atomic_t *v) +raw_atomic_fetch_sub_release(int i, atomic_t *v) { - return arch_atomic_add_return_release(1, v); -} -#define arch_atomic_inc_return_release arch_atomic_inc_return_release +#if defined(arch_atomic_fetch_sub_release) + return arch_atomic_fetch_sub_release(i, v); +#elif defined(arch_atomic_fetch_sub_relaxed) + __atomic_release_fence(); + return arch_atomic_fetch_sub_relaxed(i, v); +#elif defined(arch_atomic_fetch_sub) + return arch_atomic_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic_fetch_sub_release" #endif - -#ifndef arch_atomic_inc_return_relaxed -static __always_inline int -arch_atomic_inc_return_relaxed(atomic_t *v) -{ - return arch_atomic_add_return_relaxed(1, v); } -#define arch_atomic_inc_return_relaxed arch_atomic_inc_return_relaxed -#endif -#else /* arch_atomic_inc_return_relaxed */ - -#ifndef arch_atomic_inc_return_acquire +/** + * raw_atomic_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_sub_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_inc_return_acquire(atomic_t *v) +raw_atomic_fetch_sub_relaxed(int i, atomic_t *v) { - int ret = arch_atomic_inc_return_relaxed(v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic_inc_return_acquire arch_atomic_inc_return_acquire +#if defined(arch_atomic_fetch_sub_relaxed) + return arch_atomic_fetch_sub_relaxed(i, v); +#elif defined(arch_atomic_fetch_sub) + return arch_atomic_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic_fetch_sub_relaxed" #endif +} -#ifndef arch_atomic_inc_return_release -static __always_inline int -arch_atomic_inc_return_release(atomic_t *v) +/** + * raw_atomic_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_inc() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_inc(atomic_t *v) { - __atomic_release_fence(); - return arch_atomic_inc_return_relaxed(v); -} -#define arch_atomic_inc_return_release arch_atomic_inc_return_release +#if defined(arch_atomic_inc) + arch_atomic_inc(v); +#else + raw_atomic_add(1, v); #endif +} -#ifndef arch_atomic_inc_return +/** + * raw_atomic_inc_return() - atomic increment with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_inc_return(atomic_t *v) +raw_atomic_inc_return(atomic_t *v) { +#if defined(arch_atomic_inc_return) + return arch_atomic_inc_return(v); +#elif defined(arch_atomic_inc_return_relaxed) int ret; __atomic_pre_full_fence(); ret = arch_atomic_inc_return_relaxed(v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_inc_return arch_atomic_inc_return +#else + return raw_atomic_add_return(1, v); #endif +} -#endif /* arch_atomic_inc_return_relaxed */ - -#ifndef arch_atomic_fetch_inc_relaxed -#ifdef arch_atomic_fetch_inc -#define arch_atomic_fetch_inc_acquire arch_atomic_fetch_inc -#define arch_atomic_fetch_inc_release arch_atomic_fetch_inc -#define arch_atomic_fetch_inc_relaxed arch_atomic_fetch_inc -#endif /* arch_atomic_fetch_inc */ - -#ifndef arch_atomic_fetch_inc +/** + * raw_atomic_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_inc(atomic_t *v) +raw_atomic_inc_return_acquire(atomic_t *v) { - return arch_atomic_fetch_add(1, v); -} -#define arch_atomic_fetch_inc arch_atomic_fetch_inc +#if defined(arch_atomic_inc_return_acquire) + return arch_atomic_inc_return_acquire(v); +#elif defined(arch_atomic_inc_return_relaxed) + int ret = arch_atomic_inc_return_relaxed(v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic_inc_return) + return arch_atomic_inc_return(v); +#else + return raw_atomic_add_return_acquire(1, v); #endif +} -#ifndef arch_atomic_fetch_inc_acquire +/** + * raw_atomic_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_inc_acquire(atomic_t *v) +raw_atomic_inc_return_release(atomic_t *v) { - return arch_atomic_fetch_add_acquire(1, v); -} -#define arch_atomic_fetch_inc_acquire arch_atomic_fetch_inc_acquire +#if defined(arch_atomic_inc_return_release) + return arch_atomic_inc_return_release(v); +#elif defined(arch_atomic_inc_return_relaxed) + __atomic_release_fence(); + return arch_atomic_inc_return_relaxed(v); +#elif defined(arch_atomic_inc_return) + return arch_atomic_inc_return(v); +#else + return raw_atomic_add_return_release(1, v); #endif +} -#ifndef arch_atomic_fetch_inc_release +/** + * raw_atomic_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_fetch_inc_release(atomic_t *v) +raw_atomic_inc_return_relaxed(atomic_t *v) { - return arch_atomic_fetch_add_release(1, v); -} -#define arch_atomic_fetch_inc_release arch_atomic_fetch_inc_release +#if defined(arch_atomic_inc_return_relaxed) + return arch_atomic_inc_return_relaxed(v); +#elif defined(arch_atomic_inc_return) + return arch_atomic_inc_return(v); +#else + return raw_atomic_add_return_relaxed(1, v); #endif +} -#ifndef arch_atomic_fetch_inc_relaxed +/** + * raw_atomic_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_inc() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_inc_relaxed(atomic_t *v) +raw_atomic_fetch_inc(atomic_t *v) { - return arch_atomic_fetch_add_relaxed(1, v); -} -#define arch_atomic_fetch_inc_relaxed arch_atomic_fetch_inc_relaxed +#if defined(arch_atomic_fetch_inc) + return arch_atomic_fetch_inc(v); +#elif defined(arch_atomic_fetch_inc_relaxed) + int ret; + __atomic_pre_full_fence(); + ret = arch_atomic_fetch_inc_relaxed(v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic_fetch_add(1, v); #endif +} -#else /* arch_atomic_fetch_inc_relaxed */ - -#ifndef arch_atomic_fetch_inc_acquire +/** + * raw_atomic_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_inc_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_inc_acquire(atomic_t *v) +raw_atomic_fetch_inc_acquire(atomic_t *v) { +#if defined(arch_atomic_fetch_inc_acquire) + return arch_atomic_fetch_inc_acquire(v); +#elif defined(arch_atomic_fetch_inc_relaxed) int ret = arch_atomic_fetch_inc_relaxed(v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_inc_acquire arch_atomic_fetch_inc_acquire +#elif defined(arch_atomic_fetch_inc) + return arch_atomic_fetch_inc(v); +#else + return raw_atomic_fetch_add_acquire(1, v); #endif +} -#ifndef arch_atomic_fetch_inc_release +/** + * raw_atomic_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_inc_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_inc_release(atomic_t *v) +raw_atomic_fetch_inc_release(atomic_t *v) { +#if defined(arch_atomic_fetch_inc_release) + return arch_atomic_fetch_inc_release(v); +#elif defined(arch_atomic_fetch_inc_relaxed) __atomic_release_fence(); return arch_atomic_fetch_inc_relaxed(v); -} -#define arch_atomic_fetch_inc_release arch_atomic_fetch_inc_release +#elif defined(arch_atomic_fetch_inc) + return arch_atomic_fetch_inc(v); +#else + return raw_atomic_fetch_add_release(1, v); #endif +} -#ifndef arch_atomic_fetch_inc +/** + * raw_atomic_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_inc_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_inc(atomic_t *v) +raw_atomic_fetch_inc_relaxed(atomic_t *v) { - int ret; - __atomic_pre_full_fence(); - ret = arch_atomic_fetch_inc_relaxed(v); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic_fetch_inc arch_atomic_fetch_inc +#if defined(arch_atomic_fetch_inc_relaxed) + return arch_atomic_fetch_inc_relaxed(v); +#elif defined(arch_atomic_fetch_inc) + return arch_atomic_fetch_inc(v); +#else + return raw_atomic_fetch_add_relaxed(1, v); #endif +} -#endif /* arch_atomic_fetch_inc_relaxed */ - -#ifndef arch_atomic_dec +/** + * raw_atomic_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_dec() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_dec(atomic_t *v) +raw_atomic_dec(atomic_t *v) { - arch_atomic_sub(1, v); -} -#define arch_atomic_dec arch_atomic_dec +#if defined(arch_atomic_dec) + arch_atomic_dec(v); +#else + raw_atomic_sub(1, v); #endif - -#ifndef arch_atomic_dec_return_relaxed -#ifdef arch_atomic_dec_return -#define arch_atomic_dec_return_acquire arch_atomic_dec_return -#define arch_atomic_dec_return_release arch_atomic_dec_return -#define arch_atomic_dec_return_relaxed arch_atomic_dec_return -#endif /* arch_atomic_dec_return */ - -#ifndef arch_atomic_dec_return -static __always_inline int -arch_atomic_dec_return(atomic_t *v) -{ - return arch_atomic_sub_return(1, v); } -#define arch_atomic_dec_return arch_atomic_dec_return -#endif -#ifndef arch_atomic_dec_return_acquire -static __always_inline int -arch_atomic_dec_return_acquire(atomic_t *v) -{ - return arch_atomic_sub_return_acquire(1, v); -} -#define arch_atomic_dec_return_acquire arch_atomic_dec_return_acquire -#endif - -#ifndef arch_atomic_dec_return_release +/** + * raw_atomic_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_dec_return_release(atomic_t *v) +raw_atomic_dec_return(atomic_t *v) { - return arch_atomic_sub_return_release(1, v); -} -#define arch_atomic_dec_return_release arch_atomic_dec_return_release +#if defined(arch_atomic_dec_return) + return arch_atomic_dec_return(v); +#elif defined(arch_atomic_dec_return_relaxed) + int ret; + __atomic_pre_full_fence(); + ret = arch_atomic_dec_return_relaxed(v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic_sub_return(1, v); #endif - -#ifndef arch_atomic_dec_return_relaxed -static __always_inline int -arch_atomic_dec_return_relaxed(atomic_t *v) -{ - return arch_atomic_sub_return_relaxed(1, v); } -#define arch_atomic_dec_return_relaxed arch_atomic_dec_return_relaxed -#endif - -#else /* arch_atomic_dec_return_relaxed */ -#ifndef arch_atomic_dec_return_acquire +/** + * raw_atomic_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_dec_return_acquire(atomic_t *v) +raw_atomic_dec_return_acquire(atomic_t *v) { +#if defined(arch_atomic_dec_return_acquire) + return arch_atomic_dec_return_acquire(v); +#elif defined(arch_atomic_dec_return_relaxed) int ret = arch_atomic_dec_return_relaxed(v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_dec_return_acquire arch_atomic_dec_return_acquire +#elif defined(arch_atomic_dec_return) + return arch_atomic_dec_return(v); +#else + return raw_atomic_sub_return_acquire(1, v); #endif +} -#ifndef arch_atomic_dec_return_release +/** + * raw_atomic_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline int -arch_atomic_dec_return_release(atomic_t *v) +raw_atomic_dec_return_release(atomic_t *v) { +#if defined(arch_atomic_dec_return_release) + return arch_atomic_dec_return_release(v); +#elif defined(arch_atomic_dec_return_relaxed) __atomic_release_fence(); return arch_atomic_dec_return_relaxed(v); +#elif defined(arch_atomic_dec_return) + return arch_atomic_dec_return(v); +#else + return raw_atomic_sub_return_release(1, v); +#endif } -#define arch_atomic_dec_return_release arch_atomic_dec_return_release + +/** + * raw_atomic_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline int +raw_atomic_dec_return_relaxed(atomic_t *v) +{ +#if defined(arch_atomic_dec_return_relaxed) + return arch_atomic_dec_return_relaxed(v); +#elif defined(arch_atomic_dec_return) + return arch_atomic_dec_return(v); +#else + return raw_atomic_sub_return_relaxed(1, v); #endif +} -#ifndef arch_atomic_dec_return +/** + * raw_atomic_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_dec() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_dec_return(atomic_t *v) +raw_atomic_fetch_dec(atomic_t *v) { +#if defined(arch_atomic_fetch_dec) + return arch_atomic_fetch_dec(v); +#elif defined(arch_atomic_fetch_dec_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_dec_return_relaxed(v); + ret = arch_atomic_fetch_dec_relaxed(v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_dec_return arch_atomic_dec_return +#else + return raw_atomic_fetch_sub(1, v); #endif - -#endif /* arch_atomic_dec_return_relaxed */ - -#ifndef arch_atomic_fetch_dec_relaxed -#ifdef arch_atomic_fetch_dec -#define arch_atomic_fetch_dec_acquire arch_atomic_fetch_dec -#define arch_atomic_fetch_dec_release arch_atomic_fetch_dec -#define arch_atomic_fetch_dec_relaxed arch_atomic_fetch_dec -#endif /* arch_atomic_fetch_dec */ - -#ifndef arch_atomic_fetch_dec -static __always_inline int -arch_atomic_fetch_dec(atomic_t *v) -{ - return arch_atomic_fetch_sub(1, v); } -#define arch_atomic_fetch_dec arch_atomic_fetch_dec -#endif -#ifndef arch_atomic_fetch_dec_acquire +/** + * raw_atomic_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_dec_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_dec_acquire(atomic_t *v) +raw_atomic_fetch_dec_acquire(atomic_t *v) { - return arch_atomic_fetch_sub_acquire(1, v); -} -#define arch_atomic_fetch_dec_acquire arch_atomic_fetch_dec_acquire +#if defined(arch_atomic_fetch_dec_acquire) + return arch_atomic_fetch_dec_acquire(v); +#elif defined(arch_atomic_fetch_dec_relaxed) + int ret = arch_atomic_fetch_dec_relaxed(v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic_fetch_dec) + return arch_atomic_fetch_dec(v); +#else + return raw_atomic_fetch_sub_acquire(1, v); #endif - -#ifndef arch_atomic_fetch_dec_release -static __always_inline int -arch_atomic_fetch_dec_release(atomic_t *v) -{ - return arch_atomic_fetch_sub_release(1, v); } -#define arch_atomic_fetch_dec_release arch_atomic_fetch_dec_release -#endif -#ifndef arch_atomic_fetch_dec_relaxed +/** + * raw_atomic_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_dec_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_dec_relaxed(atomic_t *v) +raw_atomic_fetch_dec_release(atomic_t *v) { - return arch_atomic_fetch_sub_relaxed(1, v); -} -#define arch_atomic_fetch_dec_relaxed arch_atomic_fetch_dec_relaxed +#if defined(arch_atomic_fetch_dec_release) + return arch_atomic_fetch_dec_release(v); +#elif defined(arch_atomic_fetch_dec_relaxed) + __atomic_release_fence(); + return arch_atomic_fetch_dec_relaxed(v); +#elif defined(arch_atomic_fetch_dec) + return arch_atomic_fetch_dec(v); +#else + return raw_atomic_fetch_sub_release(1, v); #endif +} -#else /* arch_atomic_fetch_dec_relaxed */ - -#ifndef arch_atomic_fetch_dec_acquire +/** + * raw_atomic_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_dec_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_dec_acquire(atomic_t *v) +raw_atomic_fetch_dec_relaxed(atomic_t *v) { - int ret = arch_atomic_fetch_dec_relaxed(v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic_fetch_dec_acquire arch_atomic_fetch_dec_acquire +#if defined(arch_atomic_fetch_dec_relaxed) + return arch_atomic_fetch_dec_relaxed(v); +#elif defined(arch_atomic_fetch_dec) + return arch_atomic_fetch_dec(v); +#else + return raw_atomic_fetch_sub_relaxed(1, v); #endif +} -#ifndef arch_atomic_fetch_dec_release -static __always_inline int -arch_atomic_fetch_dec_release(atomic_t *v) +/** + * raw_atomic_and() - atomic bitwise AND with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_and() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_and(int i, atomic_t *v) { - __atomic_release_fence(); - return arch_atomic_fetch_dec_relaxed(v); + arch_atomic_and(i, v); } -#define arch_atomic_fetch_dec_release arch_atomic_fetch_dec_release -#endif -#ifndef arch_atomic_fetch_dec +/** + * raw_atomic_fetch_and() - atomic bitwise AND with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_and() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_dec(atomic_t *v) +raw_atomic_fetch_and(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_and) + return arch_atomic_fetch_and(i, v); +#elif defined(arch_atomic_fetch_and_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_fetch_dec_relaxed(v); + ret = arch_atomic_fetch_and_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_dec arch_atomic_fetch_dec +#else +#error "Unable to define raw_atomic_fetch_and" #endif +} -#endif /* arch_atomic_fetch_dec_relaxed */ - -#ifndef arch_atomic_fetch_and_relaxed -#define arch_atomic_fetch_and_acquire arch_atomic_fetch_and -#define arch_atomic_fetch_and_release arch_atomic_fetch_and -#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and -#else /* arch_atomic_fetch_and_relaxed */ - -#ifndef arch_atomic_fetch_and_acquire +/** + * raw_atomic_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_and_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_and_acquire(int i, atomic_t *v) +raw_atomic_fetch_and_acquire(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_and_acquire) + return arch_atomic_fetch_and_acquire(i, v); +#elif defined(arch_atomic_fetch_and_relaxed) int ret = arch_atomic_fetch_and_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_and_acquire arch_atomic_fetch_and_acquire +#elif defined(arch_atomic_fetch_and) + return arch_atomic_fetch_and(i, v); +#else +#error "Unable to define raw_atomic_fetch_and_acquire" #endif +} -#ifndef arch_atomic_fetch_and_release +/** + * raw_atomic_fetch_and_release() - atomic bitwise AND with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_and_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_and_release(int i, atomic_t *v) +raw_atomic_fetch_and_release(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_and_release) + return arch_atomic_fetch_and_release(i, v); +#elif defined(arch_atomic_fetch_and_relaxed) __atomic_release_fence(); return arch_atomic_fetch_and_relaxed(i, v); -} -#define arch_atomic_fetch_and_release arch_atomic_fetch_and_release +#elif defined(arch_atomic_fetch_and) + return arch_atomic_fetch_and(i, v); +#else +#error "Unable to define raw_atomic_fetch_and_release" #endif +} -#ifndef arch_atomic_fetch_and +/** + * raw_atomic_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_and_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_and(int i, atomic_t *v) +raw_atomic_fetch_and_relaxed(int i, atomic_t *v) { - int ret; - __atomic_pre_full_fence(); - ret = arch_atomic_fetch_and_relaxed(i, v); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic_fetch_and arch_atomic_fetch_and +#if defined(arch_atomic_fetch_and_relaxed) + return arch_atomic_fetch_and_relaxed(i, v); +#elif defined(arch_atomic_fetch_and) + return arch_atomic_fetch_and(i, v); +#else +#error "Unable to define raw_atomic_fetch_and_relaxed" #endif - -#endif /* arch_atomic_fetch_and_relaxed */ - -#ifndef arch_atomic_andnot -static __always_inline void -arch_atomic_andnot(int i, atomic_t *v) -{ - arch_atomic_and(~i, v); } -#define arch_atomic_andnot arch_atomic_andnot -#endif - -#ifndef arch_atomic_fetch_andnot_relaxed -#ifdef arch_atomic_fetch_andnot -#define arch_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot -#define arch_atomic_fetch_andnot_release arch_atomic_fetch_andnot -#define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot -#endif /* arch_atomic_fetch_andnot */ -#ifndef arch_atomic_fetch_andnot -static __always_inline int -arch_atomic_fetch_andnot(int i, atomic_t *v) +/** + * raw_atomic_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_andnot() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_andnot(int i, atomic_t *v) { - return arch_atomic_fetch_and(~i, v); -} -#define arch_atomic_fetch_andnot arch_atomic_fetch_andnot +#if defined(arch_atomic_andnot) + arch_atomic_andnot(i, v); +#else + raw_atomic_and(~i, v); #endif - -#ifndef arch_atomic_fetch_andnot_acquire -static __always_inline int -arch_atomic_fetch_andnot_acquire(int i, atomic_t *v) -{ - return arch_atomic_fetch_and_acquire(~i, v); } -#define arch_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot_acquire -#endif -#ifndef arch_atomic_fetch_andnot_release +/** + * raw_atomic_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_andnot() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_andnot_release(int i, atomic_t *v) +raw_atomic_fetch_andnot(int i, atomic_t *v) { - return arch_atomic_fetch_and_release(~i, v); -} -#define arch_atomic_fetch_andnot_release arch_atomic_fetch_andnot_release +#if defined(arch_atomic_fetch_andnot) + return arch_atomic_fetch_andnot(i, v); +#elif defined(arch_atomic_fetch_andnot_relaxed) + int ret; + __atomic_pre_full_fence(); + ret = arch_atomic_fetch_andnot_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic_fetch_and(~i, v); #endif - -#ifndef arch_atomic_fetch_andnot_relaxed -static __always_inline int -arch_atomic_fetch_andnot_relaxed(int i, atomic_t *v) -{ - return arch_atomic_fetch_and_relaxed(~i, v); } -#define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot_relaxed -#endif -#else /* arch_atomic_fetch_andnot_relaxed */ - -#ifndef arch_atomic_fetch_andnot_acquire +/** + * raw_atomic_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_andnot_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_andnot_acquire(int i, atomic_t *v) +raw_atomic_fetch_andnot_acquire(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_andnot_acquire) + return arch_atomic_fetch_andnot_acquire(i, v); +#elif defined(arch_atomic_fetch_andnot_relaxed) int ret = arch_atomic_fetch_andnot_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_andnot_acquire arch_atomic_fetch_andnot_acquire +#elif defined(arch_atomic_fetch_andnot) + return arch_atomic_fetch_andnot(i, v); +#else + return raw_atomic_fetch_and_acquire(~i, v); #endif +} -#ifndef arch_atomic_fetch_andnot_release +/** + * raw_atomic_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_andnot_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_andnot_release(int i, atomic_t *v) +raw_atomic_fetch_andnot_release(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_andnot_release) + return arch_atomic_fetch_andnot_release(i, v); +#elif defined(arch_atomic_fetch_andnot_relaxed) __atomic_release_fence(); return arch_atomic_fetch_andnot_relaxed(i, v); +#elif defined(arch_atomic_fetch_andnot) + return arch_atomic_fetch_andnot(i, v); +#else + return raw_atomic_fetch_and_release(~i, v); +#endif } -#define arch_atomic_fetch_andnot_release arch_atomic_fetch_andnot_release + +/** + * raw_atomic_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_andnot_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline int +raw_atomic_fetch_andnot_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_fetch_andnot_relaxed) + return arch_atomic_fetch_andnot_relaxed(i, v); +#elif defined(arch_atomic_fetch_andnot) + return arch_atomic_fetch_andnot(i, v); +#else + return raw_atomic_fetch_and_relaxed(~i, v); #endif +} + +/** + * raw_atomic_or() - atomic bitwise OR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_or() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_or(int i, atomic_t *v) +{ + arch_atomic_or(i, v); +} -#ifndef arch_atomic_fetch_andnot +/** + * raw_atomic_fetch_or() - atomic bitwise OR with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_or() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_andnot(int i, atomic_t *v) +raw_atomic_fetch_or(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_or) + return arch_atomic_fetch_or(i, v); +#elif defined(arch_atomic_fetch_or_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_fetch_andnot_relaxed(i, v); + ret = arch_atomic_fetch_or_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_andnot arch_atomic_fetch_andnot +#else +#error "Unable to define raw_atomic_fetch_or" #endif +} -#endif /* arch_atomic_fetch_andnot_relaxed */ - -#ifndef arch_atomic_fetch_or_relaxed -#define arch_atomic_fetch_or_acquire arch_atomic_fetch_or -#define arch_atomic_fetch_or_release arch_atomic_fetch_or -#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or -#else /* arch_atomic_fetch_or_relaxed */ - -#ifndef arch_atomic_fetch_or_acquire +/** + * raw_atomic_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_or_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_or_acquire(int i, atomic_t *v) +raw_atomic_fetch_or_acquire(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_or_acquire) + return arch_atomic_fetch_or_acquire(i, v); +#elif defined(arch_atomic_fetch_or_relaxed) int ret = arch_atomic_fetch_or_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_or_acquire arch_atomic_fetch_or_acquire +#elif defined(arch_atomic_fetch_or) + return arch_atomic_fetch_or(i, v); +#else +#error "Unable to define raw_atomic_fetch_or_acquire" #endif +} -#ifndef arch_atomic_fetch_or_release +/** + * raw_atomic_fetch_or_release() - atomic bitwise OR with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_or_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_or_release(int i, atomic_t *v) +raw_atomic_fetch_or_release(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_or_release) + return arch_atomic_fetch_or_release(i, v); +#elif defined(arch_atomic_fetch_or_relaxed) __atomic_release_fence(); return arch_atomic_fetch_or_relaxed(i, v); +#elif defined(arch_atomic_fetch_or) + return arch_atomic_fetch_or(i, v); +#else +#error "Unable to define raw_atomic_fetch_or_release" +#endif } -#define arch_atomic_fetch_or_release arch_atomic_fetch_or_release + +/** + * raw_atomic_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_or_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline int +raw_atomic_fetch_or_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_fetch_or_relaxed) + return arch_atomic_fetch_or_relaxed(i, v); +#elif defined(arch_atomic_fetch_or) + return arch_atomic_fetch_or(i, v); +#else +#error "Unable to define raw_atomic_fetch_or_relaxed" #endif +} -#ifndef arch_atomic_fetch_or +/** + * raw_atomic_xor() - atomic bitwise XOR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_xor() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic_xor(int i, atomic_t *v) +{ + arch_atomic_xor(i, v); +} + +/** + * raw_atomic_fetch_xor() - atomic bitwise XOR with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_xor() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_or(int i, atomic_t *v) +raw_atomic_fetch_xor(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_xor) + return arch_atomic_fetch_xor(i, v); +#elif defined(arch_atomic_fetch_xor_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_fetch_or_relaxed(i, v); + ret = arch_atomic_fetch_xor_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_or arch_atomic_fetch_or +#else +#error "Unable to define raw_atomic_fetch_xor" #endif +} -#endif /* arch_atomic_fetch_or_relaxed */ - -#ifndef arch_atomic_fetch_xor_relaxed -#define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor -#define arch_atomic_fetch_xor_release arch_atomic_fetch_xor -#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor -#else /* arch_atomic_fetch_xor_relaxed */ - -#ifndef arch_atomic_fetch_xor_acquire +/** + * raw_atomic_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_xor_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_xor_acquire(int i, atomic_t *v) +raw_atomic_fetch_xor_acquire(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_xor_acquire) + return arch_atomic_fetch_xor_acquire(i, v); +#elif defined(arch_atomic_fetch_xor_relaxed) int ret = arch_atomic_fetch_xor_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_fetch_xor_acquire arch_atomic_fetch_xor_acquire +#elif defined(arch_atomic_fetch_xor) + return arch_atomic_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic_fetch_xor_acquire" #endif +} -#ifndef arch_atomic_fetch_xor_release +/** + * raw_atomic_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_xor_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_xor_release(int i, atomic_t *v) +raw_atomic_fetch_xor_release(int i, atomic_t *v) { +#if defined(arch_atomic_fetch_xor_release) + return arch_atomic_fetch_xor_release(i, v); +#elif defined(arch_atomic_fetch_xor_relaxed) __atomic_release_fence(); return arch_atomic_fetch_xor_relaxed(i, v); +#elif defined(arch_atomic_fetch_xor) + return arch_atomic_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic_fetch_xor_release" +#endif } -#define arch_atomic_fetch_xor_release arch_atomic_fetch_xor_release + +/** + * raw_atomic_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_xor_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline int +raw_atomic_fetch_xor_relaxed(int i, atomic_t *v) +{ +#if defined(arch_atomic_fetch_xor_relaxed) + return arch_atomic_fetch_xor_relaxed(i, v); +#elif defined(arch_atomic_fetch_xor) + return arch_atomic_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic_fetch_xor_relaxed" #endif +} -#ifndef arch_atomic_fetch_xor +/** + * raw_atomic_xchg() - atomic exchange with full ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic_xchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_fetch_xor(int i, atomic_t *v) +raw_atomic_xchg(atomic_t *v, int new) { +#if defined(arch_atomic_xchg) + return arch_atomic_xchg(v, new); +#elif defined(arch_atomic_xchg_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_fetch_xor_relaxed(i, v); + ret = arch_atomic_xchg_relaxed(v, new); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_fetch_xor arch_atomic_fetch_xor +#else + return raw_xchg(&v->counter, new); #endif +} -#endif /* arch_atomic_fetch_xor_relaxed */ - -#ifndef arch_atomic_xchg_relaxed -#define arch_atomic_xchg_acquire arch_atomic_xchg -#define arch_atomic_xchg_release arch_atomic_xchg -#define arch_atomic_xchg_relaxed arch_atomic_xchg -#else /* arch_atomic_xchg_relaxed */ - -#ifndef arch_atomic_xchg_acquire +/** + * raw_atomic_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_xchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_xchg_acquire(atomic_t *v, int i) +raw_atomic_xchg_acquire(atomic_t *v, int new) { - int ret = arch_atomic_xchg_relaxed(v, i); +#if defined(arch_atomic_xchg_acquire) + return arch_atomic_xchg_acquire(v, new); +#elif defined(arch_atomic_xchg_relaxed) + int ret = arch_atomic_xchg_relaxed(v, new); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_xchg_acquire arch_atomic_xchg_acquire +#elif defined(arch_atomic_xchg) + return arch_atomic_xchg(v, new); +#else + return raw_xchg_acquire(&v->counter, new); #endif +} -#ifndef arch_atomic_xchg_release +/** + * raw_atomic_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic_xchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_xchg_release(atomic_t *v, int i) +raw_atomic_xchg_release(atomic_t *v, int new) { +#if defined(arch_atomic_xchg_release) + return arch_atomic_xchg_release(v, new); +#elif defined(arch_atomic_xchg_relaxed) __atomic_release_fence(); - return arch_atomic_xchg_relaxed(v, i); + return arch_atomic_xchg_relaxed(v, new); +#elif defined(arch_atomic_xchg) + return arch_atomic_xchg(v, new); +#else + return raw_xchg_release(&v->counter, new); +#endif } -#define arch_atomic_xchg_release arch_atomic_xchg_release + +/** + * raw_atomic_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_xchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline int +raw_atomic_xchg_relaxed(atomic_t *v, int new) +{ +#if defined(arch_atomic_xchg_relaxed) + return arch_atomic_xchg_relaxed(v, new); +#elif defined(arch_atomic_xchg) + return arch_atomic_xchg(v, new); +#else + return raw_xchg_relaxed(&v->counter, new); #endif +} -#ifndef arch_atomic_xchg +/** + * raw_atomic_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic_cmpxchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_xchg(atomic_t *v, int i) +raw_atomic_cmpxchg(atomic_t *v, int old, int new) { +#if defined(arch_atomic_cmpxchg) + return arch_atomic_cmpxchg(v, old, new); +#elif defined(arch_atomic_cmpxchg_relaxed) int ret; __atomic_pre_full_fence(); - ret = arch_atomic_xchg_relaxed(v, i); + ret = arch_atomic_cmpxchg_relaxed(v, old, new); __atomic_post_full_fence(); return ret; -} -#define arch_atomic_xchg arch_atomic_xchg +#else + return raw_cmpxchg(&v->counter, old, new); #endif +} -#endif /* arch_atomic_xchg_relaxed */ - -#ifndef arch_atomic_cmpxchg_relaxed -#define arch_atomic_cmpxchg_acquire arch_atomic_cmpxchg -#define arch_atomic_cmpxchg_release arch_atomic_cmpxchg -#define arch_atomic_cmpxchg_relaxed arch_atomic_cmpxchg -#else /* arch_atomic_cmpxchg_relaxed */ - -#ifndef arch_atomic_cmpxchg_acquire +/** + * raw_atomic_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_cmpxchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_cmpxchg_acquire(atomic_t *v, int old, int new) +raw_atomic_cmpxchg_acquire(atomic_t *v, int old, int new) { +#if defined(arch_atomic_cmpxchg_acquire) + return arch_atomic_cmpxchg_acquire(v, old, new); +#elif defined(arch_atomic_cmpxchg_relaxed) int ret = arch_atomic_cmpxchg_relaxed(v, old, new); __atomic_acquire_fence(); return ret; -} -#define arch_atomic_cmpxchg_acquire arch_atomic_cmpxchg_acquire +#elif defined(arch_atomic_cmpxchg) + return arch_atomic_cmpxchg(v, old, new); +#else + return raw_cmpxchg_acquire(&v->counter, old, new); #endif +} -#ifndef arch_atomic_cmpxchg_release +/** + * raw_atomic_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic_cmpxchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_cmpxchg_release(atomic_t *v, int old, int new) +raw_atomic_cmpxchg_release(atomic_t *v, int old, int new) { +#if defined(arch_atomic_cmpxchg_release) + return arch_atomic_cmpxchg_release(v, old, new); +#elif defined(arch_atomic_cmpxchg_relaxed) __atomic_release_fence(); return arch_atomic_cmpxchg_relaxed(v, old, new); -} -#define arch_atomic_cmpxchg_release arch_atomic_cmpxchg_release +#elif defined(arch_atomic_cmpxchg) + return arch_atomic_cmpxchg(v, old, new); +#else + return raw_cmpxchg_release(&v->counter, old, new); #endif +} -#ifndef arch_atomic_cmpxchg +/** + * raw_atomic_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_cmpxchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline int -arch_atomic_cmpxchg(atomic_t *v, int old, int new) +raw_atomic_cmpxchg_relaxed(atomic_t *v, int old, int new) { - int ret; - __atomic_pre_full_fence(); - ret = arch_atomic_cmpxchg_relaxed(v, old, new); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic_cmpxchg arch_atomic_cmpxchg +#if defined(arch_atomic_cmpxchg_relaxed) + return arch_atomic_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic_cmpxchg) + return arch_atomic_cmpxchg(v, old, new); +#else + return raw_cmpxchg_relaxed(&v->counter, old, new); #endif +} -#endif /* arch_atomic_cmpxchg_relaxed */ - -#ifndef arch_atomic_try_cmpxchg_relaxed -#ifdef arch_atomic_try_cmpxchg -#define arch_atomic_try_cmpxchg_acquire arch_atomic_try_cmpxchg -#define arch_atomic_try_cmpxchg_release arch_atomic_try_cmpxchg -#define arch_atomic_try_cmpxchg_relaxed arch_atomic_try_cmpxchg -#endif /* arch_atomic_try_cmpxchg */ - -#ifndef arch_atomic_try_cmpxchg +/** + * raw_atomic_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_try_cmpxchg() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_try_cmpxchg(atomic_t *v, int *old, int new) +raw_atomic_try_cmpxchg(atomic_t *v, int *old, int new) { +#if defined(arch_atomic_try_cmpxchg) + return arch_atomic_try_cmpxchg(v, old, new); +#elif defined(arch_atomic_try_cmpxchg_relaxed) + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic_try_cmpxchg_relaxed(v, old, new); + __atomic_post_full_fence(); + return ret; +#else int r, o = *old; - r = arch_atomic_cmpxchg(v, o, new); + r = raw_atomic_cmpxchg(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic_try_cmpxchg arch_atomic_try_cmpxchg #endif +} -#ifndef arch_atomic_try_cmpxchg_acquire +/** + * raw_atomic_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_try_cmpxchg_acquire() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new) +raw_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new) { +#if defined(arch_atomic_try_cmpxchg_acquire) + return arch_atomic_try_cmpxchg_acquire(v, old, new); +#elif defined(arch_atomic_try_cmpxchg_relaxed) + bool ret = arch_atomic_try_cmpxchg_relaxed(v, old, new); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic_try_cmpxchg) + return arch_atomic_try_cmpxchg(v, old, new); +#else int r, o = *old; - r = arch_atomic_cmpxchg_acquire(v, o, new); + r = raw_atomic_cmpxchg_acquire(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic_try_cmpxchg_acquire arch_atomic_try_cmpxchg_acquire #endif +} -#ifndef arch_atomic_try_cmpxchg_release +/** + * raw_atomic_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_try_cmpxchg_release() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new) +raw_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new) { +#if defined(arch_atomic_try_cmpxchg_release) + return arch_atomic_try_cmpxchg_release(v, old, new); +#elif defined(arch_atomic_try_cmpxchg_relaxed) + __atomic_release_fence(); + return arch_atomic_try_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic_try_cmpxchg) + return arch_atomic_try_cmpxchg(v, old, new); +#else int r, o = *old; - r = arch_atomic_cmpxchg_release(v, o, new); + r = raw_atomic_cmpxchg_release(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic_try_cmpxchg_release arch_atomic_try_cmpxchg_release #endif +} -#ifndef arch_atomic_try_cmpxchg_relaxed +/** + * raw_atomic_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_try_cmpxchg_relaxed() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new) +raw_atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new) { +#if defined(arch_atomic_try_cmpxchg_relaxed) + return arch_atomic_try_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic_try_cmpxchg) + return arch_atomic_try_cmpxchg(v, old, new); +#else int r, o = *old; - r = arch_atomic_cmpxchg_relaxed(v, o, new); + r = raw_atomic_cmpxchg_relaxed(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic_try_cmpxchg_relaxed arch_atomic_try_cmpxchg_relaxed -#endif - -#else /* arch_atomic_try_cmpxchg_relaxed */ - -#ifndef arch_atomic_try_cmpxchg_acquire -static __always_inline bool -arch_atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new) -{ - bool ret = arch_atomic_try_cmpxchg_relaxed(v, old, new); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic_try_cmpxchg_acquire arch_atomic_try_cmpxchg_acquire #endif - -#ifndef arch_atomic_try_cmpxchg_release -static __always_inline bool -arch_atomic_try_cmpxchg_release(atomic_t *v, int *old, int new) -{ - __atomic_release_fence(); - return arch_atomic_try_cmpxchg_relaxed(v, old, new); } -#define arch_atomic_try_cmpxchg_release arch_atomic_try_cmpxchg_release -#endif -#ifndef arch_atomic_try_cmpxchg -static __always_inline bool -arch_atomic_try_cmpxchg(atomic_t *v, int *old, int new) -{ - bool ret; - __atomic_pre_full_fence(); - ret = arch_atomic_try_cmpxchg_relaxed(v, old, new); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic_try_cmpxchg arch_atomic_try_cmpxchg -#endif - -#endif /* arch_atomic_try_cmpxchg_relaxed */ - -#ifndef arch_atomic_sub_and_test /** - * arch_atomic_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @v: pointer of type atomic_t + * raw_atomic_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. * - * Atomically subtracts @i from @v and returns - * true if the result is zero, or false for all - * other cases. + * Safe to use in noinstr code; prefer atomic_sub_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic_sub_and_test(int i, atomic_t *v) +raw_atomic_sub_and_test(int i, atomic_t *v) { - return arch_atomic_sub_return(i, v) == 0; -} -#define arch_atomic_sub_and_test arch_atomic_sub_and_test +#if defined(arch_atomic_sub_and_test) + return arch_atomic_sub_and_test(i, v); +#else + return raw_atomic_sub_return(i, v) == 0; #endif +} -#ifndef arch_atomic_dec_and_test /** - * arch_atomic_dec_and_test - decrement and test - * @v: pointer of type atomic_t + * raw_atomic_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic_t * - * Atomically decrements @v by 1 and - * returns true if the result is 0, or false for all other - * cases. + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic_dec_and_test(atomic_t *v) +raw_atomic_dec_and_test(atomic_t *v) { - return arch_atomic_dec_return(v) == 0; -} -#define arch_atomic_dec_and_test arch_atomic_dec_and_test +#if defined(arch_atomic_dec_and_test) + return arch_atomic_dec_and_test(v); +#else + return raw_atomic_dec_return(v) == 0; #endif +} -#ifndef arch_atomic_inc_and_test /** - * arch_atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t + * raw_atomic_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic_t * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic_inc_and_test(atomic_t *v) +raw_atomic_inc_and_test(atomic_t *v) { - return arch_atomic_inc_return(v) == 0; -} -#define arch_atomic_inc_and_test arch_atomic_inc_and_test +#if defined(arch_atomic_inc_and_test) + return arch_atomic_inc_and_test(v); +#else + return raw_atomic_inc_return(v) == 0; #endif +} -#ifndef arch_atomic_add_negative_relaxed -#ifdef arch_atomic_add_negative -#define arch_atomic_add_negative_acquire arch_atomic_add_negative -#define arch_atomic_add_negative_release arch_atomic_add_negative -#define arch_atomic_add_negative_relaxed arch_atomic_add_negative -#endif /* arch_atomic_add_negative */ - -#ifndef arch_atomic_add_negative /** - * arch_atomic_add_negative - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic_t + * raw_atomic_add_negative() - atomic add and test if negative with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_add_negative() elsewhere. * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic_add_negative(int i, atomic_t *v) +raw_atomic_add_negative(int i, atomic_t *v) { - return arch_atomic_add_return(i, v) < 0; -} -#define arch_atomic_add_negative arch_atomic_add_negative +#if defined(arch_atomic_add_negative) + return arch_atomic_add_negative(i, v); +#elif defined(arch_atomic_add_negative_relaxed) + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic_add_negative_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic_add_return(i, v) < 0; #endif +} -#ifndef arch_atomic_add_negative_acquire /** - * arch_atomic_add_negative_acquire - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic_t + * raw_atomic_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_add_negative_acquire() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic_add_negative_acquire(int i, atomic_t *v) +raw_atomic_add_negative_acquire(int i, atomic_t *v) { - return arch_atomic_add_return_acquire(i, v) < 0; -} -#define arch_atomic_add_negative_acquire arch_atomic_add_negative_acquire +#if defined(arch_atomic_add_negative_acquire) + return arch_atomic_add_negative_acquire(i, v); +#elif defined(arch_atomic_add_negative_relaxed) + bool ret = arch_atomic_add_negative_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic_add_negative) + return arch_atomic_add_negative(i, v); +#else + return raw_atomic_add_return_acquire(i, v) < 0; #endif +} -#ifndef arch_atomic_add_negative_release /** - * arch_atomic_add_negative_release - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic_t + * raw_atomic_add_negative_release() - atomic add and test if negative with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_add_negative_release() elsewhere. * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic_add_negative_release(int i, atomic_t *v) +raw_atomic_add_negative_release(int i, atomic_t *v) { - return arch_atomic_add_return_release(i, v) < 0; -} -#define arch_atomic_add_negative_release arch_atomic_add_negative_release +#if defined(arch_atomic_add_negative_release) + return arch_atomic_add_negative_release(i, v); +#elif defined(arch_atomic_add_negative_relaxed) + __atomic_release_fence(); + return arch_atomic_add_negative_relaxed(i, v); +#elif defined(arch_atomic_add_negative) + return arch_atomic_add_negative(i, v); +#else + return raw_atomic_add_return_release(i, v) < 0; #endif +} -#ifndef arch_atomic_add_negative_relaxed /** - * arch_atomic_add_negative_relaxed - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic_t + * raw_atomic_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_add_negative_relaxed() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic_add_negative_relaxed(int i, atomic_t *v) -{ - return arch_atomic_add_return_relaxed(i, v) < 0; -} -#define arch_atomic_add_negative_relaxed arch_atomic_add_negative_relaxed -#endif - -#else /* arch_atomic_add_negative_relaxed */ - -#ifndef arch_atomic_add_negative_acquire -static __always_inline bool -arch_atomic_add_negative_acquire(int i, atomic_t *v) +raw_atomic_add_negative_relaxed(int i, atomic_t *v) { - bool ret = arch_atomic_add_negative_relaxed(i, v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic_add_negative_acquire arch_atomic_add_negative_acquire -#endif - -#ifndef arch_atomic_add_negative_release -static __always_inline bool -arch_atomic_add_negative_release(int i, atomic_t *v) -{ - __atomic_release_fence(); +#if defined(arch_atomic_add_negative_relaxed) return arch_atomic_add_negative_relaxed(i, v); -} -#define arch_atomic_add_negative_release arch_atomic_add_negative_release +#elif defined(arch_atomic_add_negative) + return arch_atomic_add_negative(i, v); +#else + return raw_atomic_add_return_relaxed(i, v) < 0; #endif - -#ifndef arch_atomic_add_negative -static __always_inline bool -arch_atomic_add_negative(int i, atomic_t *v) -{ - bool ret; - __atomic_pre_full_fence(); - ret = arch_atomic_add_negative_relaxed(i, v); - __atomic_post_full_fence(); - return ret; } -#define arch_atomic_add_negative arch_atomic_add_negative -#endif -#endif /* arch_atomic_add_negative_relaxed */ - -#ifndef arch_atomic_fetch_add_unless /** - * arch_atomic_fetch_add_unless - add unless the number is already a given value - * @v: pointer of type atomic_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. + * raw_atomic_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_t + * @a: int value to add + * @u: int value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_fetch_add_unless() elsewhere. * - * Atomically adds @a to @v, so long as @v was not already @u. - * Returns original value of @v + * Return: The original value of @v. */ static __always_inline int -arch_atomic_fetch_add_unless(atomic_t *v, int a, int u) +raw_atomic_fetch_add_unless(atomic_t *v, int a, int u) { - int c = arch_atomic_read(v); +#if defined(arch_atomic_fetch_add_unless) + return arch_atomic_fetch_add_unless(v, a, u); +#else + int c = raw_atomic_read(v); do { if (unlikely(c == u)) break; - } while (!arch_atomic_try_cmpxchg(v, &c, c + a)); + } while (!raw_atomic_try_cmpxchg(v, &c, c + a)); return c; -} -#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless #endif +} -#ifndef arch_atomic_add_unless /** - * arch_atomic_add_unless - add unless the number is already a given value - * @v: pointer of type atomic_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. + * raw_atomic_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_t + * @a: int value to add + * @u: int value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_add_unless() elsewhere. * - * Atomically adds @a to @v, if @v was not already @u. - * Returns true if the addition was done. + * Return: @true if @v was updated, @false otherwise. */ static __always_inline bool -arch_atomic_add_unless(atomic_t *v, int a, int u) +raw_atomic_add_unless(atomic_t *v, int a, int u) { - return arch_atomic_fetch_add_unless(v, a, u) != u; -} -#define arch_atomic_add_unless arch_atomic_add_unless +#if defined(arch_atomic_add_unless) + return arch_atomic_add_unless(v, a, u); +#else + return raw_atomic_fetch_add_unless(v, a, u) != u; #endif +} -#ifndef arch_atomic_inc_not_zero /** - * arch_atomic_inc_not_zero - increment unless the number is zero - * @v: pointer of type atomic_t + * raw_atomic_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. * - * Atomically increments @v by 1, if @v is non-zero. - * Returns true if the increment was done. + * Safe to use in noinstr code; prefer atomic_inc_not_zero() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. */ static __always_inline bool -arch_atomic_inc_not_zero(atomic_t *v) +raw_atomic_inc_not_zero(atomic_t *v) { - return arch_atomic_add_unless(v, 1, 0); -} -#define arch_atomic_inc_not_zero arch_atomic_inc_not_zero +#if defined(arch_atomic_inc_not_zero) + return arch_atomic_inc_not_zero(v); +#else + return raw_atomic_add_unless(v, 1, 0); #endif +} -#ifndef arch_atomic_inc_unless_negative +/** + * raw_atomic_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_inc_unless_negative() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_inc_unless_negative(atomic_t *v) +raw_atomic_inc_unless_negative(atomic_t *v) { - int c = arch_atomic_read(v); +#if defined(arch_atomic_inc_unless_negative) + return arch_atomic_inc_unless_negative(v); +#else + int c = raw_atomic_read(v); do { if (unlikely(c < 0)) return false; - } while (!arch_atomic_try_cmpxchg(v, &c, c + 1)); + } while (!raw_atomic_try_cmpxchg(v, &c, c + 1)); return true; -} -#define arch_atomic_inc_unless_negative arch_atomic_inc_unless_negative #endif +} -#ifndef arch_atomic_dec_unless_positive +/** + * raw_atomic_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_unless_positive() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_dec_unless_positive(atomic_t *v) +raw_atomic_dec_unless_positive(atomic_t *v) { - int c = arch_atomic_read(v); +#if defined(arch_atomic_dec_unless_positive) + return arch_atomic_dec_unless_positive(v); +#else + int c = raw_atomic_read(v); do { if (unlikely(c > 0)) return false; - } while (!arch_atomic_try_cmpxchg(v, &c, c - 1)); + } while (!raw_atomic_try_cmpxchg(v, &c, c - 1)); return true; -} -#define arch_atomic_dec_unless_positive arch_atomic_dec_unless_positive #endif +} -#ifndef arch_atomic_dec_if_positive +/** + * raw_atomic_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_dec_if_positive() elsewhere. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline int -arch_atomic_dec_if_positive(atomic_t *v) +raw_atomic_dec_if_positive(atomic_t *v) { - int dec, c = arch_atomic_read(v); +#if defined(arch_atomic_dec_if_positive) + return arch_atomic_dec_if_positive(v); +#else + int dec, c = raw_atomic_read(v); do { dec = c - 1; if (unlikely(dec < 0)) break; - } while (!arch_atomic_try_cmpxchg(v, &c, dec)); + } while (!raw_atomic_try_cmpxchg(v, &c, dec)); return dec; -} -#define arch_atomic_dec_if_positive arch_atomic_dec_if_positive #endif +} #ifdef CONFIG_GENERIC_ATOMIC64 #include <asm-generic/atomic64.h> #endif -#ifndef arch_atomic64_read_acquire +/** + * raw_atomic64_read() - atomic load with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_read() elsewhere. + * + * Return: The value loaded from @v. + */ static __always_inline s64 -arch_atomic64_read_acquire(const atomic64_t *v) +raw_atomic64_read(const atomic64_t *v) { + return arch_atomic64_read(v); +} + +/** + * raw_atomic64_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_read_acquire() elsewhere. + * + * Return: The value loaded from @v. + */ +static __always_inline s64 +raw_atomic64_read_acquire(const atomic64_t *v) +{ +#if defined(arch_atomic64_read_acquire) + return arch_atomic64_read_acquire(v); +#elif defined(arch_atomic64_read) + return arch_atomic64_read(v); +#else s64 ret; if (__native_word(atomic64_t)) { ret = smp_load_acquire(&(v)->counter); } else { - ret = arch_atomic64_read(v); + ret = raw_atomic64_read(v); __atomic_acquire_fence(); } return ret; -} -#define arch_atomic64_read_acquire arch_atomic64_read_acquire #endif +} -#ifndef arch_atomic64_set_release +/** + * raw_atomic64_set() - atomic set with relaxed ordering + * @v: pointer to atomic64_t + * @i: s64 value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_set() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_set(atomic64_t *v, s64 i) +{ + arch_atomic64_set(v, i); +} + +/** + * raw_atomic64_set_release() - atomic set with release ordering + * @v: pointer to atomic64_t + * @i: s64 value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_set_release() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic64_set_release(atomic64_t *v, s64 i) +raw_atomic64_set_release(atomic64_t *v, s64 i) { +#if defined(arch_atomic64_set_release) + arch_atomic64_set_release(v, i); +#elif defined(arch_atomic64_set) + arch_atomic64_set(v, i); +#else if (__native_word(atomic64_t)) { smp_store_release(&(v)->counter, i); } else { __atomic_release_fence(); - arch_atomic64_set(v, i); + raw_atomic64_set(v, i); } -} -#define arch_atomic64_set_release arch_atomic64_set_release #endif - -#ifndef arch_atomic64_add_return_relaxed -#define arch_atomic64_add_return_acquire arch_atomic64_add_return -#define arch_atomic64_add_return_release arch_atomic64_add_return -#define arch_atomic64_add_return_relaxed arch_atomic64_add_return -#else /* arch_atomic64_add_return_relaxed */ - -#ifndef arch_atomic64_add_return_acquire -static __always_inline s64 -arch_atomic64_add_return_acquire(s64 i, atomic64_t *v) -{ - s64 ret = arch_atomic64_add_return_relaxed(i, v); - __atomic_acquire_fence(); - return ret; } -#define arch_atomic64_add_return_acquire arch_atomic64_add_return_acquire -#endif -#ifndef arch_atomic64_add_return_release -static __always_inline s64 -arch_atomic64_add_return_release(s64 i, atomic64_t *v) +/** + * raw_atomic64_add() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_add() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_add(s64 i, atomic64_t *v) { - __atomic_release_fence(); - return arch_atomic64_add_return_relaxed(i, v); + arch_atomic64_add(i, v); } -#define arch_atomic64_add_return_release arch_atomic64_add_return_release -#endif -#ifndef arch_atomic64_add_return +/** + * raw_atomic64_add_return() - atomic add with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_add_return(s64 i, atomic64_t *v) +raw_atomic64_add_return(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_add_return) + return arch_atomic64_add_return(i, v); +#elif defined(arch_atomic64_add_return_relaxed) s64 ret; __atomic_pre_full_fence(); ret = arch_atomic64_add_return_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_add_return arch_atomic64_add_return +#else +#error "Unable to define raw_atomic64_add_return" #endif +} -#endif /* arch_atomic64_add_return_relaxed */ - -#ifndef arch_atomic64_fetch_add_relaxed -#define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add -#define arch_atomic64_fetch_add_release arch_atomic64_fetch_add -#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add -#else /* arch_atomic64_fetch_add_relaxed */ - -#ifndef arch_atomic64_fetch_add_acquire +/** + * raw_atomic64_add_return_acquire() - atomic add with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_add_acquire(s64 i, atomic64_t *v) +raw_atomic64_add_return_acquire(s64 i, atomic64_t *v) { - s64 ret = arch_atomic64_fetch_add_relaxed(i, v); +#if defined(arch_atomic64_add_return_acquire) + return arch_atomic64_add_return_acquire(i, v); +#elif defined(arch_atomic64_add_return_relaxed) + s64 ret = arch_atomic64_add_return_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_add_acquire arch_atomic64_fetch_add_acquire +#elif defined(arch_atomic64_add_return) + return arch_atomic64_add_return(i, v); +#else +#error "Unable to define raw_atomic64_add_return_acquire" #endif +} -#ifndef arch_atomic64_fetch_add_release +/** + * raw_atomic64_add_return_release() - atomic add with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_add_release(s64 i, atomic64_t *v) +raw_atomic64_add_return_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_add_return_release) + return arch_atomic64_add_return_release(i, v); +#elif defined(arch_atomic64_add_return_relaxed) __atomic_release_fence(); - return arch_atomic64_fetch_add_relaxed(i, v); + return arch_atomic64_add_return_relaxed(i, v); +#elif defined(arch_atomic64_add_return) + return arch_atomic64_add_return(i, v); +#else +#error "Unable to define raw_atomic64_add_return_release" +#endif } -#define arch_atomic64_fetch_add_release arch_atomic64_fetch_add_release + +/** + * raw_atomic64_add_return_relaxed() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline s64 +raw_atomic64_add_return_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_add_return_relaxed) + return arch_atomic64_add_return_relaxed(i, v); +#elif defined(arch_atomic64_add_return) + return arch_atomic64_add_return(i, v); +#else +#error "Unable to define raw_atomic64_add_return_relaxed" #endif +} -#ifndef arch_atomic64_fetch_add +/** + * raw_atomic64_fetch_add() - atomic add with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_add() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_add(s64 i, atomic64_t *v) +raw_atomic64_fetch_add(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_add) + return arch_atomic64_fetch_add(i, v); +#elif defined(arch_atomic64_fetch_add_relaxed) s64 ret; __atomic_pre_full_fence(); ret = arch_atomic64_fetch_add_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_add arch_atomic64_fetch_add +#else +#error "Unable to define raw_atomic64_fetch_add" #endif +} -#endif /* arch_atomic64_fetch_add_relaxed */ - -#ifndef arch_atomic64_sub_return_relaxed -#define arch_atomic64_sub_return_acquire arch_atomic64_sub_return -#define arch_atomic64_sub_return_release arch_atomic64_sub_return -#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return -#else /* arch_atomic64_sub_return_relaxed */ - -#ifndef arch_atomic64_sub_return_acquire +/** + * raw_atomic64_fetch_add_acquire() - atomic add with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_add_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_sub_return_acquire(s64 i, atomic64_t *v) +raw_atomic64_fetch_add_acquire(s64 i, atomic64_t *v) { - s64 ret = arch_atomic64_sub_return_relaxed(i, v); +#if defined(arch_atomic64_fetch_add_acquire) + return arch_atomic64_fetch_add_acquire(i, v); +#elif defined(arch_atomic64_fetch_add_relaxed) + s64 ret = arch_atomic64_fetch_add_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_sub_return_acquire arch_atomic64_sub_return_acquire +#elif defined(arch_atomic64_fetch_add) + return arch_atomic64_fetch_add(i, v); +#else +#error "Unable to define raw_atomic64_fetch_add_acquire" #endif +} -#ifndef arch_atomic64_sub_return_release +/** + * raw_atomic64_fetch_add_release() - atomic add with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_add_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_sub_return_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_add_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_add_release) + return arch_atomic64_fetch_add_release(i, v); +#elif defined(arch_atomic64_fetch_add_relaxed) __atomic_release_fence(); - return arch_atomic64_sub_return_relaxed(i, v); + return arch_atomic64_fetch_add_relaxed(i, v); +#elif defined(arch_atomic64_fetch_add) + return arch_atomic64_fetch_add(i, v); +#else +#error "Unable to define raw_atomic64_fetch_add_release" +#endif } -#define arch_atomic64_sub_return_release arch_atomic64_sub_return_release + +/** + * raw_atomic64_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_add_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline s64 +raw_atomic64_fetch_add_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_fetch_add_relaxed) + return arch_atomic64_fetch_add_relaxed(i, v); +#elif defined(arch_atomic64_fetch_add) + return arch_atomic64_fetch_add(i, v); +#else +#error "Unable to define raw_atomic64_fetch_add_relaxed" #endif +} + +/** + * raw_atomic64_sub() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_sub(s64 i, atomic64_t *v) +{ + arch_atomic64_sub(i, v); +} -#ifndef arch_atomic64_sub_return +/** + * raw_atomic64_sub_return() - atomic subtract with full ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_sub_return(s64 i, atomic64_t *v) +raw_atomic64_sub_return(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_sub_return) + return arch_atomic64_sub_return(i, v); +#elif defined(arch_atomic64_sub_return_relaxed) s64 ret; __atomic_pre_full_fence(); ret = arch_atomic64_sub_return_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_sub_return arch_atomic64_sub_return +#else +#error "Unable to define raw_atomic64_sub_return" #endif +} -#endif /* arch_atomic64_sub_return_relaxed */ - -#ifndef arch_atomic64_fetch_sub_relaxed -#define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub -#define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub -#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub -#else /* arch_atomic64_fetch_sub_relaxed */ - -#ifndef arch_atomic64_fetch_sub_acquire +/** + * raw_atomic64_sub_return_acquire() - atomic subtract with acquire ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_sub_acquire(s64 i, atomic64_t *v) +raw_atomic64_sub_return_acquire(s64 i, atomic64_t *v) { - s64 ret = arch_atomic64_fetch_sub_relaxed(i, v); +#if defined(arch_atomic64_sub_return_acquire) + return arch_atomic64_sub_return_acquire(i, v); +#elif defined(arch_atomic64_sub_return_relaxed) + s64 ret = arch_atomic64_sub_return_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_sub_acquire arch_atomic64_fetch_sub_acquire +#elif defined(arch_atomic64_sub_return) + return arch_atomic64_sub_return(i, v); +#else +#error "Unable to define raw_atomic64_sub_return_acquire" #endif +} -#ifndef arch_atomic64_fetch_sub_release +/** + * raw_atomic64_sub_return_release() - atomic subtract with release ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_sub_release(s64 i, atomic64_t *v) +raw_atomic64_sub_return_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_sub_return_release) + return arch_atomic64_sub_return_release(i, v); +#elif defined(arch_atomic64_sub_return_relaxed) __atomic_release_fence(); - return arch_atomic64_fetch_sub_relaxed(i, v); + return arch_atomic64_sub_return_relaxed(i, v); +#elif defined(arch_atomic64_sub_return) + return arch_atomic64_sub_return(i, v); +#else +#error "Unable to define raw_atomic64_sub_return_release" +#endif } -#define arch_atomic64_fetch_sub_release arch_atomic64_fetch_sub_release + +/** + * raw_atomic64_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline s64 +raw_atomic64_sub_return_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_sub_return_relaxed) + return arch_atomic64_sub_return_relaxed(i, v); +#elif defined(arch_atomic64_sub_return) + return arch_atomic64_sub_return(i, v); +#else +#error "Unable to define raw_atomic64_sub_return_relaxed" #endif +} -#ifndef arch_atomic64_fetch_sub +/** + * raw_atomic64_fetch_sub() - atomic subtract with full ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_sub() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_sub(s64 i, atomic64_t *v) +raw_atomic64_fetch_sub(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_sub) + return arch_atomic64_fetch_sub(i, v); +#elif defined(arch_atomic64_fetch_sub_relaxed) s64 ret; __atomic_pre_full_fence(); ret = arch_atomic64_fetch_sub_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_sub arch_atomic64_fetch_sub +#else +#error "Unable to define raw_atomic64_fetch_sub" #endif - -#endif /* arch_atomic64_fetch_sub_relaxed */ - -#ifndef arch_atomic64_inc -static __always_inline void -arch_atomic64_inc(atomic64_t *v) -{ - arch_atomic64_add(1, v); } -#define arch_atomic64_inc arch_atomic64_inc -#endif - -#ifndef arch_atomic64_inc_return_relaxed -#ifdef arch_atomic64_inc_return -#define arch_atomic64_inc_return_acquire arch_atomic64_inc_return -#define arch_atomic64_inc_return_release arch_atomic64_inc_return -#define arch_atomic64_inc_return_relaxed arch_atomic64_inc_return -#endif /* arch_atomic64_inc_return */ -#ifndef arch_atomic64_inc_return +/** + * raw_atomic64_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_sub_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_inc_return(atomic64_t *v) +raw_atomic64_fetch_sub_acquire(s64 i, atomic64_t *v) { - return arch_atomic64_add_return(1, v); -} -#define arch_atomic64_inc_return arch_atomic64_inc_return +#if defined(arch_atomic64_fetch_sub_acquire) + return arch_atomic64_fetch_sub_acquire(i, v); +#elif defined(arch_atomic64_fetch_sub_relaxed) + s64 ret = arch_atomic64_fetch_sub_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic64_fetch_sub) + return arch_atomic64_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic64_fetch_sub_acquire" #endif - -#ifndef arch_atomic64_inc_return_acquire -static __always_inline s64 -arch_atomic64_inc_return_acquire(atomic64_t *v) -{ - return arch_atomic64_add_return_acquire(1, v); } -#define arch_atomic64_inc_return_acquire arch_atomic64_inc_return_acquire -#endif -#ifndef arch_atomic64_inc_return_release +/** + * raw_atomic64_fetch_sub_release() - atomic subtract with release ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_sub_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_inc_return_release(atomic64_t *v) +raw_atomic64_fetch_sub_release(s64 i, atomic64_t *v) { - return arch_atomic64_add_return_release(1, v); -} -#define arch_atomic64_inc_return_release arch_atomic64_inc_return_release +#if defined(arch_atomic64_fetch_sub_release) + return arch_atomic64_fetch_sub_release(i, v); +#elif defined(arch_atomic64_fetch_sub_relaxed) + __atomic_release_fence(); + return arch_atomic64_fetch_sub_relaxed(i, v); +#elif defined(arch_atomic64_fetch_sub) + return arch_atomic64_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic64_fetch_sub_release" #endif - -#ifndef arch_atomic64_inc_return_relaxed -static __always_inline s64 -arch_atomic64_inc_return_relaxed(atomic64_t *v) -{ - return arch_atomic64_add_return_relaxed(1, v); } -#define arch_atomic64_inc_return_relaxed arch_atomic64_inc_return_relaxed -#endif -#else /* arch_atomic64_inc_return_relaxed */ - -#ifndef arch_atomic64_inc_return_acquire +/** + * raw_atomic64_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_sub_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_inc_return_acquire(atomic64_t *v) +raw_atomic64_fetch_sub_relaxed(s64 i, atomic64_t *v) { - s64 ret = arch_atomic64_inc_return_relaxed(v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic64_inc_return_acquire arch_atomic64_inc_return_acquire +#if defined(arch_atomic64_fetch_sub_relaxed) + return arch_atomic64_fetch_sub_relaxed(i, v); +#elif defined(arch_atomic64_fetch_sub) + return arch_atomic64_fetch_sub(i, v); +#else +#error "Unable to define raw_atomic64_fetch_sub_relaxed" #endif +} -#ifndef arch_atomic64_inc_return_release -static __always_inline s64 -arch_atomic64_inc_return_release(atomic64_t *v) +/** + * raw_atomic64_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_inc(atomic64_t *v) { - __atomic_release_fence(); - return arch_atomic64_inc_return_relaxed(v); -} -#define arch_atomic64_inc_return_release arch_atomic64_inc_return_release +#if defined(arch_atomic64_inc) + arch_atomic64_inc(v); +#else + raw_atomic64_add(1, v); #endif +} -#ifndef arch_atomic64_inc_return +/** + * raw_atomic64_inc_return() - atomic increment with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_inc_return(atomic64_t *v) +raw_atomic64_inc_return(atomic64_t *v) { +#if defined(arch_atomic64_inc_return) + return arch_atomic64_inc_return(v); +#elif defined(arch_atomic64_inc_return_relaxed) s64 ret; __atomic_pre_full_fence(); ret = arch_atomic64_inc_return_relaxed(v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_inc_return arch_atomic64_inc_return +#else + return raw_atomic64_add_return(1, v); #endif +} -#endif /* arch_atomic64_inc_return_relaxed */ - -#ifndef arch_atomic64_fetch_inc_relaxed -#ifdef arch_atomic64_fetch_inc -#define arch_atomic64_fetch_inc_acquire arch_atomic64_fetch_inc -#define arch_atomic64_fetch_inc_release arch_atomic64_fetch_inc -#define arch_atomic64_fetch_inc_relaxed arch_atomic64_fetch_inc -#endif /* arch_atomic64_fetch_inc */ - -#ifndef arch_atomic64_fetch_inc +/** + * raw_atomic64_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc(atomic64_t *v) +raw_atomic64_inc_return_acquire(atomic64_t *v) { - return arch_atomic64_fetch_add(1, v); -} -#define arch_atomic64_fetch_inc arch_atomic64_fetch_inc +#if defined(arch_atomic64_inc_return_acquire) + return arch_atomic64_inc_return_acquire(v); +#elif defined(arch_atomic64_inc_return_relaxed) + s64 ret = arch_atomic64_inc_return_relaxed(v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic64_inc_return) + return arch_atomic64_inc_return(v); +#else + return raw_atomic64_add_return_acquire(1, v); #endif +} -#ifndef arch_atomic64_fetch_inc_acquire +/** + * raw_atomic64_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc_acquire(atomic64_t *v) +raw_atomic64_inc_return_release(atomic64_t *v) { - return arch_atomic64_fetch_add_acquire(1, v); -} -#define arch_atomic64_fetch_inc_acquire arch_atomic64_fetch_inc_acquire +#if defined(arch_atomic64_inc_return_release) + return arch_atomic64_inc_return_release(v); +#elif defined(arch_atomic64_inc_return_relaxed) + __atomic_release_fence(); + return arch_atomic64_inc_return_relaxed(v); +#elif defined(arch_atomic64_inc_return) + return arch_atomic64_inc_return(v); +#else + return raw_atomic64_add_return_release(1, v); #endif +} -#ifndef arch_atomic64_fetch_inc_release +/** + * raw_atomic64_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc_release(atomic64_t *v) +raw_atomic64_inc_return_relaxed(atomic64_t *v) { - return arch_atomic64_fetch_add_release(1, v); -} -#define arch_atomic64_fetch_inc_release arch_atomic64_fetch_inc_release +#if defined(arch_atomic64_inc_return_relaxed) + return arch_atomic64_inc_return_relaxed(v); +#elif defined(arch_atomic64_inc_return) + return arch_atomic64_inc_return(v); +#else + return raw_atomic64_add_return_relaxed(1, v); #endif +} -#ifndef arch_atomic64_fetch_inc_relaxed +/** + * raw_atomic64_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_inc() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc_relaxed(atomic64_t *v) +raw_atomic64_fetch_inc(atomic64_t *v) { - return arch_atomic64_fetch_add_relaxed(1, v); -} -#define arch_atomic64_fetch_inc_relaxed arch_atomic64_fetch_inc_relaxed +#if defined(arch_atomic64_fetch_inc) + return arch_atomic64_fetch_inc(v); +#elif defined(arch_atomic64_fetch_inc_relaxed) + s64 ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_fetch_inc_relaxed(v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic64_fetch_add(1, v); #endif +} -#else /* arch_atomic64_fetch_inc_relaxed */ - -#ifndef arch_atomic64_fetch_inc_acquire +/** + * raw_atomic64_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_inc_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc_acquire(atomic64_t *v) +raw_atomic64_fetch_inc_acquire(atomic64_t *v) { +#if defined(arch_atomic64_fetch_inc_acquire) + return arch_atomic64_fetch_inc_acquire(v); +#elif defined(arch_atomic64_fetch_inc_relaxed) s64 ret = arch_atomic64_fetch_inc_relaxed(v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_inc_acquire arch_atomic64_fetch_inc_acquire +#elif defined(arch_atomic64_fetch_inc) + return arch_atomic64_fetch_inc(v); +#else + return raw_atomic64_fetch_add_acquire(1, v); #endif +} -#ifndef arch_atomic64_fetch_inc_release +/** + * raw_atomic64_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_inc_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc_release(atomic64_t *v) +raw_atomic64_fetch_inc_release(atomic64_t *v) { +#if defined(arch_atomic64_fetch_inc_release) + return arch_atomic64_fetch_inc_release(v); +#elif defined(arch_atomic64_fetch_inc_relaxed) __atomic_release_fence(); return arch_atomic64_fetch_inc_relaxed(v); -} -#define arch_atomic64_fetch_inc_release arch_atomic64_fetch_inc_release +#elif defined(arch_atomic64_fetch_inc) + return arch_atomic64_fetch_inc(v); +#else + return raw_atomic64_fetch_add_release(1, v); #endif +} -#ifndef arch_atomic64_fetch_inc +/** + * raw_atomic64_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_inc_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_inc(atomic64_t *v) +raw_atomic64_fetch_inc_relaxed(atomic64_t *v) { - s64 ret; - __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_inc_relaxed(v); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic64_fetch_inc arch_atomic64_fetch_inc +#if defined(arch_atomic64_fetch_inc_relaxed) + return arch_atomic64_fetch_inc_relaxed(v); +#elif defined(arch_atomic64_fetch_inc) + return arch_atomic64_fetch_inc(v); +#else + return raw_atomic64_fetch_add_relaxed(1, v); #endif - -#endif /* arch_atomic64_fetch_inc_relaxed */ - -#ifndef arch_atomic64_dec -static __always_inline void -arch_atomic64_dec(atomic64_t *v) -{ - arch_atomic64_sub(1, v); } -#define arch_atomic64_dec arch_atomic64_dec -#endif - -#ifndef arch_atomic64_dec_return_relaxed -#ifdef arch_atomic64_dec_return -#define arch_atomic64_dec_return_acquire arch_atomic64_dec_return -#define arch_atomic64_dec_return_release arch_atomic64_dec_return -#define arch_atomic64_dec_return_relaxed arch_atomic64_dec_return -#endif /* arch_atomic64_dec_return */ -#ifndef arch_atomic64_dec_return -static __always_inline s64 -arch_atomic64_dec_return(atomic64_t *v) +/** + * raw_atomic64_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_dec(atomic64_t *v) { - return arch_atomic64_sub_return(1, v); -} -#define arch_atomic64_dec_return arch_atomic64_dec_return +#if defined(arch_atomic64_dec) + arch_atomic64_dec(v); +#else + raw_atomic64_sub(1, v); #endif - -#ifndef arch_atomic64_dec_return_acquire -static __always_inline s64 -arch_atomic64_dec_return_acquire(atomic64_t *v) -{ - return arch_atomic64_sub_return_acquire(1, v); } -#define arch_atomic64_dec_return_acquire arch_atomic64_dec_return_acquire -#endif -#ifndef arch_atomic64_dec_return_release +/** + * raw_atomic64_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_dec_return_release(atomic64_t *v) +raw_atomic64_dec_return(atomic64_t *v) { - return arch_atomic64_sub_return_release(1, v); -} -#define arch_atomic64_dec_return_release arch_atomic64_dec_return_release +#if defined(arch_atomic64_dec_return) + return arch_atomic64_dec_return(v); +#elif defined(arch_atomic64_dec_return_relaxed) + s64 ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_dec_return_relaxed(v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic64_sub_return(1, v); #endif - -#ifndef arch_atomic64_dec_return_relaxed -static __always_inline s64 -arch_atomic64_dec_return_relaxed(atomic64_t *v) -{ - return arch_atomic64_sub_return_relaxed(1, v); } -#define arch_atomic64_dec_return_relaxed arch_atomic64_dec_return_relaxed -#endif - -#else /* arch_atomic64_dec_return_relaxed */ -#ifndef arch_atomic64_dec_return_acquire +/** + * raw_atomic64_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_dec_return_acquire(atomic64_t *v) +raw_atomic64_dec_return_acquire(atomic64_t *v) { +#if defined(arch_atomic64_dec_return_acquire) + return arch_atomic64_dec_return_acquire(v); +#elif defined(arch_atomic64_dec_return_relaxed) s64 ret = arch_atomic64_dec_return_relaxed(v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_dec_return_acquire arch_atomic64_dec_return_acquire +#elif defined(arch_atomic64_dec_return) + return arch_atomic64_dec_return(v); +#else + return raw_atomic64_sub_return_acquire(1, v); #endif +} -#ifndef arch_atomic64_dec_return_release +/** + * raw_atomic64_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline s64 -arch_atomic64_dec_return_release(atomic64_t *v) +raw_atomic64_dec_return_release(atomic64_t *v) { +#if defined(arch_atomic64_dec_return_release) + return arch_atomic64_dec_return_release(v); +#elif defined(arch_atomic64_dec_return_relaxed) __atomic_release_fence(); return arch_atomic64_dec_return_relaxed(v); +#elif defined(arch_atomic64_dec_return) + return arch_atomic64_dec_return(v); +#else + return raw_atomic64_sub_return_release(1, v); +#endif } -#define arch_atomic64_dec_return_release arch_atomic64_dec_return_release + +/** + * raw_atomic64_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ +static __always_inline s64 +raw_atomic64_dec_return_relaxed(atomic64_t *v) +{ +#if defined(arch_atomic64_dec_return_relaxed) + return arch_atomic64_dec_return_relaxed(v); +#elif defined(arch_atomic64_dec_return) + return arch_atomic64_dec_return(v); +#else + return raw_atomic64_sub_return_relaxed(1, v); #endif +} -#ifndef arch_atomic64_dec_return +/** + * raw_atomic64_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_dec() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_dec_return(atomic64_t *v) +raw_atomic64_fetch_dec(atomic64_t *v) { +#if defined(arch_atomic64_fetch_dec) + return arch_atomic64_fetch_dec(v); +#elif defined(arch_atomic64_fetch_dec_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_dec_return_relaxed(v); + ret = arch_atomic64_fetch_dec_relaxed(v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_dec_return arch_atomic64_dec_return +#else + return raw_atomic64_fetch_sub(1, v); #endif - -#endif /* arch_atomic64_dec_return_relaxed */ - -#ifndef arch_atomic64_fetch_dec_relaxed -#ifdef arch_atomic64_fetch_dec -#define arch_atomic64_fetch_dec_acquire arch_atomic64_fetch_dec -#define arch_atomic64_fetch_dec_release arch_atomic64_fetch_dec -#define arch_atomic64_fetch_dec_relaxed arch_atomic64_fetch_dec -#endif /* arch_atomic64_fetch_dec */ - -#ifndef arch_atomic64_fetch_dec -static __always_inline s64 -arch_atomic64_fetch_dec(atomic64_t *v) -{ - return arch_atomic64_fetch_sub(1, v); } -#define arch_atomic64_fetch_dec arch_atomic64_fetch_dec -#endif -#ifndef arch_atomic64_fetch_dec_acquire +/** + * raw_atomic64_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_dec_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_dec_acquire(atomic64_t *v) +raw_atomic64_fetch_dec_acquire(atomic64_t *v) { - return arch_atomic64_fetch_sub_acquire(1, v); -} -#define arch_atomic64_fetch_dec_acquire arch_atomic64_fetch_dec_acquire +#if defined(arch_atomic64_fetch_dec_acquire) + return arch_atomic64_fetch_dec_acquire(v); +#elif defined(arch_atomic64_fetch_dec_relaxed) + s64 ret = arch_atomic64_fetch_dec_relaxed(v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic64_fetch_dec) + return arch_atomic64_fetch_dec(v); +#else + return raw_atomic64_fetch_sub_acquire(1, v); #endif - -#ifndef arch_atomic64_fetch_dec_release -static __always_inline s64 -arch_atomic64_fetch_dec_release(atomic64_t *v) -{ - return arch_atomic64_fetch_sub_release(1, v); } -#define arch_atomic64_fetch_dec_release arch_atomic64_fetch_dec_release -#endif -#ifndef arch_atomic64_fetch_dec_relaxed +/** + * raw_atomic64_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_dec_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_dec_relaxed(atomic64_t *v) +raw_atomic64_fetch_dec_release(atomic64_t *v) { - return arch_atomic64_fetch_sub_relaxed(1, v); -} -#define arch_atomic64_fetch_dec_relaxed arch_atomic64_fetch_dec_relaxed +#if defined(arch_atomic64_fetch_dec_release) + return arch_atomic64_fetch_dec_release(v); +#elif defined(arch_atomic64_fetch_dec_relaxed) + __atomic_release_fence(); + return arch_atomic64_fetch_dec_relaxed(v); +#elif defined(arch_atomic64_fetch_dec) + return arch_atomic64_fetch_dec(v); +#else + return raw_atomic64_fetch_sub_release(1, v); #endif +} -#else /* arch_atomic64_fetch_dec_relaxed */ - -#ifndef arch_atomic64_fetch_dec_acquire +/** + * raw_atomic64_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_dec_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_dec_acquire(atomic64_t *v) +raw_atomic64_fetch_dec_relaxed(atomic64_t *v) { - s64 ret = arch_atomic64_fetch_dec_relaxed(v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic64_fetch_dec_acquire arch_atomic64_fetch_dec_acquire +#if defined(arch_atomic64_fetch_dec_relaxed) + return arch_atomic64_fetch_dec_relaxed(v); +#elif defined(arch_atomic64_fetch_dec) + return arch_atomic64_fetch_dec(v); +#else + return raw_atomic64_fetch_sub_relaxed(1, v); #endif +} -#ifndef arch_atomic64_fetch_dec_release -static __always_inline s64 -arch_atomic64_fetch_dec_release(atomic64_t *v) +/** + * raw_atomic64_and() - atomic bitwise AND with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_and() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_and(s64 i, atomic64_t *v) { - __atomic_release_fence(); - return arch_atomic64_fetch_dec_relaxed(v); + arch_atomic64_and(i, v); } -#define arch_atomic64_fetch_dec_release arch_atomic64_fetch_dec_release -#endif -#ifndef arch_atomic64_fetch_dec +/** + * raw_atomic64_fetch_and() - atomic bitwise AND with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_and() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_dec(atomic64_t *v) +raw_atomic64_fetch_and(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_and) + return arch_atomic64_fetch_and(i, v); +#elif defined(arch_atomic64_fetch_and_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_dec_relaxed(v); + ret = arch_atomic64_fetch_and_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_dec arch_atomic64_fetch_dec +#else +#error "Unable to define raw_atomic64_fetch_and" #endif +} -#endif /* arch_atomic64_fetch_dec_relaxed */ - -#ifndef arch_atomic64_fetch_and_relaxed -#define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and -#define arch_atomic64_fetch_and_release arch_atomic64_fetch_and -#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and -#else /* arch_atomic64_fetch_and_relaxed */ - -#ifndef arch_atomic64_fetch_and_acquire +/** + * raw_atomic64_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_and_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_and_acquire(s64 i, atomic64_t *v) +raw_atomic64_fetch_and_acquire(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_and_acquire) + return arch_atomic64_fetch_and_acquire(i, v); +#elif defined(arch_atomic64_fetch_and_relaxed) s64 ret = arch_atomic64_fetch_and_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_and_acquire arch_atomic64_fetch_and_acquire +#elif defined(arch_atomic64_fetch_and) + return arch_atomic64_fetch_and(i, v); +#else +#error "Unable to define raw_atomic64_fetch_and_acquire" #endif +} -#ifndef arch_atomic64_fetch_and_release +/** + * raw_atomic64_fetch_and_release() - atomic bitwise AND with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_and_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_and_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_and_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_and_release) + return arch_atomic64_fetch_and_release(i, v); +#elif defined(arch_atomic64_fetch_and_relaxed) __atomic_release_fence(); return arch_atomic64_fetch_and_relaxed(i, v); -} -#define arch_atomic64_fetch_and_release arch_atomic64_fetch_and_release +#elif defined(arch_atomic64_fetch_and) + return arch_atomic64_fetch_and(i, v); +#else +#error "Unable to define raw_atomic64_fetch_and_release" #endif +} -#ifndef arch_atomic64_fetch_and +/** + * raw_atomic64_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_and_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_and(s64 i, atomic64_t *v) +raw_atomic64_fetch_and_relaxed(s64 i, atomic64_t *v) { - s64 ret; - __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_and_relaxed(i, v); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic64_fetch_and arch_atomic64_fetch_and +#if defined(arch_atomic64_fetch_and_relaxed) + return arch_atomic64_fetch_and_relaxed(i, v); +#elif defined(arch_atomic64_fetch_and) + return arch_atomic64_fetch_and(i, v); +#else +#error "Unable to define raw_atomic64_fetch_and_relaxed" #endif - -#endif /* arch_atomic64_fetch_and_relaxed */ - -#ifndef arch_atomic64_andnot -static __always_inline void -arch_atomic64_andnot(s64 i, atomic64_t *v) -{ - arch_atomic64_and(~i, v); } -#define arch_atomic64_andnot arch_atomic64_andnot -#endif -#ifndef arch_atomic64_fetch_andnot_relaxed -#ifdef arch_atomic64_fetch_andnot -#define arch_atomic64_fetch_andnot_acquire arch_atomic64_fetch_andnot -#define arch_atomic64_fetch_andnot_release arch_atomic64_fetch_andnot -#define arch_atomic64_fetch_andnot_relaxed arch_atomic64_fetch_andnot -#endif /* arch_atomic64_fetch_andnot */ - -#ifndef arch_atomic64_fetch_andnot -static __always_inline s64 -arch_atomic64_fetch_andnot(s64 i, atomic64_t *v) +/** + * raw_atomic64_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_andnot() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_andnot(s64 i, atomic64_t *v) { - return arch_atomic64_fetch_and(~i, v); -} -#define arch_atomic64_fetch_andnot arch_atomic64_fetch_andnot +#if defined(arch_atomic64_andnot) + arch_atomic64_andnot(i, v); +#else + raw_atomic64_and(~i, v); #endif - -#ifndef arch_atomic64_fetch_andnot_acquire -static __always_inline s64 -arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v) -{ - return arch_atomic64_fetch_and_acquire(~i, v); } -#define arch_atomic64_fetch_andnot_acquire arch_atomic64_fetch_andnot_acquire -#endif -#ifndef arch_atomic64_fetch_andnot_release +/** + * raw_atomic64_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_andnot() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_andnot(s64 i, atomic64_t *v) { - return arch_atomic64_fetch_and_release(~i, v); -} -#define arch_atomic64_fetch_andnot_release arch_atomic64_fetch_andnot_release +#if defined(arch_atomic64_fetch_andnot) + return arch_atomic64_fetch_andnot(i, v); +#elif defined(arch_atomic64_fetch_andnot_relaxed) + s64 ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_fetch_andnot_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic64_fetch_and(~i, v); #endif - -#ifndef arch_atomic64_fetch_andnot_relaxed -static __always_inline s64 -arch_atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v) -{ - return arch_atomic64_fetch_and_relaxed(~i, v); } -#define arch_atomic64_fetch_andnot_relaxed arch_atomic64_fetch_andnot_relaxed -#endif - -#else /* arch_atomic64_fetch_andnot_relaxed */ -#ifndef arch_atomic64_fetch_andnot_acquire +/** + * raw_atomic64_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_andnot_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v) +raw_atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_andnot_acquire) + return arch_atomic64_fetch_andnot_acquire(i, v); +#elif defined(arch_atomic64_fetch_andnot_relaxed) s64 ret = arch_atomic64_fetch_andnot_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_andnot_acquire arch_atomic64_fetch_andnot_acquire +#elif defined(arch_atomic64_fetch_andnot) + return arch_atomic64_fetch_andnot(i, v); +#else + return raw_atomic64_fetch_and_acquire(~i, v); #endif +} -#ifndef arch_atomic64_fetch_andnot_release +/** + * raw_atomic64_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_andnot_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_andnot_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_andnot_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_andnot_release) + return arch_atomic64_fetch_andnot_release(i, v); +#elif defined(arch_atomic64_fetch_andnot_relaxed) __atomic_release_fence(); return arch_atomic64_fetch_andnot_relaxed(i, v); +#elif defined(arch_atomic64_fetch_andnot) + return arch_atomic64_fetch_andnot(i, v); +#else + return raw_atomic64_fetch_and_release(~i, v); +#endif } -#define arch_atomic64_fetch_andnot_release arch_atomic64_fetch_andnot_release + +/** + * raw_atomic64_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_andnot_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline s64 +raw_atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_fetch_andnot_relaxed) + return arch_atomic64_fetch_andnot_relaxed(i, v); +#elif defined(arch_atomic64_fetch_andnot) + return arch_atomic64_fetch_andnot(i, v); +#else + return raw_atomic64_fetch_and_relaxed(~i, v); #endif +} -#ifndef arch_atomic64_fetch_andnot +/** + * raw_atomic64_or() - atomic bitwise OR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_or() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_or(s64 i, atomic64_t *v) +{ + arch_atomic64_or(i, v); +} + +/** + * raw_atomic64_fetch_or() - atomic bitwise OR with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_or() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_andnot(s64 i, atomic64_t *v) +raw_atomic64_fetch_or(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_or) + return arch_atomic64_fetch_or(i, v); +#elif defined(arch_atomic64_fetch_or_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_andnot_relaxed(i, v); + ret = arch_atomic64_fetch_or_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_andnot arch_atomic64_fetch_andnot +#else +#error "Unable to define raw_atomic64_fetch_or" #endif +} -#endif /* arch_atomic64_fetch_andnot_relaxed */ - -#ifndef arch_atomic64_fetch_or_relaxed -#define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or -#define arch_atomic64_fetch_or_release arch_atomic64_fetch_or -#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or -#else /* arch_atomic64_fetch_or_relaxed */ - -#ifndef arch_atomic64_fetch_or_acquire +/** + * raw_atomic64_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_or_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_or_acquire(s64 i, atomic64_t *v) +raw_atomic64_fetch_or_acquire(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_or_acquire) + return arch_atomic64_fetch_or_acquire(i, v); +#elif defined(arch_atomic64_fetch_or_relaxed) s64 ret = arch_atomic64_fetch_or_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_or_acquire arch_atomic64_fetch_or_acquire +#elif defined(arch_atomic64_fetch_or) + return arch_atomic64_fetch_or(i, v); +#else +#error "Unable to define raw_atomic64_fetch_or_acquire" #endif +} -#ifndef arch_atomic64_fetch_or_release +/** + * raw_atomic64_fetch_or_release() - atomic bitwise OR with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_or_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_or_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_or_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_or_release) + return arch_atomic64_fetch_or_release(i, v); +#elif defined(arch_atomic64_fetch_or_relaxed) __atomic_release_fence(); return arch_atomic64_fetch_or_relaxed(i, v); +#elif defined(arch_atomic64_fetch_or) + return arch_atomic64_fetch_or(i, v); +#else +#error "Unable to define raw_atomic64_fetch_or_release" +#endif } -#define arch_atomic64_fetch_or_release arch_atomic64_fetch_or_release + +/** + * raw_atomic64_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_or_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline s64 +raw_atomic64_fetch_or_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_fetch_or_relaxed) + return arch_atomic64_fetch_or_relaxed(i, v); +#elif defined(arch_atomic64_fetch_or) + return arch_atomic64_fetch_or(i, v); +#else +#error "Unable to define raw_atomic64_fetch_or_relaxed" #endif +} + +/** + * raw_atomic64_xor() - atomic bitwise XOR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_xor() elsewhere. + * + * Return: Nothing. + */ +static __always_inline void +raw_atomic64_xor(s64 i, atomic64_t *v) +{ + arch_atomic64_xor(i, v); +} -#ifndef arch_atomic64_fetch_or +/** + * raw_atomic64_fetch_xor() - atomic bitwise XOR with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_xor() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_or(s64 i, atomic64_t *v) +raw_atomic64_fetch_xor(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_xor) + return arch_atomic64_fetch_xor(i, v); +#elif defined(arch_atomic64_fetch_xor_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_or_relaxed(i, v); + ret = arch_atomic64_fetch_xor_relaxed(i, v); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_or arch_atomic64_fetch_or +#else +#error "Unable to define raw_atomic64_fetch_xor" #endif +} -#endif /* arch_atomic64_fetch_or_relaxed */ - -#ifndef arch_atomic64_fetch_xor_relaxed -#define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor -#define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor -#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor -#else /* arch_atomic64_fetch_xor_relaxed */ - -#ifndef arch_atomic64_fetch_xor_acquire +/** + * raw_atomic64_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_xor_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_xor_acquire(s64 i, atomic64_t *v) +raw_atomic64_fetch_xor_acquire(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_xor_acquire) + return arch_atomic64_fetch_xor_acquire(i, v); +#elif defined(arch_atomic64_fetch_xor_relaxed) s64 ret = arch_atomic64_fetch_xor_relaxed(i, v); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_fetch_xor_acquire arch_atomic64_fetch_xor_acquire +#elif defined(arch_atomic64_fetch_xor) + return arch_atomic64_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic64_fetch_xor_acquire" #endif +} -#ifndef arch_atomic64_fetch_xor_release +/** + * raw_atomic64_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_xor_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_xor_release(s64 i, atomic64_t *v) +raw_atomic64_fetch_xor_release(s64 i, atomic64_t *v) { +#if defined(arch_atomic64_fetch_xor_release) + return arch_atomic64_fetch_xor_release(i, v); +#elif defined(arch_atomic64_fetch_xor_relaxed) __atomic_release_fence(); return arch_atomic64_fetch_xor_relaxed(i, v); +#elif defined(arch_atomic64_fetch_xor) + return arch_atomic64_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic64_fetch_xor_release" +#endif } -#define arch_atomic64_fetch_xor_release arch_atomic64_fetch_xor_release + +/** + * raw_atomic64_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_xor_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline s64 +raw_atomic64_fetch_xor_relaxed(s64 i, atomic64_t *v) +{ +#if defined(arch_atomic64_fetch_xor_relaxed) + return arch_atomic64_fetch_xor_relaxed(i, v); +#elif defined(arch_atomic64_fetch_xor) + return arch_atomic64_fetch_xor(i, v); +#else +#error "Unable to define raw_atomic64_fetch_xor_relaxed" #endif +} -#ifndef arch_atomic64_fetch_xor +/** + * raw_atomic64_xchg() - atomic exchange with full ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_xchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_fetch_xor(s64 i, atomic64_t *v) +raw_atomic64_xchg(atomic64_t *v, s64 new) { +#if defined(arch_atomic64_xchg) + return arch_atomic64_xchg(v, new); +#elif defined(arch_atomic64_xchg_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_fetch_xor_relaxed(i, v); + ret = arch_atomic64_xchg_relaxed(v, new); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_fetch_xor arch_atomic64_fetch_xor +#else + return raw_xchg(&v->counter, new); #endif +} -#endif /* arch_atomic64_fetch_xor_relaxed */ - -#ifndef arch_atomic64_xchg_relaxed -#define arch_atomic64_xchg_acquire arch_atomic64_xchg -#define arch_atomic64_xchg_release arch_atomic64_xchg -#define arch_atomic64_xchg_relaxed arch_atomic64_xchg -#else /* arch_atomic64_xchg_relaxed */ - -#ifndef arch_atomic64_xchg_acquire +/** + * raw_atomic64_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_xchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_xchg_acquire(atomic64_t *v, s64 i) +raw_atomic64_xchg_acquire(atomic64_t *v, s64 new) { - s64 ret = arch_atomic64_xchg_relaxed(v, i); +#if defined(arch_atomic64_xchg_acquire) + return arch_atomic64_xchg_acquire(v, new); +#elif defined(arch_atomic64_xchg_relaxed) + s64 ret = arch_atomic64_xchg_relaxed(v, new); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_xchg_acquire arch_atomic64_xchg_acquire +#elif defined(arch_atomic64_xchg) + return arch_atomic64_xchg(v, new); +#else + return raw_xchg_acquire(&v->counter, new); #endif +} -#ifndef arch_atomic64_xchg_release +/** + * raw_atomic64_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_xchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_xchg_release(atomic64_t *v, s64 i) +raw_atomic64_xchg_release(atomic64_t *v, s64 new) { +#if defined(arch_atomic64_xchg_release) + return arch_atomic64_xchg_release(v, new); +#elif defined(arch_atomic64_xchg_relaxed) __atomic_release_fence(); - return arch_atomic64_xchg_relaxed(v, i); + return arch_atomic64_xchg_relaxed(v, new); +#elif defined(arch_atomic64_xchg) + return arch_atomic64_xchg(v, new); +#else + return raw_xchg_release(&v->counter, new); +#endif } -#define arch_atomic64_xchg_release arch_atomic64_xchg_release + +/** + * raw_atomic64_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_xchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ +static __always_inline s64 +raw_atomic64_xchg_relaxed(atomic64_t *v, s64 new) +{ +#if defined(arch_atomic64_xchg_relaxed) + return arch_atomic64_xchg_relaxed(v, new); +#elif defined(arch_atomic64_xchg) + return arch_atomic64_xchg(v, new); +#else + return raw_xchg_relaxed(&v->counter, new); #endif +} -#ifndef arch_atomic64_xchg +/** + * raw_atomic64_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_cmpxchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_xchg(atomic64_t *v, s64 i) +raw_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new) { +#if defined(arch_atomic64_cmpxchg) + return arch_atomic64_cmpxchg(v, old, new); +#elif defined(arch_atomic64_cmpxchg_relaxed) s64 ret; __atomic_pre_full_fence(); - ret = arch_atomic64_xchg_relaxed(v, i); + ret = arch_atomic64_cmpxchg_relaxed(v, old, new); __atomic_post_full_fence(); return ret; -} -#define arch_atomic64_xchg arch_atomic64_xchg +#else + return raw_cmpxchg(&v->counter, old, new); #endif +} -#endif /* arch_atomic64_xchg_relaxed */ - -#ifndef arch_atomic64_cmpxchg_relaxed -#define arch_atomic64_cmpxchg_acquire arch_atomic64_cmpxchg -#define arch_atomic64_cmpxchg_release arch_atomic64_cmpxchg -#define arch_atomic64_cmpxchg_relaxed arch_atomic64_cmpxchg -#else /* arch_atomic64_cmpxchg_relaxed */ - -#ifndef arch_atomic64_cmpxchg_acquire +/** + * raw_atomic64_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_cmpxchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new) +raw_atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new) { +#if defined(arch_atomic64_cmpxchg_acquire) + return arch_atomic64_cmpxchg_acquire(v, old, new); +#elif defined(arch_atomic64_cmpxchg_relaxed) s64 ret = arch_atomic64_cmpxchg_relaxed(v, old, new); __atomic_acquire_fence(); return ret; -} -#define arch_atomic64_cmpxchg_acquire arch_atomic64_cmpxchg_acquire +#elif defined(arch_atomic64_cmpxchg) + return arch_atomic64_cmpxchg(v, old, new); +#else + return raw_cmpxchg_acquire(&v->counter, old, new); #endif +} -#ifndef arch_atomic64_cmpxchg_release +/** + * raw_atomic64_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_cmpxchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new) +raw_atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new) { +#if defined(arch_atomic64_cmpxchg_release) + return arch_atomic64_cmpxchg_release(v, old, new); +#elif defined(arch_atomic64_cmpxchg_relaxed) __atomic_release_fence(); return arch_atomic64_cmpxchg_relaxed(v, old, new); -} -#define arch_atomic64_cmpxchg_release arch_atomic64_cmpxchg_release +#elif defined(arch_atomic64_cmpxchg) + return arch_atomic64_cmpxchg(v, old, new); +#else + return raw_cmpxchg_release(&v->counter, old, new); #endif +} -#ifndef arch_atomic64_cmpxchg +/** + * raw_atomic64_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic64_cmpxchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline s64 -arch_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new) +raw_atomic64_cmpxchg_relaxed(atomic64_t *v, s64 old, s64 new) { - s64 ret; - __atomic_pre_full_fence(); - ret = arch_atomic64_cmpxchg_relaxed(v, old, new); - __atomic_post_full_fence(); - return ret; -} -#define arch_atomic64_cmpxchg arch_atomic64_cmpxchg +#if defined(arch_atomic64_cmpxchg_relaxed) + return arch_atomic64_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic64_cmpxchg) + return arch_atomic64_cmpxchg(v, old, new); +#else + return raw_cmpxchg_relaxed(&v->counter, old, new); #endif +} -#endif /* arch_atomic64_cmpxchg_relaxed */ - -#ifndef arch_atomic64_try_cmpxchg_relaxed -#ifdef arch_atomic64_try_cmpxchg -#define arch_atomic64_try_cmpxchg_acquire arch_atomic64_try_cmpxchg -#define arch_atomic64_try_cmpxchg_release arch_atomic64_try_cmpxchg -#define arch_atomic64_try_cmpxchg_relaxed arch_atomic64_try_cmpxchg -#endif /* arch_atomic64_try_cmpxchg */ - -#ifndef arch_atomic64_try_cmpxchg +/** + * raw_atomic64_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic64_try_cmpxchg() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new) +raw_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new) { +#if defined(arch_atomic64_try_cmpxchg) + return arch_atomic64_try_cmpxchg(v, old, new); +#elif defined(arch_atomic64_try_cmpxchg_relaxed) + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_try_cmpxchg_relaxed(v, old, new); + __atomic_post_full_fence(); + return ret; +#else s64 r, o = *old; - r = arch_atomic64_cmpxchg(v, o, new); + r = raw_atomic64_cmpxchg(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic64_try_cmpxchg arch_atomic64_try_cmpxchg #endif +} -#ifndef arch_atomic64_try_cmpxchg_acquire +/** + * raw_atomic64_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic64_try_cmpxchg_acquire() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new) +raw_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new) { +#if defined(arch_atomic64_try_cmpxchg_acquire) + return arch_atomic64_try_cmpxchg_acquire(v, old, new); +#elif defined(arch_atomic64_try_cmpxchg_relaxed) + bool ret = arch_atomic64_try_cmpxchg_relaxed(v, old, new); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic64_try_cmpxchg) + return arch_atomic64_try_cmpxchg(v, old, new); +#else s64 r, o = *old; - r = arch_atomic64_cmpxchg_acquire(v, o, new); + r = raw_atomic64_cmpxchg_acquire(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic64_try_cmpxchg_acquire arch_atomic64_try_cmpxchg_acquire #endif +} -#ifndef arch_atomic64_try_cmpxchg_release +/** + * raw_atomic64_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic64_try_cmpxchg_release() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new) +raw_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new) { +#if defined(arch_atomic64_try_cmpxchg_release) + return arch_atomic64_try_cmpxchg_release(v, old, new); +#elif defined(arch_atomic64_try_cmpxchg_relaxed) + __atomic_release_fence(); + return arch_atomic64_try_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic64_try_cmpxchg) + return arch_atomic64_try_cmpxchg(v, old, new); +#else s64 r, o = *old; - r = arch_atomic64_cmpxchg_release(v, o, new); + r = raw_atomic64_cmpxchg_release(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic64_try_cmpxchg_release arch_atomic64_try_cmpxchg_release #endif +} -#ifndef arch_atomic64_try_cmpxchg_relaxed +/** + * raw_atomic64_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic64_try_cmpxchg_relaxed() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new) +raw_atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new) { +#if defined(arch_atomic64_try_cmpxchg_relaxed) + return arch_atomic64_try_cmpxchg_relaxed(v, old, new); +#elif defined(arch_atomic64_try_cmpxchg) + return arch_atomic64_try_cmpxchg(v, old, new); +#else s64 r, o = *old; - r = arch_atomic64_cmpxchg_relaxed(v, o, new); + r = raw_atomic64_cmpxchg_relaxed(v, o, new); if (unlikely(r != o)) *old = r; return likely(r == o); -} -#define arch_atomic64_try_cmpxchg_relaxed arch_atomic64_try_cmpxchg_relaxed -#endif - -#else /* arch_atomic64_try_cmpxchg_relaxed */ - -#ifndef arch_atomic64_try_cmpxchg_acquire -static __always_inline bool -arch_atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new) -{ - bool ret = arch_atomic64_try_cmpxchg_relaxed(v, old, new); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic64_try_cmpxchg_acquire arch_atomic64_try_cmpxchg_acquire -#endif - -#ifndef arch_atomic64_try_cmpxchg_release -static __always_inline bool -arch_atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new) -{ - __atomic_release_fence(); - return arch_atomic64_try_cmpxchg_relaxed(v, old, new); -} -#define arch_atomic64_try_cmpxchg_release arch_atomic64_try_cmpxchg_release #endif - -#ifndef arch_atomic64_try_cmpxchg -static __always_inline bool -arch_atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new) -{ - bool ret; - __atomic_pre_full_fence(); - ret = arch_atomic64_try_cmpxchg_relaxed(v, old, new); - __atomic_post_full_fence(); - return ret; } -#define arch_atomic64_try_cmpxchg arch_atomic64_try_cmpxchg -#endif -#endif /* arch_atomic64_try_cmpxchg_relaxed */ - -#ifndef arch_atomic64_sub_and_test /** - * arch_atomic64_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @v: pointer of type atomic64_t + * raw_atomic64_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_sub_and_test() elsewhere. * - * Atomically subtracts @i from @v and returns - * true if the result is zero, or false for all - * other cases. + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic64_sub_and_test(s64 i, atomic64_t *v) +raw_atomic64_sub_and_test(s64 i, atomic64_t *v) { - return arch_atomic64_sub_return(i, v) == 0; -} -#define arch_atomic64_sub_and_test arch_atomic64_sub_and_test +#if defined(arch_atomic64_sub_and_test) + return arch_atomic64_sub_and_test(i, v); +#else + return raw_atomic64_sub_return(i, v) == 0; #endif +} -#ifndef arch_atomic64_dec_and_test /** - * arch_atomic64_dec_and_test - decrement and test - * @v: pointer of type atomic64_t + * raw_atomic64_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_and_test() elsewhere. * - * Atomically decrements @v by 1 and - * returns true if the result is 0, or false for all other - * cases. + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic64_dec_and_test(atomic64_t *v) +raw_atomic64_dec_and_test(atomic64_t *v) { - return arch_atomic64_dec_return(v) == 0; -} -#define arch_atomic64_dec_and_test arch_atomic64_dec_and_test +#if defined(arch_atomic64_dec_and_test) + return arch_atomic64_dec_and_test(v); +#else + return raw_atomic64_dec_return(v) == 0; #endif +} -#ifndef arch_atomic64_inc_and_test /** - * arch_atomic64_inc_and_test - increment and test - * @v: pointer of type atomic64_t + * raw_atomic64_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. + * Safe to use in noinstr code; prefer atomic64_inc_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. */ static __always_inline bool -arch_atomic64_inc_and_test(atomic64_t *v) +raw_atomic64_inc_and_test(atomic64_t *v) { - return arch_atomic64_inc_return(v) == 0; -} -#define arch_atomic64_inc_and_test arch_atomic64_inc_and_test +#if defined(arch_atomic64_inc_and_test) + return arch_atomic64_inc_and_test(v); +#else + return raw_atomic64_inc_return(v) == 0; #endif +} -#ifndef arch_atomic64_add_negative_relaxed -#ifdef arch_atomic64_add_negative -#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative -#define arch_atomic64_add_negative_release arch_atomic64_add_negative -#define arch_atomic64_add_negative_relaxed arch_atomic64_add_negative -#endif /* arch_atomic64_add_negative */ - -#ifndef arch_atomic64_add_negative /** - * arch_atomic64_add_negative - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic64_t + * raw_atomic64_add_negative() - atomic add and test if negative with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_negative() elsewhere. * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic64_add_negative(s64 i, atomic64_t *v) +raw_atomic64_add_negative(s64 i, atomic64_t *v) { - return arch_atomic64_add_return(i, v) < 0; -} -#define arch_atomic64_add_negative arch_atomic64_add_negative +#if defined(arch_atomic64_add_negative) + return arch_atomic64_add_negative(i, v); +#elif defined(arch_atomic64_add_negative_relaxed) + bool ret; + __atomic_pre_full_fence(); + ret = arch_atomic64_add_negative_relaxed(i, v); + __atomic_post_full_fence(); + return ret; +#else + return raw_atomic64_add_return(i, v) < 0; #endif +} -#ifndef arch_atomic64_add_negative_acquire /** - * arch_atomic64_add_negative_acquire - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic64_t + * raw_atomic64_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_negative_acquire() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v) +raw_atomic64_add_negative_acquire(s64 i, atomic64_t *v) { - return arch_atomic64_add_return_acquire(i, v) < 0; -} -#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative_acquire +#if defined(arch_atomic64_add_negative_acquire) + return arch_atomic64_add_negative_acquire(i, v); +#elif defined(arch_atomic64_add_negative_relaxed) + bool ret = arch_atomic64_add_negative_relaxed(i, v); + __atomic_acquire_fence(); + return ret; +#elif defined(arch_atomic64_add_negative) + return arch_atomic64_add_negative(i, v); +#else + return raw_atomic64_add_return_acquire(i, v) < 0; #endif +} -#ifndef arch_atomic64_add_negative_release /** - * arch_atomic64_add_negative_release - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic64_t + * raw_atomic64_add_negative_release() - atomic add and test if negative with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_negative_release() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic64_add_negative_release(s64 i, atomic64_t *v) +raw_atomic64_add_negative_release(s64 i, atomic64_t *v) { - return arch_atomic64_add_return_release(i, v) < 0; -} -#define arch_atomic64_add_negative_release arch_atomic64_add_negative_release +#if defined(arch_atomic64_add_negative_release) + return arch_atomic64_add_negative_release(i, v); +#elif defined(arch_atomic64_add_negative_relaxed) + __atomic_release_fence(); + return arch_atomic64_add_negative_relaxed(i, v); +#elif defined(arch_atomic64_add_negative) + return arch_atomic64_add_negative(i, v); +#else + return raw_atomic64_add_return_release(i, v) < 0; #endif +} -#ifndef arch_atomic64_add_negative_relaxed /** - * arch_atomic64_add_negative_relaxed - Add and test if negative - * @i: integer value to add - * @v: pointer of type atomic64_t + * raw_atomic64_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. * - * Atomically adds @i to @v and returns true if the result is negative, - * or false when the result is greater than or equal to zero. + * Safe to use in noinstr code; prefer atomic64_add_negative_relaxed() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. */ static __always_inline bool -arch_atomic64_add_negative_relaxed(s64 i, atomic64_t *v) -{ - return arch_atomic64_add_return_relaxed(i, v) < 0; -} -#define arch_atomic64_add_negative_relaxed arch_atomic64_add_negative_relaxed -#endif - -#else /* arch_atomic64_add_negative_relaxed */ - -#ifndef arch_atomic64_add_negative_acquire -static __always_inline bool -arch_atomic64_add_negative_acquire(s64 i, atomic64_t *v) -{ - bool ret = arch_atomic64_add_negative_relaxed(i, v); - __atomic_acquire_fence(); - return ret; -} -#define arch_atomic64_add_negative_acquire arch_atomic64_add_negative_acquire -#endif - -#ifndef arch_atomic64_add_negative_release -static __always_inline bool -arch_atomic64_add_negative_release(s64 i, atomic64_t *v) +raw_atomic64_add_negative_relaxed(s64 i, atomic64_t *v) { - __atomic_release_fence(); +#if defined(arch_atomic64_add_negative_relaxed) return arch_atomic64_add_negative_relaxed(i, v); -} -#define arch_atomic64_add_negative_release arch_atomic64_add_negative_release +#elif defined(arch_atomic64_add_negative) + return arch_atomic64_add_negative(i, v); +#else + return raw_atomic64_add_return_relaxed(i, v) < 0; #endif - -#ifndef arch_atomic64_add_negative -static __always_inline bool -arch_atomic64_add_negative(s64 i, atomic64_t *v) -{ - bool ret; - __atomic_pre_full_fence(); - ret = arch_atomic64_add_negative_relaxed(i, v); - __atomic_post_full_fence(); - return ret; } -#define arch_atomic64_add_negative arch_atomic64_add_negative -#endif - -#endif /* arch_atomic64_add_negative_relaxed */ -#ifndef arch_atomic64_fetch_add_unless /** - * arch_atomic64_fetch_add_unless - add unless the number is already a given value - * @v: pointer of type atomic64_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. + * raw_atomic64_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic64_t + * @a: s64 value to add + * @u: s64 value to compare with * - * Atomically adds @a to @v, so long as @v was not already @u. - * Returns original value of @v + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_fetch_add_unless() elsewhere. + * + * Return: The original value of @v. */ static __always_inline s64 -arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u) +raw_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u) { - s64 c = arch_atomic64_read(v); +#if defined(arch_atomic64_fetch_add_unless) + return arch_atomic64_fetch_add_unless(v, a, u); +#else + s64 c = raw_atomic64_read(v); do { if (unlikely(c == u)) break; - } while (!arch_atomic64_try_cmpxchg(v, &c, c + a)); + } while (!raw_atomic64_try_cmpxchg(v, &c, c + a)); return c; -} -#define arch_atomic64_fetch_add_unless arch_atomic64_fetch_add_unless #endif +} -#ifndef arch_atomic64_add_unless /** - * arch_atomic64_add_unless - add unless the number is already a given value - * @v: pointer of type atomic64_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. + * raw_atomic64_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic64_t + * @a: s64 value to add + * @u: s64 value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_add_unless() elsewhere. * - * Atomically adds @a to @v, if @v was not already @u. - * Returns true if the addition was done. + * Return: @true if @v was updated, @false otherwise. */ static __always_inline bool -arch_atomic64_add_unless(atomic64_t *v, s64 a, s64 u) +raw_atomic64_add_unless(atomic64_t *v, s64 a, s64 u) { - return arch_atomic64_fetch_add_unless(v, a, u) != u; -} -#define arch_atomic64_add_unless arch_atomic64_add_unless +#if defined(arch_atomic64_add_unless) + return arch_atomic64_add_unless(v, a, u); +#else + return raw_atomic64_fetch_add_unless(v, a, u) != u; #endif +} -#ifndef arch_atomic64_inc_not_zero /** - * arch_atomic64_inc_not_zero - increment unless the number is zero - * @v: pointer of type atomic64_t + * raw_atomic64_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic64_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_not_zero() elsewhere. * - * Atomically increments @v by 1, if @v is non-zero. - * Returns true if the increment was done. + * Return: @true if @v was updated, @false otherwise. */ static __always_inline bool -arch_atomic64_inc_not_zero(atomic64_t *v) +raw_atomic64_inc_not_zero(atomic64_t *v) { - return arch_atomic64_add_unless(v, 1, 0); -} -#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero +#if defined(arch_atomic64_inc_not_zero) + return arch_atomic64_inc_not_zero(v); +#else + return raw_atomic64_add_unless(v, 1, 0); #endif +} -#ifndef arch_atomic64_inc_unless_negative +/** + * raw_atomic64_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic64_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_inc_unless_negative() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic64_inc_unless_negative(atomic64_t *v) +raw_atomic64_inc_unless_negative(atomic64_t *v) { - s64 c = arch_atomic64_read(v); +#if defined(arch_atomic64_inc_unless_negative) + return arch_atomic64_inc_unless_negative(v); +#else + s64 c = raw_atomic64_read(v); do { if (unlikely(c < 0)) return false; - } while (!arch_atomic64_try_cmpxchg(v, &c, c + 1)); + } while (!raw_atomic64_try_cmpxchg(v, &c, c + 1)); return true; -} -#define arch_atomic64_inc_unless_negative arch_atomic64_inc_unless_negative #endif +} -#ifndef arch_atomic64_dec_unless_positive +/** + * raw_atomic64_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic64_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_unless_positive() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic64_dec_unless_positive(atomic64_t *v) +raw_atomic64_dec_unless_positive(atomic64_t *v) { - s64 c = arch_atomic64_read(v); +#if defined(arch_atomic64_dec_unless_positive) + return arch_atomic64_dec_unless_positive(v); +#else + s64 c = raw_atomic64_read(v); do { if (unlikely(c > 0)) return false; - } while (!arch_atomic64_try_cmpxchg(v, &c, c - 1)); + } while (!raw_atomic64_try_cmpxchg(v, &c, c - 1)); return true; -} -#define arch_atomic64_dec_unless_positive arch_atomic64_dec_unless_positive #endif +} -#ifndef arch_atomic64_dec_if_positive +/** + * raw_atomic64_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic64_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic64_dec_if_positive() elsewhere. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline s64 -arch_atomic64_dec_if_positive(atomic64_t *v) +raw_atomic64_dec_if_positive(atomic64_t *v) { - s64 dec, c = arch_atomic64_read(v); +#if defined(arch_atomic64_dec_if_positive) + return arch_atomic64_dec_if_positive(v); +#else + s64 dec, c = raw_atomic64_read(v); do { dec = c - 1; if (unlikely(dec < 0)) break; - } while (!arch_atomic64_try_cmpxchg(v, &c, dec)); + } while (!raw_atomic64_try_cmpxchg(v, &c, dec)); return dec; -} -#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive #endif +} #endif /* _LINUX_ATOMIC_FALLBACK_H */ -// ad2e2b4d168dbc60a73922616047a9bfa446af36 +// 202b45c7db600ce36198eb1f1fc2c2d5268ace2d diff --git a/include/linux/atomic/atomic-instrumented.h b/include/linux/atomic/atomic-instrumented.h index 03a232a1fa57..d401b406ef7c 100644 --- a/include/linux/atomic/atomic-instrumented.h +++ b/include/linux/atomic/atomic-instrumented.h @@ -4,15 +4,10 @@ // DO NOT MODIFY THIS FILE DIRECTLY /* - * This file provides wrappers with KASAN instrumentation for atomic operations. - * To use this functionality an arch's atomic.h file needs to define all - * atomic operations with arch_ prefix (e.g. arch_atomic_read()) and include - * this file at the end. This file provides atomic_read() that forwards to - * arch_atomic_read() for actual atomic operation. - * Note: if an arch atomic operation is implemented by means of other atomic - * operations (e.g. atomic_read()/atomic_cmpxchg() loop), then it needs to use - * arch_ variants (i.e. arch_atomic_read()/arch_atomic_cmpxchg()) to avoid - * double instrumentation. + * This file provoides atomic operations with explicit instrumentation (e.g. + * KASAN, KCSAN), which should be used unless it is necessary to avoid + * instrumentation. Where it is necessary to aovid instrumenation, the + * raw_atomic*() operations should be used. */ #ifndef _LINUX_ATOMIC_INSTRUMENTED_H #define _LINUX_ATOMIC_INSTRUMENTED_H @@ -21,1927 +16,4696 @@ #include <linux/compiler.h> #include <linux/instrumented.h> +/** + * atomic_read() - atomic load with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_read() there. + * + * Return: The value loaded from @v. + */ static __always_inline int atomic_read(const atomic_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic_read(v); -} - + return raw_atomic_read(v); +} + +/** + * atomic_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_read_acquire() there. + * + * Return: The value loaded from @v. + */ static __always_inline int atomic_read_acquire(const atomic_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic_read_acquire(v); -} - + return raw_atomic_read_acquire(v); +} + +/** + * atomic_set() - atomic set with relaxed ordering + * @v: pointer to atomic_t + * @i: int value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_set() there. + * + * Return: Nothing. + */ static __always_inline void atomic_set(atomic_t *v, int i) { instrument_atomic_write(v, sizeof(*v)); - arch_atomic_set(v, i); -} - + raw_atomic_set(v, i); +} + +/** + * atomic_set_release() - atomic set with release ordering + * @v: pointer to atomic_t + * @i: int value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_set_release() there. + * + * Return: Nothing. + */ static __always_inline void atomic_set_release(atomic_t *v, int i) { kcsan_release(); instrument_atomic_write(v, sizeof(*v)); - arch_atomic_set_release(v, i); -} - + raw_atomic_set_release(v, i); +} + +/** + * atomic_add() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add() there. + * + * Return: Nothing. + */ static __always_inline void atomic_add(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_add(i, v); + raw_atomic_add(i, v); } +/** + * atomic_add_return() - atomic add with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_return() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_add_return(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_return(i, v); + return raw_atomic_add_return(i, v); } +/** + * atomic_add_return_acquire() - atomic add with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_add_return_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_return_acquire(i, v); + return raw_atomic_add_return_acquire(i, v); } +/** + * atomic_add_return_release() - atomic add with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_add_return_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_return_release(i, v); + return raw_atomic_add_return_release(i, v); } +/** + * atomic_add_return_relaxed() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_add_return_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_return_relaxed(i, v); + return raw_atomic_add_return_relaxed(i, v); } +/** + * atomic_fetch_add() - atomic add with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_add() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_add(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_add(i, v); + return raw_atomic_fetch_add(i, v); } +/** + * atomic_fetch_add_acquire() - atomic add with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_add_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_add_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_add_acquire(i, v); + return raw_atomic_fetch_add_acquire(i, v); } +/** + * atomic_fetch_add_release() - atomic add with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_add_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_add_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_add_release(i, v); + return raw_atomic_fetch_add_release(i, v); } +/** + * atomic_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_add_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_add_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_add_relaxed(i, v); + return raw_atomic_fetch_add_relaxed(i, v); } +/** + * atomic_sub() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub() there. + * + * Return: Nothing. + */ static __always_inline void atomic_sub(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_sub(i, v); + raw_atomic_sub(i, v); } +/** + * atomic_sub_return() - atomic subtract with full ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub_return() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_sub_return(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_sub_return(i, v); + return raw_atomic_sub_return(i, v); } +/** + * atomic_sub_return_acquire() - atomic subtract with acquire ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_sub_return_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_sub_return_acquire(i, v); + return raw_atomic_sub_return_acquire(i, v); } +/** + * atomic_sub_return_release() - atomic subtract with release ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_sub_return_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_sub_return_release(i, v); + return raw_atomic_sub_return_release(i, v); } +/** + * atomic_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_sub_return_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_sub_return_relaxed(i, v); + return raw_atomic_sub_return_relaxed(i, v); } +/** + * atomic_fetch_sub() - atomic subtract with full ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_sub() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_sub(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_sub(i, v); + return raw_atomic_fetch_sub(i, v); } +/** + * atomic_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_sub_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_sub_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_sub_acquire(i, v); + return raw_atomic_fetch_sub_acquire(i, v); } +/** + * atomic_fetch_sub_release() - atomic subtract with release ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_sub_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_sub_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_sub_release(i, v); + return raw_atomic_fetch_sub_release(i, v); } +/** + * atomic_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: int value to subtract + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_sub_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_sub_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_sub_relaxed(i, v); + return raw_atomic_fetch_sub_relaxed(i, v); } +/** + * atomic_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc() there. + * + * Return: Nothing. + */ static __always_inline void atomic_inc(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_inc(v); + raw_atomic_inc(v); } +/** + * atomic_inc_return() - atomic increment with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_return() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_inc_return(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_return(v); + return raw_atomic_inc_return(v); } +/** + * atomic_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_inc_return_acquire(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_return_acquire(v); + return raw_atomic_inc_return_acquire(v); } +/** + * atomic_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_inc_return_release(atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_return_release(v); + return raw_atomic_inc_return_release(v); } +/** + * atomic_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_inc_return_relaxed(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_return_relaxed(v); + return raw_atomic_inc_return_relaxed(v); } +/** + * atomic_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_inc() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_inc(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_inc(v); + return raw_atomic_fetch_inc(v); } +/** + * atomic_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_inc_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_inc_acquire(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_inc_acquire(v); + return raw_atomic_fetch_inc_acquire(v); } +/** + * atomic_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_inc_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_inc_release(atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_inc_release(v); + return raw_atomic_fetch_inc_release(v); } +/** + * atomic_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_inc_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_inc_relaxed(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_inc_relaxed(v); + return raw_atomic_fetch_inc_relaxed(v); } +/** + * atomic_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec() there. + * + * Return: Nothing. + */ static __always_inline void atomic_dec(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_dec(v); + raw_atomic_dec(v); } +/** + * atomic_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_return() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_dec_return(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_return(v); + return raw_atomic_dec_return(v); } +/** + * atomic_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_dec_return_acquire(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_return_acquire(v); + return raw_atomic_dec_return_acquire(v); } +/** + * atomic_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_dec_return_release(atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_return_release(v); + return raw_atomic_dec_return_release(v); } +/** + * atomic_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline int atomic_dec_return_relaxed(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_return_relaxed(v); + return raw_atomic_dec_return_relaxed(v); } +/** + * atomic_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_dec() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_dec(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_dec(v); + return raw_atomic_fetch_dec(v); } +/** + * atomic_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_dec_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_dec_acquire(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_dec_acquire(v); + return raw_atomic_fetch_dec_acquire(v); } +/** + * atomic_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_dec_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_dec_release(atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_dec_release(v); + return raw_atomic_fetch_dec_release(v); } +/** + * atomic_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_dec_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_dec_relaxed(atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_dec_relaxed(v); + return raw_atomic_fetch_dec_relaxed(v); } +/** + * atomic_and() - atomic bitwise AND with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_and() there. + * + * Return: Nothing. + */ static __always_inline void atomic_and(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_and(i, v); + raw_atomic_and(i, v); } +/** + * atomic_fetch_and() - atomic bitwise AND with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_and() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_and(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_and(i, v); + return raw_atomic_fetch_and(i, v); } +/** + * atomic_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_and_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_and_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_and_acquire(i, v); + return raw_atomic_fetch_and_acquire(i, v); } +/** + * atomic_fetch_and_release() - atomic bitwise AND with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_and_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_and_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_and_release(i, v); + return raw_atomic_fetch_and_release(i, v); } +/** + * atomic_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_and_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_and_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_and_relaxed(i, v); + return raw_atomic_fetch_and_relaxed(i, v); } +/** + * atomic_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_andnot() there. + * + * Return: Nothing. + */ static __always_inline void atomic_andnot(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_andnot(i, v); + raw_atomic_andnot(i, v); } +/** + * atomic_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_andnot() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_andnot(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_andnot(i, v); + return raw_atomic_fetch_andnot(i, v); } +/** + * atomic_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_andnot_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_andnot_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_andnot_acquire(i, v); + return raw_atomic_fetch_andnot_acquire(i, v); } +/** + * atomic_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_andnot_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_andnot_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_andnot_release(i, v); + return raw_atomic_fetch_andnot_release(i, v); } +/** + * atomic_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_andnot_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_andnot_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_andnot_relaxed(i, v); + return raw_atomic_fetch_andnot_relaxed(i, v); } +/** + * atomic_or() - atomic bitwise OR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_or() there. + * + * Return: Nothing. + */ static __always_inline void atomic_or(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_or(i, v); + raw_atomic_or(i, v); } +/** + * atomic_fetch_or() - atomic bitwise OR with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_or() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_or(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_or(i, v); + return raw_atomic_fetch_or(i, v); } +/** + * atomic_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_or_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_or_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_or_acquire(i, v); + return raw_atomic_fetch_or_acquire(i, v); } +/** + * atomic_fetch_or_release() - atomic bitwise OR with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_or_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_or_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_or_release(i, v); + return raw_atomic_fetch_or_release(i, v); } +/** + * atomic_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_or_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_or_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_or_relaxed(i, v); + return raw_atomic_fetch_or_relaxed(i, v); } +/** + * atomic_xor() - atomic bitwise XOR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_xor() there. + * + * Return: Nothing. + */ static __always_inline void atomic_xor(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_xor(i, v); + raw_atomic_xor(i, v); } +/** + * atomic_fetch_xor() - atomic bitwise XOR with full ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_xor() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_xor(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_xor(i, v); + return raw_atomic_fetch_xor(i, v); } +/** + * atomic_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_xor_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_xor_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_xor_acquire(i, v); + return raw_atomic_fetch_xor_acquire(i, v); } +/** + * atomic_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_xor_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_xor_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_xor_release(i, v); + return raw_atomic_fetch_xor_release(i, v); } +/** + * atomic_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: int value + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_xor_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_xor_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_xor_relaxed(i, v); + return raw_atomic_fetch_xor_relaxed(i, v); } +/** + * atomic_xchg() - atomic exchange with full ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_xchg() there. + * + * Return: The original value of @v. + */ static __always_inline int -atomic_xchg(atomic_t *v, int i) +atomic_xchg(atomic_t *v, int new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_xchg(v, i); + return raw_atomic_xchg(v, new); } +/** + * atomic_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_xchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int -atomic_xchg_acquire(atomic_t *v, int i) +atomic_xchg_acquire(atomic_t *v, int new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_xchg_acquire(v, i); + return raw_atomic_xchg_acquire(v, new); } +/** + * atomic_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_xchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline int -atomic_xchg_release(atomic_t *v, int i) +atomic_xchg_release(atomic_t *v, int new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_xchg_release(v, i); + return raw_atomic_xchg_release(v, new); } +/** + * atomic_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic_t + * @new: int value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_xchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int -atomic_xchg_relaxed(atomic_t *v, int i) +atomic_xchg_relaxed(atomic_t *v, int new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_xchg_relaxed(v, i); + return raw_atomic_xchg_relaxed(v, new); } +/** + * atomic_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_cmpxchg() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_cmpxchg(v, old, new); + return raw_atomic_cmpxchg(v, old, new); } +/** + * atomic_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_cmpxchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_cmpxchg_acquire(atomic_t *v, int old, int new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_cmpxchg_acquire(v, old, new); + return raw_atomic_cmpxchg_acquire(v, old, new); } +/** + * atomic_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_cmpxchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_cmpxchg_release(atomic_t *v, int old, int new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_cmpxchg_release(v, old, new); + return raw_atomic_cmpxchg_release(v, old, new); } +/** + * atomic_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_t + * @old: int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_cmpxchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_cmpxchg_relaxed(atomic_t *v, int old, int new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_cmpxchg_relaxed(v, old, new); + return raw_atomic_cmpxchg_relaxed(v, old, new); } +/** + * atomic_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_try_cmpxchg() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_try_cmpxchg(atomic_t *v, int *old, int new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_try_cmpxchg(v, old, new); -} - + return raw_atomic_try_cmpxchg(v, old, new); +} + +/** + * atomic_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_try_cmpxchg_acquire() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_try_cmpxchg_acquire(atomic_t *v, int *old, int new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_try_cmpxchg_acquire(v, old, new); -} - + return raw_atomic_try_cmpxchg_acquire(v, old, new); +} + +/** + * atomic_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_try_cmpxchg_release() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_try_cmpxchg_release(atomic_t *v, int *old, int new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_try_cmpxchg_release(v, old, new); -} - + return raw_atomic_try_cmpxchg_release(v, old, new); +} + +/** + * atomic_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_t + * @old: pointer to int value to compare with + * @new: int value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_try_cmpxchg_relaxed() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_try_cmpxchg_relaxed(atomic_t *v, int *old, int new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_try_cmpxchg_relaxed(v, old, new); -} - + return raw_atomic_try_cmpxchg_relaxed(v, old, new); +} + +/** + * atomic_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_sub_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_sub_and_test(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_sub_and_test(i, v); + return raw_atomic_sub_and_test(i, v); } +/** + * atomic_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_dec_and_test(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_and_test(v); + return raw_atomic_dec_and_test(v); } +/** + * atomic_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_inc_and_test(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_and_test(v); + return raw_atomic_inc_and_test(v); } +/** + * atomic_add_negative() - atomic add and test if negative with full ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_negative() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_add_negative(int i, atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_negative(i, v); + return raw_atomic_add_negative(i, v); } +/** + * atomic_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_negative_acquire() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_add_negative_acquire(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_negative_acquire(i, v); + return raw_atomic_add_negative_acquire(i, v); } +/** + * atomic_add_negative_release() - atomic add and test if negative with release ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_negative_release() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_add_negative_release(int i, atomic_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_negative_release(i, v); + return raw_atomic_add_negative_release(i, v); } +/** + * atomic_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: int value to add + * @v: pointer to atomic_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_negative_relaxed() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_add_negative_relaxed(int i, atomic_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_negative_relaxed(i, v); + return raw_atomic_add_negative_relaxed(i, v); } +/** + * atomic_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_t + * @a: int value to add + * @u: int value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_fetch_add_unless() there. + * + * Return: The original value of @v. + */ static __always_inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_fetch_add_unless(v, a, u); + return raw_atomic_fetch_add_unless(v, a, u); } +/** + * atomic_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_t + * @a: int value to add + * @u: int value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_add_unless() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_add_unless(atomic_t *v, int a, int u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_add_unless(v, a, u); + return raw_atomic_add_unless(v, a, u); } +/** + * atomic_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_not_zero() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_inc_not_zero(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_not_zero(v); + return raw_atomic_inc_not_zero(v); } +/** + * atomic_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_inc_unless_negative() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_inc_unless_negative(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_inc_unless_negative(v); + return raw_atomic_inc_unless_negative(v); } +/** + * atomic_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_unless_positive() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_dec_unless_positive(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_unless_positive(v); + return raw_atomic_dec_unless_positive(v); } +/** + * atomic_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_dec_if_positive() there. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline int atomic_dec_if_positive(atomic_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_dec_if_positive(v); + return raw_atomic_dec_if_positive(v); } +/** + * atomic64_read() - atomic load with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_read() there. + * + * Return: The value loaded from @v. + */ static __always_inline s64 atomic64_read(const atomic64_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic64_read(v); -} - + return raw_atomic64_read(v); +} + +/** + * atomic64_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_read_acquire() there. + * + * Return: The value loaded from @v. + */ static __always_inline s64 atomic64_read_acquire(const atomic64_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic64_read_acquire(v); -} - + return raw_atomic64_read_acquire(v); +} + +/** + * atomic64_set() - atomic set with relaxed ordering + * @v: pointer to atomic64_t + * @i: s64 value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_set() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_set(atomic64_t *v, s64 i) { instrument_atomic_write(v, sizeof(*v)); - arch_atomic64_set(v, i); -} - + raw_atomic64_set(v, i); +} + +/** + * atomic64_set_release() - atomic set with release ordering + * @v: pointer to atomic64_t + * @i: s64 value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_set_release() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_set_release(atomic64_t *v, s64 i) { kcsan_release(); instrument_atomic_write(v, sizeof(*v)); - arch_atomic64_set_release(v, i); -} - + raw_atomic64_set_release(v, i); +} + +/** + * atomic64_add() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_add(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_add(i, v); + raw_atomic64_add(i, v); } +/** + * atomic64_add_return() - atomic add with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_return() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_add_return(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_return(i, v); + return raw_atomic64_add_return(i, v); } +/** + * atomic64_add_return_acquire() - atomic add with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_add_return_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_return_acquire(i, v); + return raw_atomic64_add_return_acquire(i, v); } +/** + * atomic64_add_return_release() - atomic add with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_add_return_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_return_release(i, v); + return raw_atomic64_add_return_release(i, v); } +/** + * atomic64_add_return_relaxed() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_add_return_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_return_relaxed(i, v); + return raw_atomic64_add_return_relaxed(i, v); } +/** + * atomic64_fetch_add() - atomic add with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_add() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_add(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_add(i, v); + return raw_atomic64_fetch_add(i, v); } +/** + * atomic64_fetch_add_acquire() - atomic add with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_add_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_add_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_add_acquire(i, v); + return raw_atomic64_fetch_add_acquire(i, v); } +/** + * atomic64_fetch_add_release() - atomic add with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_add_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_add_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_add_release(i, v); + return raw_atomic64_fetch_add_release(i, v); } +/** + * atomic64_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_add_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_add_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_add_relaxed(i, v); + return raw_atomic64_fetch_add_relaxed(i, v); } +/** + * atomic64_sub() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_sub(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_sub(i, v); + raw_atomic64_sub(i, v); } +/** + * atomic64_sub_return() - atomic subtract with full ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub_return() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_sub_return(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_sub_return(i, v); + return raw_atomic64_sub_return(i, v); } +/** + * atomic64_sub_return_acquire() - atomic subtract with acquire ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_sub_return_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_sub_return_acquire(i, v); + return raw_atomic64_sub_return_acquire(i, v); } +/** + * atomic64_sub_return_release() - atomic subtract with release ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_sub_return_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_sub_return_release(i, v); + return raw_atomic64_sub_return_release(i, v); } +/** + * atomic64_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_sub_return_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_sub_return_relaxed(i, v); + return raw_atomic64_sub_return_relaxed(i, v); } +/** + * atomic64_fetch_sub() - atomic subtract with full ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_sub() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_sub(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_sub(i, v); + return raw_atomic64_fetch_sub(i, v); } +/** + * atomic64_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_sub_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_sub_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_sub_acquire(i, v); + return raw_atomic64_fetch_sub_acquire(i, v); } +/** + * atomic64_fetch_sub_release() - atomic subtract with release ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_sub_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_sub_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_sub_release(i, v); + return raw_atomic64_fetch_sub_release(i, v); } +/** + * atomic64_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: s64 value to subtract + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_sub_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_sub_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_sub_relaxed(i, v); + return raw_atomic64_fetch_sub_relaxed(i, v); } +/** + * atomic64_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_inc(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_inc(v); + raw_atomic64_inc(v); } +/** + * atomic64_inc_return() - atomic increment with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_return() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_inc_return(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_return(v); + return raw_atomic64_inc_return(v); } +/** + * atomic64_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_inc_return_acquire(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_return_acquire(v); + return raw_atomic64_inc_return_acquire(v); } +/** + * atomic64_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_inc_return_release(atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_return_release(v); + return raw_atomic64_inc_return_release(v); } +/** + * atomic64_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_inc_return_relaxed(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_return_relaxed(v); + return raw_atomic64_inc_return_relaxed(v); } +/** + * atomic64_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_inc() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_inc(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_inc(v); + return raw_atomic64_fetch_inc(v); } +/** + * atomic64_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_inc_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_inc_acquire(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_inc_acquire(v); + return raw_atomic64_fetch_inc_acquire(v); } +/** + * atomic64_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_inc_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_inc_release(atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_inc_release(v); + return raw_atomic64_fetch_inc_release(v); } +/** + * atomic64_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_inc_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_inc_relaxed(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_inc_relaxed(v); + return raw_atomic64_fetch_inc_relaxed(v); } +/** + * atomic64_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_dec(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_dec(v); + raw_atomic64_dec(v); } +/** + * atomic64_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_return() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_dec_return(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_return(v); + return raw_atomic64_dec_return(v); } +/** + * atomic64_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_dec_return_acquire(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_return_acquire(v); + return raw_atomic64_dec_return_acquire(v); } +/** + * atomic64_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_dec_return_release(atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_return_release(v); + return raw_atomic64_dec_return_release(v); } +/** + * atomic64_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline s64 atomic64_dec_return_relaxed(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_return_relaxed(v); + return raw_atomic64_dec_return_relaxed(v); } +/** + * atomic64_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_dec() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_dec(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_dec(v); + return raw_atomic64_fetch_dec(v); } +/** + * atomic64_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_dec_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_dec_acquire(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_dec_acquire(v); + return raw_atomic64_fetch_dec_acquire(v); } +/** + * atomic64_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_dec_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_dec_release(atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_dec_release(v); + return raw_atomic64_fetch_dec_release(v); } +/** + * atomic64_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_dec_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_dec_relaxed(atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_dec_relaxed(v); + return raw_atomic64_fetch_dec_relaxed(v); } +/** + * atomic64_and() - atomic bitwise AND with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_and() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_and(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_and(i, v); + raw_atomic64_and(i, v); } +/** + * atomic64_fetch_and() - atomic bitwise AND with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_and() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_and(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_and(i, v); + return raw_atomic64_fetch_and(i, v); } +/** + * atomic64_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_and_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_and_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_and_acquire(i, v); + return raw_atomic64_fetch_and_acquire(i, v); } +/** + * atomic64_fetch_and_release() - atomic bitwise AND with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_and_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_and_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_and_release(i, v); + return raw_atomic64_fetch_and_release(i, v); } +/** + * atomic64_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_and_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_and_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_and_relaxed(i, v); + return raw_atomic64_fetch_and_relaxed(i, v); } +/** + * atomic64_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_andnot() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_andnot(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_andnot(i, v); + raw_atomic64_andnot(i, v); } +/** + * atomic64_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_andnot() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_andnot(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_andnot(i, v); + return raw_atomic64_fetch_andnot(i, v); } +/** + * atomic64_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_andnot_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_andnot_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_andnot_acquire(i, v); + return raw_atomic64_fetch_andnot_acquire(i, v); } +/** + * atomic64_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_andnot_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_andnot_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_andnot_release(i, v); + return raw_atomic64_fetch_andnot_release(i, v); } +/** + * atomic64_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_andnot_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_andnot_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_andnot_relaxed(i, v); + return raw_atomic64_fetch_andnot_relaxed(i, v); } +/** + * atomic64_or() - atomic bitwise OR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_or() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_or(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_or(i, v); + raw_atomic64_or(i, v); } +/** + * atomic64_fetch_or() - atomic bitwise OR with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_or() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_or(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_or(i, v); + return raw_atomic64_fetch_or(i, v); } +/** + * atomic64_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_or_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_or_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_or_acquire(i, v); + return raw_atomic64_fetch_or_acquire(i, v); } +/** + * atomic64_fetch_or_release() - atomic bitwise OR with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_or_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_or_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_or_release(i, v); + return raw_atomic64_fetch_or_release(i, v); } +/** + * atomic64_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_or_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_or_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_or_relaxed(i, v); + return raw_atomic64_fetch_or_relaxed(i, v); } +/** + * atomic64_xor() - atomic bitwise XOR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_xor() there. + * + * Return: Nothing. + */ static __always_inline void atomic64_xor(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic64_xor(i, v); + raw_atomic64_xor(i, v); } +/** + * atomic64_fetch_xor() - atomic bitwise XOR with full ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_xor() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_xor(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_xor(i, v); + return raw_atomic64_fetch_xor(i, v); } +/** + * atomic64_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_xor_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_xor_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_xor_acquire(i, v); + return raw_atomic64_fetch_xor_acquire(i, v); } +/** + * atomic64_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_xor_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_xor_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_xor_release(i, v); + return raw_atomic64_fetch_xor_release(i, v); } +/** + * atomic64_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: s64 value + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_xor_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_xor_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_xor_relaxed(i, v); + return raw_atomic64_fetch_xor_relaxed(i, v); } +/** + * atomic64_xchg() - atomic exchange with full ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_xchg() there. + * + * Return: The original value of @v. + */ static __always_inline s64 -atomic64_xchg(atomic64_t *v, s64 i) +atomic64_xchg(atomic64_t *v, s64 new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_xchg(v, i); + return raw_atomic64_xchg(v, new); } +/** + * atomic64_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_xchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 -atomic64_xchg_acquire(atomic64_t *v, s64 i) +atomic64_xchg_acquire(atomic64_t *v, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_xchg_acquire(v, i); + return raw_atomic64_xchg_acquire(v, new); } +/** + * atomic64_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_xchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 -atomic64_xchg_release(atomic64_t *v, s64 i) +atomic64_xchg_release(atomic64_t *v, s64 new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_xchg_release(v, i); + return raw_atomic64_xchg_release(v, new); } +/** + * atomic64_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic64_t + * @new: s64 value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_xchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 -atomic64_xchg_relaxed(atomic64_t *v, s64 i) +atomic64_xchg_relaxed(atomic64_t *v, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_xchg_relaxed(v, i); + return raw_atomic64_xchg_relaxed(v, new); } +/** + * atomic64_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_cmpxchg() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_cmpxchg(v, old, new); + return raw_atomic64_cmpxchg(v, old, new); } +/** + * atomic64_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_cmpxchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_cmpxchg_acquire(atomic64_t *v, s64 old, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_cmpxchg_acquire(v, old, new); + return raw_atomic64_cmpxchg_acquire(v, old, new); } +/** + * atomic64_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_cmpxchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_cmpxchg_release(atomic64_t *v, s64 old, s64 new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_cmpxchg_release(v, old, new); + return raw_atomic64_cmpxchg_release(v, old, new); } +/** + * atomic64_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic64_t + * @old: s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_cmpxchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_cmpxchg_relaxed(atomic64_t *v, s64 old, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_cmpxchg_relaxed(v, old, new); + return raw_atomic64_cmpxchg_relaxed(v, old, new); } +/** + * atomic64_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic64_try_cmpxchg() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, s64 *old, s64 new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic64_try_cmpxchg(v, old, new); -} - + return raw_atomic64_try_cmpxchg(v, old, new); +} + +/** + * atomic64_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic64_try_cmpxchg_acquire() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic64_try_cmpxchg_acquire(atomic64_t *v, s64 *old, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic64_try_cmpxchg_acquire(v, old, new); -} - + return raw_atomic64_try_cmpxchg_acquire(v, old, new); +} + +/** + * atomic64_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic64_try_cmpxchg_release() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic64_try_cmpxchg_release(atomic64_t *v, s64 *old, s64 new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic64_try_cmpxchg_release(v, old, new); -} - + return raw_atomic64_try_cmpxchg_release(v, old, new); +} + +/** + * atomic64_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic64_t + * @old: pointer to s64 value to compare with + * @new: s64 value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic64_try_cmpxchg_relaxed() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic64_try_cmpxchg_relaxed(atomic64_t *v, s64 *old, s64 new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic64_try_cmpxchg_relaxed(v, old, new); -} - + return raw_atomic64_try_cmpxchg_relaxed(v, old, new); +} + +/** + * atomic64_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_sub_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic64_sub_and_test(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_sub_and_test(i, v); + return raw_atomic64_sub_and_test(i, v); } +/** + * atomic64_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic64_dec_and_test(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_and_test(v); + return raw_atomic64_dec_and_test(v); } +/** + * atomic64_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic64_inc_and_test(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_and_test(v); + return raw_atomic64_inc_and_test(v); } +/** + * atomic64_add_negative() - atomic add and test if negative with full ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_negative() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic64_add_negative(s64 i, atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_negative(i, v); + return raw_atomic64_add_negative(i, v); } +/** + * atomic64_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_negative_acquire() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic64_add_negative_acquire(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_negative_acquire(i, v); + return raw_atomic64_add_negative_acquire(i, v); } +/** + * atomic64_add_negative_release() - atomic add and test if negative with release ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_negative_release() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic64_add_negative_release(s64 i, atomic64_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_negative_release(i, v); + return raw_atomic64_add_negative_release(i, v); } +/** + * atomic64_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: s64 value to add + * @v: pointer to atomic64_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_negative_relaxed() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic64_add_negative_relaxed(s64 i, atomic64_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_negative_relaxed(i, v); + return raw_atomic64_add_negative_relaxed(i, v); } +/** + * atomic64_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic64_t + * @a: s64 value to add + * @u: s64 value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_fetch_add_unless() there. + * + * Return: The original value of @v. + */ static __always_inline s64 atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_fetch_add_unless(v, a, u); + return raw_atomic64_fetch_add_unless(v, a, u); } +/** + * atomic64_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic64_t + * @a: s64 value to add + * @u: s64 value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_add_unless() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic64_add_unless(atomic64_t *v, s64 a, s64 u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_add_unless(v, a, u); + return raw_atomic64_add_unless(v, a, u); } +/** + * atomic64_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic64_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_not_zero() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic64_inc_not_zero(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_not_zero(v); + return raw_atomic64_inc_not_zero(v); } +/** + * atomic64_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic64_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_inc_unless_negative() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic64_inc_unless_negative(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_inc_unless_negative(v); + return raw_atomic64_inc_unless_negative(v); } +/** + * atomic64_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic64_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_unless_positive() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic64_dec_unless_positive(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_unless_positive(v); + return raw_atomic64_dec_unless_positive(v); } +/** + * atomic64_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic64_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic64_dec_if_positive() there. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline s64 atomic64_dec_if_positive(atomic64_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic64_dec_if_positive(v); + return raw_atomic64_dec_if_positive(v); } +/** + * atomic_long_read() - atomic load with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_read() there. + * + * Return: The value loaded from @v. + */ static __always_inline long atomic_long_read(const atomic_long_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic_long_read(v); -} - + return raw_atomic_long_read(v); +} + +/** + * atomic_long_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_read_acquire() there. + * + * Return: The value loaded from @v. + */ static __always_inline long atomic_long_read_acquire(const atomic_long_t *v) { instrument_atomic_read(v, sizeof(*v)); - return arch_atomic_long_read_acquire(v); -} - + return raw_atomic_long_read_acquire(v); +} + +/** + * atomic_long_set() - atomic set with relaxed ordering + * @v: pointer to atomic_long_t + * @i: long value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_set() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_set(atomic_long_t *v, long i) { instrument_atomic_write(v, sizeof(*v)); - arch_atomic_long_set(v, i); -} - + raw_atomic_long_set(v, i); +} + +/** + * atomic_long_set_release() - atomic set with release ordering + * @v: pointer to atomic_long_t + * @i: long value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_set_release() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_set_release(atomic_long_t *v, long i) { kcsan_release(); instrument_atomic_write(v, sizeof(*v)); - arch_atomic_long_set_release(v, i); -} - + raw_atomic_long_set_release(v, i); +} + +/** + * atomic_long_add() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_add(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_add(i, v); + raw_atomic_long_add(i, v); } +/** + * atomic_long_add_return() - atomic add with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_return() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_add_return(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_return(i, v); + return raw_atomic_long_add_return(i, v); } +/** + * atomic_long_add_return_acquire() - atomic add with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_add_return_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_return_acquire(i, v); + return raw_atomic_long_add_return_acquire(i, v); } +/** + * atomic_long_add_return_release() - atomic add with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_add_return_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_return_release(i, v); + return raw_atomic_long_add_return_release(i, v); } +/** + * atomic_long_add_return_relaxed() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_add_return_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_return_relaxed(i, v); + return raw_atomic_long_add_return_relaxed(i, v); } +/** + * atomic_long_fetch_add() - atomic add with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_add() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_add(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_add(i, v); + return raw_atomic_long_fetch_add(i, v); } +/** + * atomic_long_fetch_add_acquire() - atomic add with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_add_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_add_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_add_acquire(i, v); + return raw_atomic_long_fetch_add_acquire(i, v); } +/** + * atomic_long_fetch_add_release() - atomic add with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_add_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_add_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_add_release(i, v); + return raw_atomic_long_fetch_add_release(i, v); } +/** + * atomic_long_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_add_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_add_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_add_relaxed(i, v); + return raw_atomic_long_fetch_add_relaxed(i, v); } +/** + * atomic_long_sub() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_sub(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_sub(i, v); + raw_atomic_long_sub(i, v); } +/** + * atomic_long_sub_return() - atomic subtract with full ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub_return() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_sub_return(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_sub_return(i, v); + return raw_atomic_long_sub_return(i, v); } +/** + * atomic_long_sub_return_acquire() - atomic subtract with acquire ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_sub_return_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_sub_return_acquire(i, v); + return raw_atomic_long_sub_return_acquire(i, v); } +/** + * atomic_long_sub_return_release() - atomic subtract with release ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_sub_return_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_sub_return_release(i, v); + return raw_atomic_long_sub_return_release(i, v); } +/** + * atomic_long_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_sub_return_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_sub_return_relaxed(i, v); + return raw_atomic_long_sub_return_relaxed(i, v); } +/** + * atomic_long_fetch_sub() - atomic subtract with full ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_sub() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_sub(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_sub(i, v); + return raw_atomic_long_fetch_sub(i, v); } +/** + * atomic_long_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_sub_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_sub_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_sub_acquire(i, v); + return raw_atomic_long_fetch_sub_acquire(i, v); } +/** + * atomic_long_fetch_sub_release() - atomic subtract with release ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_sub_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_sub_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_sub_release(i, v); + return raw_atomic_long_fetch_sub_release(i, v); } +/** + * atomic_long_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_sub_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_sub_relaxed(i, v); + return raw_atomic_long_fetch_sub_relaxed(i, v); } +/** + * atomic_long_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_inc(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_inc(v); + raw_atomic_long_inc(v); } +/** + * atomic_long_inc_return() - atomic increment with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_return() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_inc_return(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_return(v); + return raw_atomic_long_inc_return(v); } +/** + * atomic_long_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_inc_return_acquire(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_return_acquire(v); + return raw_atomic_long_inc_return_acquire(v); } +/** + * atomic_long_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_inc_return_release(atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_return_release(v); + return raw_atomic_long_inc_return_release(v); } +/** + * atomic_long_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_inc_return_relaxed(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_return_relaxed(v); + return raw_atomic_long_inc_return_relaxed(v); } +/** + * atomic_long_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_inc() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_inc(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_inc(v); + return raw_atomic_long_fetch_inc(v); } +/** + * atomic_long_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_inc_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_inc_acquire(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_inc_acquire(v); + return raw_atomic_long_fetch_inc_acquire(v); } +/** + * atomic_long_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_inc_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_inc_release(atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_inc_release(v); + return raw_atomic_long_fetch_inc_release(v); } +/** + * atomic_long_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_inc_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_inc_relaxed(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_inc_relaxed(v); + return raw_atomic_long_fetch_inc_relaxed(v); } +/** + * atomic_long_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_dec(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_dec(v); + raw_atomic_long_dec(v); } +/** + * atomic_long_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_return() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_dec_return(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_return(v); + return raw_atomic_long_dec_return(v); } +/** + * atomic_long_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_return_acquire() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_dec_return_acquire(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_return_acquire(v); + return raw_atomic_long_dec_return_acquire(v); } +/** + * atomic_long_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_return_release() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_dec_return_release(atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_return_release(v); + return raw_atomic_long_dec_return_release(v); } +/** + * atomic_long_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_return_relaxed() there. + * + * Return: The updated value of @v. + */ static __always_inline long atomic_long_dec_return_relaxed(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_return_relaxed(v); + return raw_atomic_long_dec_return_relaxed(v); } +/** + * atomic_long_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_dec() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_dec(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_dec(v); + return raw_atomic_long_fetch_dec(v); } +/** + * atomic_long_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_dec_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_dec_acquire(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_dec_acquire(v); + return raw_atomic_long_fetch_dec_acquire(v); } +/** + * atomic_long_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_dec_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_dec_release(atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_dec_release(v); + return raw_atomic_long_fetch_dec_release(v); } +/** + * atomic_long_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_dec_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_dec_relaxed(atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_dec_relaxed(v); + return raw_atomic_long_fetch_dec_relaxed(v); } +/** + * atomic_long_and() - atomic bitwise AND with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_and() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_and(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_and(i, v); + raw_atomic_long_and(i, v); } +/** + * atomic_long_fetch_and() - atomic bitwise AND with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_and() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_and(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_and(i, v); + return raw_atomic_long_fetch_and(i, v); } +/** + * atomic_long_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_and_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_and_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_and_acquire(i, v); + return raw_atomic_long_fetch_and_acquire(i, v); } +/** + * atomic_long_fetch_and_release() - atomic bitwise AND with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_and_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_and_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_and_release(i, v); + return raw_atomic_long_fetch_and_release(i, v); } +/** + * atomic_long_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_and_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_and_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_and_relaxed(i, v); + return raw_atomic_long_fetch_and_relaxed(i, v); } +/** + * atomic_long_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_andnot() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_andnot(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_andnot(i, v); + raw_atomic_long_andnot(i, v); } +/** + * atomic_long_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_andnot() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_andnot(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_andnot(i, v); + return raw_atomic_long_fetch_andnot(i, v); } +/** + * atomic_long_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_andnot_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_andnot_acquire(i, v); + return raw_atomic_long_fetch_andnot_acquire(i, v); } +/** + * atomic_long_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_andnot_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_andnot_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_andnot_release(i, v); + return raw_atomic_long_fetch_andnot_release(i, v); } +/** + * atomic_long_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_andnot_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_andnot_relaxed(i, v); + return raw_atomic_long_fetch_andnot_relaxed(i, v); } +/** + * atomic_long_or() - atomic bitwise OR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_or() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_or(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_or(i, v); + raw_atomic_long_or(i, v); } +/** + * atomic_long_fetch_or() - atomic bitwise OR with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_or() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_or(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_or(i, v); + return raw_atomic_long_fetch_or(i, v); } +/** + * atomic_long_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_or_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_or_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_or_acquire(i, v); + return raw_atomic_long_fetch_or_acquire(i, v); } +/** + * atomic_long_fetch_or_release() - atomic bitwise OR with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_or_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_or_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_or_release(i, v); + return raw_atomic_long_fetch_or_release(i, v); } +/** + * atomic_long_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_or_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_or_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_or_relaxed(i, v); + return raw_atomic_long_fetch_or_relaxed(i, v); } +/** + * atomic_long_xor() - atomic bitwise XOR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_xor() there. + * + * Return: Nothing. + */ static __always_inline void atomic_long_xor(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - arch_atomic_long_xor(i, v); + raw_atomic_long_xor(i, v); } +/** + * atomic_long_fetch_xor() - atomic bitwise XOR with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_xor() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_xor(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_xor(i, v); + return raw_atomic_long_fetch_xor(i, v); } +/** + * atomic_long_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_xor_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_xor_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_xor_acquire(i, v); + return raw_atomic_long_fetch_xor_acquire(i, v); } +/** + * atomic_long_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_xor_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_xor_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_xor_release(i, v); + return raw_atomic_long_fetch_xor_release(i, v); } +/** + * atomic_long_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_xor_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_xor_relaxed(i, v); + return raw_atomic_long_fetch_xor_relaxed(i, v); } +/** + * atomic_long_xchg() - atomic exchange with full ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_xchg() there. + * + * Return: The original value of @v. + */ static __always_inline long -atomic_long_xchg(atomic_long_t *v, long i) +atomic_long_xchg(atomic_long_t *v, long new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_xchg(v, i); + return raw_atomic_long_xchg(v, new); } +/** + * atomic_long_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_xchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long -atomic_long_xchg_acquire(atomic_long_t *v, long i) +atomic_long_xchg_acquire(atomic_long_t *v, long new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_xchg_acquire(v, i); + return raw_atomic_long_xchg_acquire(v, new); } +/** + * atomic_long_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_xchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline long -atomic_long_xchg_release(atomic_long_t *v, long i) +atomic_long_xchg_release(atomic_long_t *v, long new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_xchg_release(v, i); + return raw_atomic_long_xchg_release(v, new); } +/** + * atomic_long_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_xchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long -atomic_long_xchg_relaxed(atomic_long_t *v, long i) +atomic_long_xchg_relaxed(atomic_long_t *v, long new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_xchg_relaxed(v, i); + return raw_atomic_long_xchg_relaxed(v, new); } +/** + * atomic_long_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_cmpxchg() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_cmpxchg(atomic_long_t *v, long old, long new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_cmpxchg(v, old, new); + return raw_atomic_long_cmpxchg(v, old, new); } +/** + * atomic_long_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_cmpxchg_acquire() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_cmpxchg_acquire(v, old, new); + return raw_atomic_long_cmpxchg_acquire(v, old, new); } +/** + * atomic_long_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_cmpxchg_release() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_cmpxchg_release(v, old, new); + return raw_atomic_long_cmpxchg_release(v, old, new); } +/** + * atomic_long_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_cmpxchg_relaxed() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_cmpxchg_relaxed(v, old, new); + return raw_atomic_long_cmpxchg_relaxed(v, old, new); } +/** + * atomic_long_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_long_try_cmpxchg() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_long_try_cmpxchg(v, old, new); -} - + return raw_atomic_long_try_cmpxchg(v, old, new); +} + +/** + * atomic_long_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_long_try_cmpxchg_acquire() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_long_try_cmpxchg_acquire(v, old, new); -} - + return raw_atomic_long_try_cmpxchg_acquire(v, old, new); +} + +/** + * atomic_long_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_long_try_cmpxchg_release() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_long_try_cmpxchg_release(v, old, new); -} - + return raw_atomic_long_try_cmpxchg_release(v, old, new); +} + +/** + * atomic_long_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Unsafe to use in noinstr code; use raw_atomic_long_try_cmpxchg_relaxed() there. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new) { instrument_atomic_read_write(v, sizeof(*v)); instrument_atomic_read_write(old, sizeof(*old)); - return arch_atomic_long_try_cmpxchg_relaxed(v, old, new); -} - + return raw_atomic_long_try_cmpxchg_relaxed(v, old, new); +} + +/** + * atomic_long_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_sub_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_long_sub_and_test(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_sub_and_test(i, v); + return raw_atomic_long_sub_and_test(i, v); } +/** + * atomic_long_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_long_dec_and_test(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_and_test(v); + return raw_atomic_long_dec_and_test(v); } +/** + * atomic_long_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_and_test() there. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool atomic_long_inc_and_test(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_and_test(v); + return raw_atomic_long_inc_and_test(v); } +/** + * atomic_long_add_negative() - atomic add and test if negative with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_negative() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_long_add_negative(long i, atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_negative(i, v); + return raw_atomic_long_add_negative(i, v); } +/** + * atomic_long_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_negative_acquire() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_long_add_negative_acquire(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_negative_acquire(i, v); + return raw_atomic_long_add_negative_acquire(i, v); } +/** + * atomic_long_add_negative_release() - atomic add and test if negative with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_negative_release() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_long_add_negative_release(long i, atomic_long_t *v) { kcsan_release(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_negative_release(i, v); + return raw_atomic_long_add_negative_release(i, v); } +/** + * atomic_long_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_negative_relaxed() there. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool atomic_long_add_negative_relaxed(long i, atomic_long_t *v) { instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_negative_relaxed(i, v); + return raw_atomic_long_add_negative_relaxed(i, v); } +/** + * atomic_long_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_long_t + * @a: long value to add + * @u: long value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_fetch_add_unless() there. + * + * Return: The original value of @v. + */ static __always_inline long atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_fetch_add_unless(v, a, u); + return raw_atomic_long_fetch_add_unless(v, a, u); } +/** + * atomic_long_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_long_t + * @a: long value to add + * @u: long value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_add_unless() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_long_add_unless(atomic_long_t *v, long a, long u) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_add_unless(v, a, u); + return raw_atomic_long_add_unless(v, a, u); } +/** + * atomic_long_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic_long_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_not_zero() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_long_inc_not_zero(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_not_zero(v); + return raw_atomic_long_inc_not_zero(v); } +/** + * atomic_long_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic_long_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_inc_unless_negative() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_long_inc_unless_negative(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_inc_unless_negative(v); + return raw_atomic_long_inc_unless_negative(v); } +/** + * atomic_long_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic_long_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_unless_positive() there. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool atomic_long_dec_unless_positive(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_unless_positive(v); + return raw_atomic_long_dec_unless_positive(v); } +/** + * atomic_long_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic_long_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Unsafe to use in noinstr code; use raw_atomic_long_dec_if_positive() there. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline long atomic_long_dec_if_positive(atomic_long_t *v) { kcsan_mb(); instrument_atomic_read_write(v, sizeof(*v)); - return arch_atomic_long_dec_if_positive(v); + return raw_atomic_long_dec_if_positive(v); } #define xchg(ptr, ...) \ @@ -1949,14 +4713,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_xchg(__ai_ptr, __VA_ARGS__); \ + raw_xchg(__ai_ptr, __VA_ARGS__); \ }) #define xchg_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_xchg_acquire(__ai_ptr, __VA_ARGS__); \ + raw_xchg_acquire(__ai_ptr, __VA_ARGS__); \ }) #define xchg_release(ptr, ...) \ @@ -1964,14 +4728,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_xchg_release(__ai_ptr, __VA_ARGS__); \ + raw_xchg_release(__ai_ptr, __VA_ARGS__); \ }) #define xchg_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_xchg_relaxed(__ai_ptr, __VA_ARGS__); \ + raw_xchg_relaxed(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg(ptr, ...) \ @@ -1979,14 +4743,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg_acquire(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg_acquire(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg_release(ptr, ...) \ @@ -1994,14 +4758,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg_release(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg_release(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg_relaxed(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg_relaxed(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64(ptr, ...) \ @@ -2009,14 +4773,14 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg64(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg64(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_acquire(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg64_acquire(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg64_acquire(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_release(ptr, ...) \ @@ -2024,14 +4788,44 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_release(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg64_release(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg64_release(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_relaxed(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg64_relaxed(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg64_relaxed(__ai_ptr, __VA_ARGS__); \ +}) + +#define cmpxchg128(ptr, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + kcsan_mb(); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + raw_cmpxchg128(__ai_ptr, __VA_ARGS__); \ +}) + +#define cmpxchg128_acquire(ptr, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + raw_cmpxchg128_acquire(__ai_ptr, __VA_ARGS__); \ +}) + +#define cmpxchg128_release(ptr, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + kcsan_release(); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + raw_cmpxchg128_release(__ai_ptr, __VA_ARGS__); \ +}) + +#define cmpxchg128_relaxed(ptr, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + raw_cmpxchg128_relaxed(__ai_ptr, __VA_ARGS__); \ }) #define try_cmpxchg(ptr, oldp, ...) \ @@ -2041,7 +4835,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg_acquire(ptr, oldp, ...) \ @@ -2050,7 +4844,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg_release(ptr, oldp, ...) \ @@ -2060,7 +4854,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) kcsan_release(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg_relaxed(ptr, oldp, ...) \ @@ -2069,7 +4863,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg64(ptr, oldp, ...) \ @@ -2079,7 +4873,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg64(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg64(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg64_acquire(ptr, oldp, ...) \ @@ -2088,7 +4882,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg64_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg64_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg64_release(ptr, oldp, ...) \ @@ -2098,7 +4892,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) kcsan_release(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg64_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg64_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg64_relaxed(ptr, oldp, ...) \ @@ -2107,21 +4901,66 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg64_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg64_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg128(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + kcsan_mb(); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ + raw_try_cmpxchg128(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg128_acquire(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ + raw_try_cmpxchg128_acquire(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg128_release(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + kcsan_release(); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ + raw_try_cmpxchg128_release(__ai_ptr, __ai_oldp, __VA_ARGS__); \ +}) + +#define try_cmpxchg128_relaxed(ptr, oldp, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + typeof(oldp) __ai_oldp = (oldp); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ + raw_try_cmpxchg128_relaxed(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define cmpxchg_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg_local(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg_local(__ai_ptr, __VA_ARGS__); \ }) #define cmpxchg64_local(ptr, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_cmpxchg64_local(__ai_ptr, __VA_ARGS__); \ + raw_cmpxchg64_local(__ai_ptr, __VA_ARGS__); \ +}) + +#define cmpxchg128_local(ptr, ...) \ +({ \ + typeof(ptr) __ai_ptr = (ptr); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + raw_cmpxchg128_local(__ai_ptr, __VA_ARGS__); \ }) #define sync_cmpxchg(ptr, ...) \ @@ -2129,7 +4968,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(ptr) __ai_ptr = (ptr); \ kcsan_mb(); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ - arch_sync_cmpxchg(__ai_ptr, __VA_ARGS__); \ + raw_sync_cmpxchg(__ai_ptr, __VA_ARGS__); \ }) #define try_cmpxchg_local(ptr, oldp, ...) \ @@ -2138,7 +4977,7 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) #define try_cmpxchg64_local(ptr, oldp, ...) \ @@ -2147,24 +4986,18 @@ atomic_long_dec_if_positive(atomic_long_t *v) typeof(oldp) __ai_oldp = (oldp); \ instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ - arch_try_cmpxchg64_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ + raw_try_cmpxchg64_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) -#define cmpxchg_double(ptr, ...) \ +#define try_cmpxchg128_local(ptr, oldp, ...) \ ({ \ typeof(ptr) __ai_ptr = (ptr); \ - kcsan_mb(); \ - instrument_atomic_read_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ - arch_cmpxchg_double(__ai_ptr, __VA_ARGS__); \ + typeof(oldp) __ai_oldp = (oldp); \ + instrument_atomic_read_write(__ai_ptr, sizeof(*__ai_ptr)); \ + instrument_read_write(__ai_oldp, sizeof(*__ai_oldp)); \ + raw_try_cmpxchg128_local(__ai_ptr, __ai_oldp, __VA_ARGS__); \ }) -#define cmpxchg_double_local(ptr, ...) \ -({ \ - typeof(ptr) __ai_ptr = (ptr); \ - instrument_atomic_read_write(__ai_ptr, 2 * sizeof(*__ai_ptr)); \ - arch_cmpxchg_double_local(__ai_ptr, __VA_ARGS__); \ -}) - #endif /* _LINUX_ATOMIC_INSTRUMENTED_H */ -// 6b513a42e1a1b5962532a019b7fc91eaa044ad5e +// 1568f875fef72097413caab8339120c065a39aa4 diff --git a/include/linux/atomic/atomic-long.h b/include/linux/atomic/atomic-long.h index 2fc51ba66beb..c82947170ddc 100644 --- a/include/linux/atomic/atomic-long.h +++ b/include/linux/atomic/atomic-long.h @@ -21,1030 +21,1778 @@ typedef atomic_t atomic_long_t; #define atomic_long_cond_read_relaxed atomic_cond_read_relaxed #endif -#ifdef CONFIG_64BIT - -static __always_inline long -arch_atomic_long_read(const atomic_long_t *v) -{ - return arch_atomic64_read(v); -} - -static __always_inline long -arch_atomic_long_read_acquire(const atomic_long_t *v) -{ - return arch_atomic64_read_acquire(v); -} - -static __always_inline void -arch_atomic_long_set(atomic_long_t *v, long i) -{ - arch_atomic64_set(v, i); -} - -static __always_inline void -arch_atomic_long_set_release(atomic_long_t *v, long i) -{ - arch_atomic64_set_release(v, i); -} - -static __always_inline void -arch_atomic_long_add(long i, atomic_long_t *v) -{ - arch_atomic64_add(i, v); -} - -static __always_inline long -arch_atomic_long_add_return(long i, atomic_long_t *v) -{ - return arch_atomic64_add_return(i, v); -} - -static __always_inline long -arch_atomic_long_add_return_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_add_return_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_add_return_release(long i, atomic_long_t *v) -{ - return arch_atomic64_add_return_release(i, v); -} - -static __always_inline long -arch_atomic_long_add_return_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_add_return_relaxed(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_add(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_add(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_add_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_add_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_add_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_add_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_add_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_add_relaxed(i, v); -} - -static __always_inline void -arch_atomic_long_sub(long i, atomic_long_t *v) -{ - arch_atomic64_sub(i, v); -} - -static __always_inline long -arch_atomic_long_sub_return(long i, atomic_long_t *v) -{ - return arch_atomic64_sub_return(i, v); -} - -static __always_inline long -arch_atomic_long_sub_return_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_sub_return_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_sub_return_release(long i, atomic_long_t *v) -{ - return arch_atomic64_sub_return_release(i, v); -} - -static __always_inline long -arch_atomic_long_sub_return_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_sub_return_relaxed(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_sub(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_sub(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_sub_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_sub_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_sub_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_sub_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_sub_relaxed(i, v); -} - -static __always_inline void -arch_atomic_long_inc(atomic_long_t *v) -{ - arch_atomic64_inc(v); -} - -static __always_inline long -arch_atomic_long_inc_return(atomic_long_t *v) -{ - return arch_atomic64_inc_return(v); -} - -static __always_inline long -arch_atomic_long_inc_return_acquire(atomic_long_t *v) -{ - return arch_atomic64_inc_return_acquire(v); -} - -static __always_inline long -arch_atomic_long_inc_return_release(atomic_long_t *v) -{ - return arch_atomic64_inc_return_release(v); -} - -static __always_inline long -arch_atomic_long_inc_return_relaxed(atomic_long_t *v) -{ - return arch_atomic64_inc_return_relaxed(v); -} - -static __always_inline long -arch_atomic_long_fetch_inc(atomic_long_t *v) -{ - return arch_atomic64_fetch_inc(v); -} - -static __always_inline long -arch_atomic_long_fetch_inc_acquire(atomic_long_t *v) -{ - return arch_atomic64_fetch_inc_acquire(v); -} - -static __always_inline long -arch_atomic_long_fetch_inc_release(atomic_long_t *v) -{ - return arch_atomic64_fetch_inc_release(v); -} - -static __always_inline long -arch_atomic_long_fetch_inc_relaxed(atomic_long_t *v) -{ - return arch_atomic64_fetch_inc_relaxed(v); -} - -static __always_inline void -arch_atomic_long_dec(atomic_long_t *v) -{ - arch_atomic64_dec(v); -} - -static __always_inline long -arch_atomic_long_dec_return(atomic_long_t *v) -{ - return arch_atomic64_dec_return(v); -} - -static __always_inline long -arch_atomic_long_dec_return_acquire(atomic_long_t *v) -{ - return arch_atomic64_dec_return_acquire(v); -} - -static __always_inline long -arch_atomic_long_dec_return_release(atomic_long_t *v) -{ - return arch_atomic64_dec_return_release(v); -} - -static __always_inline long -arch_atomic_long_dec_return_relaxed(atomic_long_t *v) -{ - return arch_atomic64_dec_return_relaxed(v); -} - -static __always_inline long -arch_atomic_long_fetch_dec(atomic_long_t *v) -{ - return arch_atomic64_fetch_dec(v); -} - -static __always_inline long -arch_atomic_long_fetch_dec_acquire(atomic_long_t *v) -{ - return arch_atomic64_fetch_dec_acquire(v); -} - -static __always_inline long -arch_atomic_long_fetch_dec_release(atomic_long_t *v) -{ - return arch_atomic64_fetch_dec_release(v); -} - -static __always_inline long -arch_atomic_long_fetch_dec_relaxed(atomic_long_t *v) -{ - return arch_atomic64_fetch_dec_relaxed(v); -} - -static __always_inline void -arch_atomic_long_and(long i, atomic_long_t *v) -{ - arch_atomic64_and(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_and(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_and(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_and_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_and_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_and_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_and_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_and_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_and_relaxed(i, v); -} - -static __always_inline void -arch_atomic_long_andnot(long i, atomic_long_t *v) -{ - arch_atomic64_andnot(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_andnot(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_andnot(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_andnot_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_andnot_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_andnot_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_andnot_relaxed(i, v); -} - -static __always_inline void -arch_atomic_long_or(long i, atomic_long_t *v) -{ - arch_atomic64_or(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_or(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_or(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_or_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_or_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_or_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_or_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_or_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_or_relaxed(i, v); -} - -static __always_inline void -arch_atomic_long_xor(long i, atomic_long_t *v) -{ - arch_atomic64_xor(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_xor(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_xor(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_xor_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_xor_acquire(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_xor_release(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_xor_release(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_fetch_xor_relaxed(i, v); -} - -static __always_inline long -arch_atomic_long_xchg(atomic_long_t *v, long i) -{ - return arch_atomic64_xchg(v, i); -} - -static __always_inline long -arch_atomic_long_xchg_acquire(atomic_long_t *v, long i) -{ - return arch_atomic64_xchg_acquire(v, i); -} - -static __always_inline long -arch_atomic_long_xchg_release(atomic_long_t *v, long i) -{ - return arch_atomic64_xchg_release(v, i); -} - -static __always_inline long -arch_atomic_long_xchg_relaxed(atomic_long_t *v, long i) -{ - return arch_atomic64_xchg_relaxed(v, i); -} - -static __always_inline long -arch_atomic_long_cmpxchg(atomic_long_t *v, long old, long new) -{ - return arch_atomic64_cmpxchg(v, old, new); -} - -static __always_inline long -arch_atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new) +/** + * raw_atomic_long_read() - atomic load with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically loads the value of @v with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_read() elsewhere. + * + * Return: The value loaded from @v. + */ +static __always_inline long +raw_atomic_long_read(const atomic_long_t *v) { - return arch_atomic64_cmpxchg_acquire(v, old, new); -} - -static __always_inline long -arch_atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new) -{ - return arch_atomic64_cmpxchg_release(v, old, new); -} - -static __always_inline long -arch_atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new) -{ - return arch_atomic64_cmpxchg_relaxed(v, old, new); -} - -static __always_inline bool -arch_atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new) -{ - return arch_atomic64_try_cmpxchg(v, (s64 *)old, new); -} - -static __always_inline bool -arch_atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new) -{ - return arch_atomic64_try_cmpxchg_acquire(v, (s64 *)old, new); -} - -static __always_inline bool -arch_atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new) -{ - return arch_atomic64_try_cmpxchg_release(v, (s64 *)old, new); -} - -static __always_inline bool -arch_atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new) -{ - return arch_atomic64_try_cmpxchg_relaxed(v, (s64 *)old, new); -} - -static __always_inline bool -arch_atomic_long_sub_and_test(long i, atomic_long_t *v) -{ - return arch_atomic64_sub_and_test(i, v); -} - -static __always_inline bool -arch_atomic_long_dec_and_test(atomic_long_t *v) -{ - return arch_atomic64_dec_and_test(v); -} - -static __always_inline bool -arch_atomic_long_inc_and_test(atomic_long_t *v) -{ - return arch_atomic64_inc_and_test(v); -} - -static __always_inline bool -arch_atomic_long_add_negative(long i, atomic_long_t *v) -{ - return arch_atomic64_add_negative(i, v); -} - -static __always_inline bool -arch_atomic_long_add_negative_acquire(long i, atomic_long_t *v) -{ - return arch_atomic64_add_negative_acquire(i, v); -} - -static __always_inline bool -arch_atomic_long_add_negative_release(long i, atomic_long_t *v) -{ - return arch_atomic64_add_negative_release(i, v); -} - -static __always_inline bool -arch_atomic_long_add_negative_relaxed(long i, atomic_long_t *v) -{ - return arch_atomic64_add_negative_relaxed(i, v); -} - -static __always_inline long -arch_atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) -{ - return arch_atomic64_fetch_add_unless(v, a, u); -} - -static __always_inline bool -arch_atomic_long_add_unless(atomic_long_t *v, long a, long u) -{ - return arch_atomic64_add_unless(v, a, u); -} - -static __always_inline bool -arch_atomic_long_inc_not_zero(atomic_long_t *v) -{ - return arch_atomic64_inc_not_zero(v); -} - -static __always_inline bool -arch_atomic_long_inc_unless_negative(atomic_long_t *v) -{ - return arch_atomic64_inc_unless_negative(v); -} - -static __always_inline bool -arch_atomic_long_dec_unless_positive(atomic_long_t *v) -{ - return arch_atomic64_dec_unless_positive(v); -} - -static __always_inline long -arch_atomic_long_dec_if_positive(atomic_long_t *v) -{ - return arch_atomic64_dec_if_positive(v); -} - -#else /* CONFIG_64BIT */ - -static __always_inline long -arch_atomic_long_read(const atomic_long_t *v) -{ - return arch_atomic_read(v); +#ifdef CONFIG_64BIT + return raw_atomic64_read(v); +#else + return raw_atomic_read(v); +#endif } +/** + * raw_atomic_long_read_acquire() - atomic load with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically loads the value of @v with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_read_acquire() elsewhere. + * + * Return: The value loaded from @v. + */ static __always_inline long -arch_atomic_long_read_acquire(const atomic_long_t *v) +raw_atomic_long_read_acquire(const atomic_long_t *v) { - return arch_atomic_read_acquire(v); +#ifdef CONFIG_64BIT + return raw_atomic64_read_acquire(v); +#else + return raw_atomic_read_acquire(v); +#endif } +/** + * raw_atomic_long_set() - atomic set with relaxed ordering + * @v: pointer to atomic_long_t + * @i: long value to assign + * + * Atomically sets @v to @i with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_set() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_set(atomic_long_t *v, long i) +raw_atomic_long_set(atomic_long_t *v, long i) { - arch_atomic_set(v, i); +#ifdef CONFIG_64BIT + raw_atomic64_set(v, i); +#else + raw_atomic_set(v, i); +#endif } +/** + * raw_atomic_long_set_release() - atomic set with release ordering + * @v: pointer to atomic_long_t + * @i: long value to assign + * + * Atomically sets @v to @i with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_set_release() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_set_release(atomic_long_t *v, long i) +raw_atomic_long_set_release(atomic_long_t *v, long i) { - arch_atomic_set_release(v, i); +#ifdef CONFIG_64BIT + raw_atomic64_set_release(v, i); +#else + raw_atomic_set_release(v, i); +#endif } +/** + * raw_atomic_long_add() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_add(long i, atomic_long_t *v) +raw_atomic_long_add(long i, atomic_long_t *v) { - arch_atomic_add(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_add(i, v); +#else + raw_atomic_add(i, v); +#endif } +/** + * raw_atomic_long_add_return() - atomic add with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_add_return(long i, atomic_long_t *v) +raw_atomic_long_add_return(long i, atomic_long_t *v) { - return arch_atomic_add_return(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_return(i, v); +#else + return raw_atomic_add_return(i, v); +#endif } +/** + * raw_atomic_long_add_return_acquire() - atomic add with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_add_return_acquire(long i, atomic_long_t *v) +raw_atomic_long_add_return_acquire(long i, atomic_long_t *v) { - return arch_atomic_add_return_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_return_acquire(i, v); +#else + return raw_atomic_add_return_acquire(i, v); +#endif } +/** + * raw_atomic_long_add_return_release() - atomic add with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_add_return_release(long i, atomic_long_t *v) +raw_atomic_long_add_return_release(long i, atomic_long_t *v) { - return arch_atomic_add_return_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_return_release(i, v); +#else + return raw_atomic_add_return_release(i, v); +#endif } +/** + * raw_atomic_long_add_return_relaxed() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_add_return_relaxed(long i, atomic_long_t *v) +raw_atomic_long_add_return_relaxed(long i, atomic_long_t *v) { - return arch_atomic_add_return_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_return_relaxed(i, v); +#else + return raw_atomic_add_return_relaxed(i, v); +#endif } +/** + * raw_atomic_long_fetch_add() - atomic add with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_add() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_add(long i, atomic_long_t *v) +raw_atomic_long_fetch_add(long i, atomic_long_t *v) { - return arch_atomic_fetch_add(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_add(i, v); +#else + return raw_atomic_fetch_add(i, v); +#endif } +/** + * raw_atomic_long_fetch_add_acquire() - atomic add with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_add_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_add_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_add_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_add_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_add_acquire(i, v); +#else + return raw_atomic_fetch_add_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_add_release() - atomic add with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_add_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_add_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_add_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_add_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_add_release(i, v); +#else + return raw_atomic_fetch_add_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_add_relaxed() - atomic add with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_add_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_add_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_add_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_add_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_add_relaxed(i, v); +#else + return raw_atomic_fetch_add_relaxed(i, v); +#endif } +/** + * raw_atomic_long_sub() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_sub(long i, atomic_long_t *v) +raw_atomic_long_sub(long i, atomic_long_t *v) { - arch_atomic_sub(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_sub(i, v); +#else + raw_atomic_sub(i, v); +#endif } +/** + * raw_atomic_long_sub_return() - atomic subtract with full ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_sub_return(long i, atomic_long_t *v) +raw_atomic_long_sub_return(long i, atomic_long_t *v) { - return arch_atomic_sub_return(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_sub_return(i, v); +#else + return raw_atomic_sub_return(i, v); +#endif } +/** + * raw_atomic_long_sub_return_acquire() - atomic subtract with acquire ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_sub_return_acquire(long i, atomic_long_t *v) +raw_atomic_long_sub_return_acquire(long i, atomic_long_t *v) { - return arch_atomic_sub_return_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_sub_return_acquire(i, v); +#else + return raw_atomic_sub_return_acquire(i, v); +#endif } +/** + * raw_atomic_long_sub_return_release() - atomic subtract with release ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_sub_return_release(long i, atomic_long_t *v) +raw_atomic_long_sub_return_release(long i, atomic_long_t *v) { - return arch_atomic_sub_return_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_sub_return_release(i, v); +#else + return raw_atomic_sub_return_release(i, v); +#endif } +/** + * raw_atomic_long_sub_return_relaxed() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_sub_return_relaxed(long i, atomic_long_t *v) +raw_atomic_long_sub_return_relaxed(long i, atomic_long_t *v) { - return arch_atomic_sub_return_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_sub_return_relaxed(i, v); +#else + return raw_atomic_sub_return_relaxed(i, v); +#endif } +/** + * raw_atomic_long_fetch_sub() - atomic subtract with full ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_sub() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_sub(long i, atomic_long_t *v) +raw_atomic_long_fetch_sub(long i, atomic_long_t *v) { - return arch_atomic_fetch_sub(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_sub(i, v); +#else + return raw_atomic_fetch_sub(i, v); +#endif } +/** + * raw_atomic_long_fetch_sub_acquire() - atomic subtract with acquire ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_sub_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_sub_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_sub_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_sub_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_sub_acquire(i, v); +#else + return raw_atomic_fetch_sub_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_sub_release() - atomic subtract with release ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_sub_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_sub_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_sub_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_sub_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_sub_release(i, v); +#else + return raw_atomic_fetch_sub_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_sub_relaxed() - atomic subtract with relaxed ordering + * @i: long value to subtract + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_sub_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_sub_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_sub_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_sub_relaxed(i, v); +#else + return raw_atomic_fetch_sub_relaxed(i, v); +#endif } +/** + * raw_atomic_long_inc() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_inc(atomic_long_t *v) +raw_atomic_long_inc(atomic_long_t *v) { - arch_atomic_inc(v); +#ifdef CONFIG_64BIT + raw_atomic64_inc(v); +#else + raw_atomic_inc(v); +#endif } +/** + * raw_atomic_long_inc_return() - atomic increment with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_inc_return(atomic_long_t *v) +raw_atomic_long_inc_return(atomic_long_t *v) { - return arch_atomic_inc_return(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_return(v); +#else + return raw_atomic_inc_return(v); +#endif } +/** + * raw_atomic_long_inc_return_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_inc_return_acquire(atomic_long_t *v) +raw_atomic_long_inc_return_acquire(atomic_long_t *v) { - return arch_atomic_inc_return_acquire(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_return_acquire(v); +#else + return raw_atomic_inc_return_acquire(v); +#endif } +/** + * raw_atomic_long_inc_return_release() - atomic increment with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_inc_return_release(atomic_long_t *v) +raw_atomic_long_inc_return_release(atomic_long_t *v) { - return arch_atomic_inc_return_release(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_return_release(v); +#else + return raw_atomic_inc_return_release(v); +#endif } +/** + * raw_atomic_long_inc_return_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_inc_return_relaxed(atomic_long_t *v) +raw_atomic_long_inc_return_relaxed(atomic_long_t *v) { - return arch_atomic_inc_return_relaxed(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_return_relaxed(v); +#else + return raw_atomic_inc_return_relaxed(v); +#endif } +/** + * raw_atomic_long_fetch_inc() - atomic increment with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_inc() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_inc(atomic_long_t *v) +raw_atomic_long_fetch_inc(atomic_long_t *v) { - return arch_atomic_fetch_inc(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_inc(v); +#else + return raw_atomic_fetch_inc(v); +#endif } +/** + * raw_atomic_long_fetch_inc_acquire() - atomic increment with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_inc_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_inc_acquire(atomic_long_t *v) +raw_atomic_long_fetch_inc_acquire(atomic_long_t *v) { - return arch_atomic_fetch_inc_acquire(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_inc_acquire(v); +#else + return raw_atomic_fetch_inc_acquire(v); +#endif } +/** + * raw_atomic_long_fetch_inc_release() - atomic increment with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_inc_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_inc_release(atomic_long_t *v) +raw_atomic_long_fetch_inc_release(atomic_long_t *v) { - return arch_atomic_fetch_inc_release(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_inc_release(v); +#else + return raw_atomic_fetch_inc_release(v); +#endif } +/** + * raw_atomic_long_fetch_inc_relaxed() - atomic increment with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_inc_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_inc_relaxed(atomic_long_t *v) +raw_atomic_long_fetch_inc_relaxed(atomic_long_t *v) { - return arch_atomic_fetch_inc_relaxed(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_inc_relaxed(v); +#else + return raw_atomic_fetch_inc_relaxed(v); +#endif } +/** + * raw_atomic_long_dec() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_dec(atomic_long_t *v) +raw_atomic_long_dec(atomic_long_t *v) { - arch_atomic_dec(v); +#ifdef CONFIG_64BIT + raw_atomic64_dec(v); +#else + raw_atomic_dec(v); +#endif } +/** + * raw_atomic_long_dec_return() - atomic decrement with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_return() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_dec_return(atomic_long_t *v) +raw_atomic_long_dec_return(atomic_long_t *v) { - return arch_atomic_dec_return(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_return(v); +#else + return raw_atomic_dec_return(v); +#endif } +/** + * raw_atomic_long_dec_return_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_return_acquire() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_dec_return_acquire(atomic_long_t *v) +raw_atomic_long_dec_return_acquire(atomic_long_t *v) { - return arch_atomic_dec_return_acquire(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_return_acquire(v); +#else + return raw_atomic_dec_return_acquire(v); +#endif } +/** + * raw_atomic_long_dec_return_release() - atomic decrement with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_return_release() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_dec_return_release(atomic_long_t *v) +raw_atomic_long_dec_return_release(atomic_long_t *v) { - return arch_atomic_dec_return_release(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_return_release(v); +#else + return raw_atomic_dec_return_release(v); +#endif } +/** + * raw_atomic_long_dec_return_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_return_relaxed() elsewhere. + * + * Return: The updated value of @v. + */ static __always_inline long -arch_atomic_long_dec_return_relaxed(atomic_long_t *v) +raw_atomic_long_dec_return_relaxed(atomic_long_t *v) { - return arch_atomic_dec_return_relaxed(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_return_relaxed(v); +#else + return raw_atomic_dec_return_relaxed(v); +#endif } +/** + * raw_atomic_long_fetch_dec() - atomic decrement with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_dec() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_dec(atomic_long_t *v) +raw_atomic_long_fetch_dec(atomic_long_t *v) { - return arch_atomic_fetch_dec(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_dec(v); +#else + return raw_atomic_fetch_dec(v); +#endif } +/** + * raw_atomic_long_fetch_dec_acquire() - atomic decrement with acquire ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_dec_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_dec_acquire(atomic_long_t *v) +raw_atomic_long_fetch_dec_acquire(atomic_long_t *v) { - return arch_atomic_fetch_dec_acquire(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_dec_acquire(v); +#else + return raw_atomic_fetch_dec_acquire(v); +#endif } +/** + * raw_atomic_long_fetch_dec_release() - atomic decrement with release ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_dec_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_dec_release(atomic_long_t *v) +raw_atomic_long_fetch_dec_release(atomic_long_t *v) { - return arch_atomic_fetch_dec_release(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_dec_release(v); +#else + return raw_atomic_fetch_dec_release(v); +#endif } +/** + * raw_atomic_long_fetch_dec_relaxed() - atomic decrement with relaxed ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_dec_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_dec_relaxed(atomic_long_t *v) +raw_atomic_long_fetch_dec_relaxed(atomic_long_t *v) { - return arch_atomic_fetch_dec_relaxed(v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_dec_relaxed(v); +#else + return raw_atomic_fetch_dec_relaxed(v); +#endif } +/** + * raw_atomic_long_and() - atomic bitwise AND with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_and() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_and(long i, atomic_long_t *v) +raw_atomic_long_and(long i, atomic_long_t *v) { - arch_atomic_and(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_and(i, v); +#else + raw_atomic_and(i, v); +#endif } +/** + * raw_atomic_long_fetch_and() - atomic bitwise AND with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_and() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_and(long i, atomic_long_t *v) +raw_atomic_long_fetch_and(long i, atomic_long_t *v) { - return arch_atomic_fetch_and(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_and(i, v); +#else + return raw_atomic_fetch_and(i, v); +#endif } +/** + * raw_atomic_long_fetch_and_acquire() - atomic bitwise AND with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_and_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_and_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_and_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_and_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_and_acquire(i, v); +#else + return raw_atomic_fetch_and_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_and_release() - atomic bitwise AND with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_and_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_and_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_and_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_and_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_and_release(i, v); +#else + return raw_atomic_fetch_and_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_and_relaxed() - atomic bitwise AND with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_and_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_and_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_and_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_and_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_and_relaxed(i, v); +#else + return raw_atomic_fetch_and_relaxed(i, v); +#endif } +/** + * raw_atomic_long_andnot() - atomic bitwise AND NOT with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_andnot() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_andnot(long i, atomic_long_t *v) +raw_atomic_long_andnot(long i, atomic_long_t *v) { - arch_atomic_andnot(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_andnot(i, v); +#else + raw_atomic_andnot(i, v); +#endif } +/** + * raw_atomic_long_fetch_andnot() - atomic bitwise AND NOT with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_andnot() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_andnot(long i, atomic_long_t *v) +raw_atomic_long_fetch_andnot(long i, atomic_long_t *v) { - return arch_atomic_fetch_andnot(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_andnot(i, v); +#else + return raw_atomic_fetch_andnot(i, v); +#endif } +/** + * raw_atomic_long_fetch_andnot_acquire() - atomic bitwise AND NOT with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_andnot_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_andnot_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_andnot_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_andnot_acquire(i, v); +#else + return raw_atomic_fetch_andnot_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_andnot_release() - atomic bitwise AND NOT with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_andnot_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_andnot_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_andnot_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_andnot_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_andnot_release(i, v); +#else + return raw_atomic_fetch_andnot_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_andnot_relaxed() - atomic bitwise AND NOT with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v & ~@i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_andnot_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_andnot_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_andnot_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_andnot_relaxed(i, v); +#else + return raw_atomic_fetch_andnot_relaxed(i, v); +#endif } +/** + * raw_atomic_long_or() - atomic bitwise OR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_or() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_or(long i, atomic_long_t *v) +raw_atomic_long_or(long i, atomic_long_t *v) { - arch_atomic_or(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_or(i, v); +#else + raw_atomic_or(i, v); +#endif } +/** + * raw_atomic_long_fetch_or() - atomic bitwise OR with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_or() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_or(long i, atomic_long_t *v) +raw_atomic_long_fetch_or(long i, atomic_long_t *v) { - return arch_atomic_fetch_or(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_or(i, v); +#else + return raw_atomic_fetch_or(i, v); +#endif } +/** + * raw_atomic_long_fetch_or_acquire() - atomic bitwise OR with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_or_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_or_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_or_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_or_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_or_acquire(i, v); +#else + return raw_atomic_fetch_or_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_or_release() - atomic bitwise OR with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_or_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_or_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_or_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_or_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_or_release(i, v); +#else + return raw_atomic_fetch_or_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_or_relaxed() - atomic bitwise OR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v | @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_or_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_or_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_or_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_or_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_or_relaxed(i, v); +#else + return raw_atomic_fetch_or_relaxed(i, v); +#endif } +/** + * raw_atomic_long_xor() - atomic bitwise XOR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_xor() elsewhere. + * + * Return: Nothing. + */ static __always_inline void -arch_atomic_long_xor(long i, atomic_long_t *v) +raw_atomic_long_xor(long i, atomic_long_t *v) { - arch_atomic_xor(i, v); +#ifdef CONFIG_64BIT + raw_atomic64_xor(i, v); +#else + raw_atomic_xor(i, v); +#endif } +/** + * raw_atomic_long_fetch_xor() - atomic bitwise XOR with full ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_xor() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_xor(long i, atomic_long_t *v) +raw_atomic_long_fetch_xor(long i, atomic_long_t *v) { - return arch_atomic_fetch_xor(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_xor(i, v); +#else + return raw_atomic_fetch_xor(i, v); +#endif } +/** + * raw_atomic_long_fetch_xor_acquire() - atomic bitwise XOR with acquire ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_xor_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_xor_acquire(long i, atomic_long_t *v) +raw_atomic_long_fetch_xor_acquire(long i, atomic_long_t *v) { - return arch_atomic_fetch_xor_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_xor_acquire(i, v); +#else + return raw_atomic_fetch_xor_acquire(i, v); +#endif } +/** + * raw_atomic_long_fetch_xor_release() - atomic bitwise XOR with release ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_xor_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_xor_release(long i, atomic_long_t *v) +raw_atomic_long_fetch_xor_release(long i, atomic_long_t *v) { - return arch_atomic_fetch_xor_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_xor_release(i, v); +#else + return raw_atomic_fetch_xor_release(i, v); +#endif } +/** + * raw_atomic_long_fetch_xor_relaxed() - atomic bitwise XOR with relaxed ordering + * @i: long value + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v ^ @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_xor_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v) +raw_atomic_long_fetch_xor_relaxed(long i, atomic_long_t *v) { - return arch_atomic_fetch_xor_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_xor_relaxed(i, v); +#else + return raw_atomic_fetch_xor_relaxed(i, v); +#endif } +/** + * raw_atomic_long_xchg() - atomic exchange with full ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_xchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_xchg(atomic_long_t *v, long i) +raw_atomic_long_xchg(atomic_long_t *v, long new) { - return arch_atomic_xchg(v, i); +#ifdef CONFIG_64BIT + return raw_atomic64_xchg(v, new); +#else + return raw_atomic_xchg(v, new); +#endif } +/** + * raw_atomic_long_xchg_acquire() - atomic exchange with acquire ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_xchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_xchg_acquire(atomic_long_t *v, long i) +raw_atomic_long_xchg_acquire(atomic_long_t *v, long new) { - return arch_atomic_xchg_acquire(v, i); +#ifdef CONFIG_64BIT + return raw_atomic64_xchg_acquire(v, new); +#else + return raw_atomic_xchg_acquire(v, new); +#endif } +/** + * raw_atomic_long_xchg_release() - atomic exchange with release ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_xchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_xchg_release(atomic_long_t *v, long i) +raw_atomic_long_xchg_release(atomic_long_t *v, long new) { - return arch_atomic_xchg_release(v, i); +#ifdef CONFIG_64BIT + return raw_atomic64_xchg_release(v, new); +#else + return raw_atomic_xchg_release(v, new); +#endif } +/** + * raw_atomic_long_xchg_relaxed() - atomic exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @new: long value to assign + * + * Atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_xchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_xchg_relaxed(atomic_long_t *v, long i) +raw_atomic_long_xchg_relaxed(atomic_long_t *v, long new) { - return arch_atomic_xchg_relaxed(v, i); +#ifdef CONFIG_64BIT + return raw_atomic64_xchg_relaxed(v, new); +#else + return raw_atomic_xchg_relaxed(v, new); +#endif } +/** + * raw_atomic_long_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_cmpxchg() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_cmpxchg(atomic_long_t *v, long old, long new) +raw_atomic_long_cmpxchg(atomic_long_t *v, long old, long new) { - return arch_atomic_cmpxchg(v, old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_cmpxchg(v, old, new); +#else + return raw_atomic_cmpxchg(v, old, new); +#endif } +/** + * raw_atomic_long_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_cmpxchg_acquire() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new) +raw_atomic_long_cmpxchg_acquire(atomic_long_t *v, long old, long new) { - return arch_atomic_cmpxchg_acquire(v, old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_cmpxchg_acquire(v, old, new); +#else + return raw_atomic_cmpxchg_acquire(v, old, new); +#endif } +/** + * raw_atomic_long_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_cmpxchg_release() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new) +raw_atomic_long_cmpxchg_release(atomic_long_t *v, long old, long new) { - return arch_atomic_cmpxchg_release(v, old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_cmpxchg_release(v, old, new); +#else + return raw_atomic_cmpxchg_release(v, old, new); +#endif } +/** + * raw_atomic_long_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @old: long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_cmpxchg_relaxed() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new) +raw_atomic_long_cmpxchg_relaxed(atomic_long_t *v, long old, long new) { - return arch_atomic_cmpxchg_relaxed(v, old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_cmpxchg_relaxed(v, old, new); +#else + return raw_atomic_cmpxchg_relaxed(v, old, new); +#endif } +/** + * raw_atomic_long_try_cmpxchg() - atomic compare and exchange with full ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with full ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_long_try_cmpxchg() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new) +raw_atomic_long_try_cmpxchg(atomic_long_t *v, long *old, long new) { - return arch_atomic_try_cmpxchg(v, (int *)old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_try_cmpxchg(v, (s64 *)old, new); +#else + return raw_atomic_try_cmpxchg(v, (int *)old, new); +#endif } +/** + * raw_atomic_long_try_cmpxchg_acquire() - atomic compare and exchange with acquire ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with acquire ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_long_try_cmpxchg_acquire() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new) +raw_atomic_long_try_cmpxchg_acquire(atomic_long_t *v, long *old, long new) { - return arch_atomic_try_cmpxchg_acquire(v, (int *)old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_try_cmpxchg_acquire(v, (s64 *)old, new); +#else + return raw_atomic_try_cmpxchg_acquire(v, (int *)old, new); +#endif } +/** + * raw_atomic_long_try_cmpxchg_release() - atomic compare and exchange with release ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with release ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_long_try_cmpxchg_release() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new) +raw_atomic_long_try_cmpxchg_release(atomic_long_t *v, long *old, long new) { - return arch_atomic_try_cmpxchg_release(v, (int *)old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_try_cmpxchg_release(v, (s64 *)old, new); +#else + return raw_atomic_try_cmpxchg_release(v, (int *)old, new); +#endif } +/** + * raw_atomic_long_try_cmpxchg_relaxed() - atomic compare and exchange with relaxed ordering + * @v: pointer to atomic_long_t + * @old: pointer to long value to compare with + * @new: long value to assign + * + * If (@v == @old), atomically updates @v to @new with relaxed ordering. + * Otherwise, updates @old to the current value of @v. + * + * Safe to use in noinstr code; prefer atomic_long_try_cmpxchg_relaxed() elsewhere. + * + * Return: @true if the exchange occured, @false otherwise. + */ static __always_inline bool -arch_atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new) +raw_atomic_long_try_cmpxchg_relaxed(atomic_long_t *v, long *old, long new) { - return arch_atomic_try_cmpxchg_relaxed(v, (int *)old, new); +#ifdef CONFIG_64BIT + return raw_atomic64_try_cmpxchg_relaxed(v, (s64 *)old, new); +#else + return raw_atomic_try_cmpxchg_relaxed(v, (int *)old, new); +#endif } +/** + * raw_atomic_long_sub_and_test() - atomic subtract and test if zero with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_sub_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool -arch_atomic_long_sub_and_test(long i, atomic_long_t *v) +raw_atomic_long_sub_and_test(long i, atomic_long_t *v) { - return arch_atomic_sub_and_test(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_sub_and_test(i, v); +#else + return raw_atomic_sub_and_test(i, v); +#endif } +/** + * raw_atomic_long_dec_and_test() - atomic decrement and test if zero with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool -arch_atomic_long_dec_and_test(atomic_long_t *v) +raw_atomic_long_dec_and_test(atomic_long_t *v) { - return arch_atomic_dec_and_test(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_and_test(v); +#else + return raw_atomic_dec_and_test(v); +#endif } +/** + * raw_atomic_long_inc_and_test() - atomic increment and test if zero with full ordering + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_and_test() elsewhere. + * + * Return: @true if the resulting value of @v is zero, @false otherwise. + */ static __always_inline bool -arch_atomic_long_inc_and_test(atomic_long_t *v) +raw_atomic_long_inc_and_test(atomic_long_t *v) { - return arch_atomic_inc_and_test(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_and_test(v); +#else + return raw_atomic_inc_and_test(v); +#endif } +/** + * raw_atomic_long_add_negative() - atomic add and test if negative with full ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_negative() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool -arch_atomic_long_add_negative(long i, atomic_long_t *v) +raw_atomic_long_add_negative(long i, atomic_long_t *v) { - return arch_atomic_add_negative(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_negative(i, v); +#else + return raw_atomic_add_negative(i, v); +#endif } +/** + * raw_atomic_long_add_negative_acquire() - atomic add and test if negative with acquire ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with acquire ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_negative_acquire() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool -arch_atomic_long_add_negative_acquire(long i, atomic_long_t *v) +raw_atomic_long_add_negative_acquire(long i, atomic_long_t *v) { - return arch_atomic_add_negative_acquire(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_negative_acquire(i, v); +#else + return raw_atomic_add_negative_acquire(i, v); +#endif } +/** + * raw_atomic_long_add_negative_release() - atomic add and test if negative with release ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with release ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_negative_release() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool -arch_atomic_long_add_negative_release(long i, atomic_long_t *v) +raw_atomic_long_add_negative_release(long i, atomic_long_t *v) { - return arch_atomic_add_negative_release(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_negative_release(i, v); +#else + return raw_atomic_add_negative_release(i, v); +#endif } +/** + * raw_atomic_long_add_negative_relaxed() - atomic add and test if negative with relaxed ordering + * @i: long value to add + * @v: pointer to atomic_long_t + * + * Atomically updates @v to (@v + @i) with relaxed ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_negative_relaxed() elsewhere. + * + * Return: @true if the resulting value of @v is negative, @false otherwise. + */ static __always_inline bool -arch_atomic_long_add_negative_relaxed(long i, atomic_long_t *v) +raw_atomic_long_add_negative_relaxed(long i, atomic_long_t *v) { - return arch_atomic_add_negative_relaxed(i, v); +#ifdef CONFIG_64BIT + return raw_atomic64_add_negative_relaxed(i, v); +#else + return raw_atomic_add_negative_relaxed(i, v); +#endif } +/** + * raw_atomic_long_fetch_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_long_t + * @a: long value to add + * @u: long value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_fetch_add_unless() elsewhere. + * + * Return: The original value of @v. + */ static __always_inline long -arch_atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) +raw_atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u) { - return arch_atomic_fetch_add_unless(v, a, u); +#ifdef CONFIG_64BIT + return raw_atomic64_fetch_add_unless(v, a, u); +#else + return raw_atomic_fetch_add_unless(v, a, u); +#endif } +/** + * raw_atomic_long_add_unless() - atomic add unless value with full ordering + * @v: pointer to atomic_long_t + * @a: long value to add + * @u: long value to compare with + * + * If (@v != @u), atomically updates @v to (@v + @a) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_add_unless() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_long_add_unless(atomic_long_t *v, long a, long u) +raw_atomic_long_add_unless(atomic_long_t *v, long a, long u) { - return arch_atomic_add_unless(v, a, u); +#ifdef CONFIG_64BIT + return raw_atomic64_add_unless(v, a, u); +#else + return raw_atomic_add_unless(v, a, u); +#endif } +/** + * raw_atomic_long_inc_not_zero() - atomic increment unless zero with full ordering + * @v: pointer to atomic_long_t + * + * If (@v != 0), atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_not_zero() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_long_inc_not_zero(atomic_long_t *v) +raw_atomic_long_inc_not_zero(atomic_long_t *v) { - return arch_atomic_inc_not_zero(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_not_zero(v); +#else + return raw_atomic_inc_not_zero(v); +#endif } +/** + * raw_atomic_long_inc_unless_negative() - atomic increment unless negative with full ordering + * @v: pointer to atomic_long_t + * + * If (@v >= 0), atomically updates @v to (@v + 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_inc_unless_negative() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_long_inc_unless_negative(atomic_long_t *v) +raw_atomic_long_inc_unless_negative(atomic_long_t *v) { - return arch_atomic_inc_unless_negative(v); +#ifdef CONFIG_64BIT + return raw_atomic64_inc_unless_negative(v); +#else + return raw_atomic_inc_unless_negative(v); +#endif } +/** + * raw_atomic_long_dec_unless_positive() - atomic decrement unless positive with full ordering + * @v: pointer to atomic_long_t + * + * If (@v <= 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_unless_positive() elsewhere. + * + * Return: @true if @v was updated, @false otherwise. + */ static __always_inline bool -arch_atomic_long_dec_unless_positive(atomic_long_t *v) +raw_atomic_long_dec_unless_positive(atomic_long_t *v) { - return arch_atomic_dec_unless_positive(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_unless_positive(v); +#else + return raw_atomic_dec_unless_positive(v); +#endif } +/** + * raw_atomic_long_dec_if_positive() - atomic decrement if positive with full ordering + * @v: pointer to atomic_long_t + * + * If (@v > 0), atomically updates @v to (@v - 1) with full ordering. + * + * Safe to use in noinstr code; prefer atomic_long_dec_if_positive() elsewhere. + * + * Return: The old value of (@v - 1), regardless of whether @v was updated. + */ static __always_inline long -arch_atomic_long_dec_if_positive(atomic_long_t *v) +raw_atomic_long_dec_if_positive(atomic_long_t *v) { - return arch_atomic_dec_if_positive(v); +#ifdef CONFIG_64BIT + return raw_atomic64_dec_if_positive(v); +#else + return raw_atomic_dec_if_positive(v); +#endif } -#endif /* CONFIG_64BIT */ #endif /* _LINUX_ATOMIC_LONG_H */ -// a194c07d7d2f4b0e178d3c118c919775d5d65f50 +// 4ef23f98c73cff96d239896175fd26b10b88899e diff --git a/include/linux/audit.h b/include/linux/audit.h index 31086a72e32a..6a3a9e122bb5 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -130,8 +130,6 @@ extern unsigned compat_dir_class[]; extern unsigned compat_chattr_class[]; extern unsigned compat_signal_class[]; -extern int audit_classify_compat_syscall(int abi, unsigned syscall); - /* audit_names->type values */ #define AUDIT_TYPE_UNKNOWN 0 /* we don't know yet */ #define AUDIT_TYPE_NORMAL 1 /* a "normal" audit record */ diff --git a/include/linux/audit_arch.h b/include/linux/audit_arch.h index 8fdb1afe251a..0e34d673ef17 100644 --- a/include/linux/audit_arch.h +++ b/include/linux/audit_arch.h @@ -21,4 +21,6 @@ enum auditsc_class_t { AUDITSC_NVALS /* count */ }; +extern int audit_classify_compat_syscall(int abi, unsigned syscall); + #endif diff --git a/include/linux/bio.h b/include/linux/bio.h index b3e7529ff55e..c4f5b5228105 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -229,7 +229,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned int count) static inline bool bio_flagged(struct bio *bio, unsigned int bit) { - return (bio->bi_flags & (1U << bit)) != 0; + return bio->bi_flags & (1U << bit); } static inline void bio_set_flag(struct bio *bio, unsigned int bit) @@ -465,14 +465,18 @@ extern void bio_uninit(struct bio *); void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf); void bio_chain(struct bio *, struct bio *); -int bio_add_page(struct bio *, struct page *, unsigned len, unsigned off); -bool bio_add_folio(struct bio *, struct folio *, size_t len, size_t off); +int __must_check bio_add_page(struct bio *bio, struct page *page, unsigned len, + unsigned off); +bool __must_check bio_add_folio(struct bio *bio, struct folio *folio, + size_t len, size_t off); extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, unsigned int, unsigned int); int bio_add_zone_append_page(struct bio *bio, struct page *page, unsigned int len, unsigned int offset); void __bio_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int off); +void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len, + size_t off); int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter); void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter); void __bio_release_pages(struct bio *bio, bool mark_dirty); @@ -488,7 +492,7 @@ void zero_fill_bio(struct bio *bio); static inline void bio_release_pages(struct bio *bio, bool mark_dirty) { - if (!bio_flagged(bio, BIO_NO_PAGE_REF)) + if (bio_flagged(bio, BIO_PAGE_PINNED)) __bio_release_pages(bio, mark_dirty); } diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 06caacd77ed6..2b7fb8e87793 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -28,8 +28,6 @@ typedef __u32 __bitwise req_flags_t; /* drive already may have started this one */ #define RQF_STARTED ((__force req_flags_t)(1 << 1)) -/* may not be passed by ioscheduler */ -#define RQF_SOFTBARRIER ((__force req_flags_t)(1 << 3)) /* request for flush sequence */ #define RQF_FLUSH_SEQ ((__force req_flags_t)(1 << 4)) /* merge of different types, fail separately */ @@ -38,12 +36,14 @@ typedef __u32 __bitwise req_flags_t; #define RQF_MQ_INFLIGHT ((__force req_flags_t)(1 << 6)) /* don't call prep for this one */ #define RQF_DONTPREP ((__force req_flags_t)(1 << 7)) +/* use hctx->sched_tags */ +#define RQF_SCHED_TAGS ((__force req_flags_t)(1 << 8)) +/* use an I/O scheduler for this request */ +#define RQF_USE_SCHED ((__force req_flags_t)(1 << 9)) /* vaguely specified driver internal error. Ignored by the block layer */ #define RQF_FAILED ((__force req_flags_t)(1 << 10)) /* don't warn about errors */ #define RQF_QUIET ((__force req_flags_t)(1 << 11)) -/* elevator private data attached */ -#define RQF_ELVPRIV ((__force req_flags_t)(1 << 12)) /* account into disk and partition IO statistics */ #define RQF_IO_STAT ((__force req_flags_t)(1 << 13)) /* runtime pm request */ @@ -59,13 +59,11 @@ typedef __u32 __bitwise req_flags_t; #define RQF_ZONE_WRITE_LOCKED ((__force req_flags_t)(1 << 19)) /* ->timeout has been called, don't expire again */ #define RQF_TIMED_OUT ((__force req_flags_t)(1 << 21)) -/* queue has elevator attached */ -#define RQF_ELV ((__force req_flags_t)(1 << 22)) -#define RQF_RESV ((__force req_flags_t)(1 << 23)) +#define RQF_RESV ((__force req_flags_t)(1 << 23)) /* flags that prevent us from merging requests: */ #define RQF_NOMERGE_FLAGS \ - (RQF_STARTED | RQF_SOFTBARRIER | RQF_FLUSH_SEQ | RQF_SPECIAL_PAYLOAD) + (RQF_STARTED | RQF_FLUSH_SEQ | RQF_SPECIAL_PAYLOAD) enum mq_rq_state { MQ_RQ_IDLE = 0, @@ -169,25 +167,20 @@ struct request { void *completion_data; }; - /* * Three pointers are available for the IO schedulers, if they need - * more they have to dynamically allocate it. Flush requests are - * never put on the IO scheduler. So let the flush fields share - * space with the elevator data. + * more they have to dynamically allocate it. */ - union { - struct { - struct io_cq *icq; - void *priv[2]; - } elv; - - struct { - unsigned int seq; - struct list_head list; - rq_end_io_fn *saved_end_io; - } flush; - }; + struct { + struct io_cq *icq; + void *priv[2]; + } elv; + + struct { + unsigned int seq; + struct list_head list; + rq_end_io_fn *saved_end_io; + } flush; union { struct __call_single_data csd; @@ -208,7 +201,7 @@ static inline enum req_op req_op(const struct request *req) static inline bool blk_rq_is_passthrough(struct request *rq) { - return blk_op_is_passthrough(req_op(rq)); + return blk_op_is_passthrough(rq->cmd_flags); } static inline unsigned short req_get_ioprio(struct request *req) @@ -722,6 +715,8 @@ int blk_mq_alloc_sq_tag_set(struct blk_mq_tag_set *set, void blk_mq_free_tag_set(struct blk_mq_tag_set *set); void blk_mq_free_request(struct request *rq); +int blk_rq_poll(struct request *rq, struct io_comp_batch *iob, + unsigned int poll_flags); bool blk_mq_queue_inflight(struct request_queue *q); @@ -746,8 +741,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, struct blk_mq_tags { unsigned int nr_tags; unsigned int nr_reserved_tags; - - atomic_t active_queues; + unsigned int active_queues; struct sbitmap_queue bitmap_tags; struct sbitmap_queue breserved_tags; @@ -844,7 +838,7 @@ void blk_mq_end_request_batch(struct io_comp_batch *ib); */ static inline bool blk_mq_need_time_stamp(struct request *rq) { - return (rq->rq_flags & (RQF_IO_STAT | RQF_STATS | RQF_ELV)); + return (rq->rq_flags & (RQF_IO_STAT | RQF_STATS | RQF_USE_SCHED)); } static inline bool blk_mq_is_reserved_rq(struct request *rq) @@ -860,7 +854,11 @@ static inline bool blk_mq_add_to_batch(struct request *req, struct io_comp_batch *iob, int ioerror, void (*complete)(struct io_comp_batch *)) { - if (!iob || (req->rq_flags & RQF_ELV) || ioerror || + /* + * blk_mq_end_request_batch() can't end request allocated from + * sched tags + */ + if (!iob || (req->rq_flags & RQF_SCHED_TAGS) || ioerror || (req->end_io && !blk_rq_is_passthrough(req))) return false; @@ -1164,6 +1162,18 @@ static inline unsigned int blk_rq_zone_is_seq(struct request *rq) return disk_zone_is_seq(rq->q->disk, blk_rq_pos(rq)); } +/** + * blk_rq_is_seq_zoned_write() - Check if @rq requires write serialization. + * @rq: Request to examine. + * + * Note: REQ_OP_ZONE_APPEND requests do not require serialization. + */ +static inline bool blk_rq_is_seq_zoned_write(struct request *rq) +{ + return op_needs_zoned_write_locking(req_op(rq)) && + blk_rq_zone_is_seq(rq); +} + bool blk_req_needs_zone_write_lock(struct request *rq); bool blk_req_zone_write_trylock(struct request *rq); void __blk_req_zone_write_lock(struct request *rq); @@ -1194,6 +1204,11 @@ static inline bool blk_req_can_dispatch_to_zone(struct request *rq) return !blk_req_zone_is_write_locked(rq); } #else /* CONFIG_BLK_DEV_ZONED */ +static inline bool blk_rq_is_seq_zoned_write(struct request *rq) +{ + return false; +} + static inline bool blk_req_needs_zone_write_lock(struct request *rq) { return false; diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 740afe80f297..0bad62cca3d0 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -55,6 +55,8 @@ struct block_device { struct super_block * bd_super; void * bd_claiming; void * bd_holder; + const struct blk_holder_ops *bd_holder_ops; + struct mutex bd_holder_lock; /* The counter of freeze processes */ int bd_fsfreeze_count; int bd_holders; @@ -101,7 +103,7 @@ typedef u16 blk_short_t; #define BLK_STS_NOSPC ((__force blk_status_t)3) #define BLK_STS_TRANSPORT ((__force blk_status_t)4) #define BLK_STS_TARGET ((__force blk_status_t)5) -#define BLK_STS_NEXUS ((__force blk_status_t)6) +#define BLK_STS_RESV_CONFLICT ((__force blk_status_t)6) #define BLK_STS_MEDIUM ((__force blk_status_t)7) #define BLK_STS_PROTECTION ((__force blk_status_t)8) #define BLK_STS_RESOURCE ((__force blk_status_t)9) @@ -171,6 +173,12 @@ typedef u16 blk_short_t; */ #define BLK_STS_OFFLINE ((__force blk_status_t)17) +/* + * BLK_STS_DURATION_LIMIT is returned from the driver when the target device + * aborted the command because it exceeded one of its Command Duration Limits. + */ +#define BLK_STS_DURATION_LIMIT ((__force blk_status_t)18) + /** * blk_path_error - returns true if error may be path related * @error: status the request was completed with @@ -189,7 +197,7 @@ static inline bool blk_path_error(blk_status_t error) case BLK_STS_NOTSUPP: case BLK_STS_NOSPC: case BLK_STS_TARGET: - case BLK_STS_NEXUS: + case BLK_STS_RESV_CONFLICT: case BLK_STS_MEDIUM: case BLK_STS_PROTECTION: return false; @@ -323,7 +331,7 @@ struct bio { * bio flags */ enum { - BIO_NO_PAGE_REF, /* don't put release vec pages */ + BIO_PAGE_PINNED, /* Unpin pages in bio_release_pages() */ BIO_CLONED, /* doesn't own data */ BIO_BOUNCED, /* bio is a bounce bio */ BIO_QUIET, /* Make BIO Quiet */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b441e633f4dd..ed44a997f629 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -41,7 +41,7 @@ struct blk_stat_callback; struct blk_crypto_profile; extern const struct device_type disk_type; -extern struct device_type part_type; +extern const struct device_type part_type; extern struct class block_class; /* @@ -112,6 +112,19 @@ struct blk_integrity { unsigned char tag_size; }; +typedef unsigned int __bitwise blk_mode_t; + +/* open for reading */ +#define BLK_OPEN_READ ((__force blk_mode_t)(1 << 0)) +/* open for writing */ +#define BLK_OPEN_WRITE ((__force blk_mode_t)(1 << 1)) +/* open exclusively (vs other exclusive openers */ +#define BLK_OPEN_EXCL ((__force blk_mode_t)(1 << 2)) +/* opened with O_NDELAY */ +#define BLK_OPEN_NDELAY ((__force blk_mode_t)(1 << 3)) +/* open for "writes" only for ioctls (specialy hack for floppy.c) */ +#define BLK_OPEN_WRITE_IOCTL ((__force blk_mode_t)(1 << 4)) + struct gendisk { /* * major/first_minor/minors should not be set by any new driver, the @@ -187,6 +200,7 @@ struct gendisk { struct badblocks *bb; struct lockdep_map lockdep_map; u64 diskseq; + blk_mode_t open_mode; /* * Independent sector access ranges. This is always NULL for @@ -318,7 +332,6 @@ typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx, void disk_set_zoned(struct gendisk *disk, enum blk_zoned_model model); #ifdef CONFIG_BLK_DEV_ZONED - #define BLK_ALL_ZONES ((unsigned int)-1) int blkdev_report_zones(struct block_device *bdev, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); @@ -328,33 +341,11 @@ extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_op op, gfp_t gfp_mask); int blk_revalidate_disk_zones(struct gendisk *disk, void (*update_driver_data)(struct gendisk *disk)); - -extern int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg); -extern int blkdev_zone_mgmt_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg); - #else /* CONFIG_BLK_DEV_ZONED */ - static inline unsigned int bdev_nr_zones(struct block_device *bdev) { return 0; } - -static inline int blkdev_report_zones_ioctl(struct block_device *bdev, - fmode_t mode, unsigned int cmd, - unsigned long arg) -{ - return -ENOTTY; -} - -static inline int blkdev_zone_mgmt_ioctl(struct block_device *bdev, - fmode_t mode, unsigned int cmd, - unsigned long arg) -{ - return -ENOTTY; -} - #endif /* CONFIG_BLK_DEV_ZONED */ /* @@ -392,6 +383,7 @@ struct request_queue { struct blk_queue_stats *stats; struct rq_qos *rq_qos; + struct mutex rq_qos_mutex; const struct blk_mq_ops *mq_ops; @@ -487,6 +479,7 @@ struct request_queue { * for flush operations */ struct blk_flush_queue *fq; + struct list_head flush_list; struct list_head requeue_list; spinlock_t requeue_lock; @@ -815,7 +808,7 @@ int __register_blkdev(unsigned int major, const char *name, __register_blkdev(major, name, NULL) void unregister_blkdev(unsigned int major, const char *name); -bool bdev_check_media_change(struct block_device *bdev); +bool disk_check_media_change(struct gendisk *disk); int __invalidate_device(struct block_device *bdev, bool kill_dirty); void set_capacity(struct gendisk *disk, sector_t size); @@ -836,7 +829,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev, dev_t part_devt(struct gendisk *disk, u8 partno); void inc_diskseq(struct gendisk *disk); -dev_t blk_lookup_devt(const char *name, int partno); void blk_request_module(dev_t devt); extern int blk_register_queue(struct gendisk *disk); @@ -1281,15 +1273,18 @@ static inline unsigned int bdev_zone_no(struct block_device *bdev, sector_t sec) return disk_zone_no(bdev->bd_disk, sec); } -static inline bool bdev_op_is_zoned_write(struct block_device *bdev, - blk_opf_t op) +/* Whether write serialization is required for @op on zoned devices. */ +static inline bool op_needs_zoned_write_locking(enum req_op op) { - if (!bdev_is_zoned(bdev)) - return false; - return op == REQ_OP_WRITE || op == REQ_OP_WRITE_ZEROES; } +static inline bool bdev_op_is_zoned_write(struct block_device *bdev, + enum req_op op) +{ + return bdev_is_zoned(bdev) && op_needs_zoned_write_locking(op); +} + static inline sector_t bdev_zone_sectors(struct block_device *bdev) { struct request_queue *q = bdev_get_queue(bdev); @@ -1376,16 +1371,16 @@ enum blk_unique_id { BLK_UID_NAA = 3, }; -#define NFL4_UFLG_MASK 0x0000003F - struct block_device_operations { void (*submit_bio)(struct bio *bio); int (*poll_bio)(struct bio *bio, struct io_comp_batch *iob, unsigned int flags); - int (*open) (struct block_device *, fmode_t); - void (*release) (struct gendisk *, fmode_t); - int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); - int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); + int (*open)(struct gendisk *disk, blk_mode_t mode); + void (*release)(struct gendisk *disk); + int (*ioctl)(struct block_device *bdev, blk_mode_t mode, + unsigned cmd, unsigned long arg); + int (*compat_ioctl)(struct block_device *bdev, blk_mode_t mode, + unsigned cmd, unsigned long arg); unsigned int (*check_events) (struct gendisk *disk, unsigned int clearing); void (*unlock_native_capacity) (struct gendisk *); @@ -1412,7 +1407,7 @@ struct block_device_operations { }; #ifdef CONFIG_COMPAT -extern int blkdev_compat_ptr_ioctl(struct block_device *, fmode_t, +extern int blkdev_compat_ptr_ioctl(struct block_device *, blk_mode_t, unsigned int, unsigned long); #else #define blkdev_compat_ptr_ioctl NULL @@ -1465,22 +1460,31 @@ void blkdev_show(struct seq_file *seqf, off_t offset); #define BLKDEV_MAJOR_MAX 0 #endif -struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, - void *holder); -struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder); -int bd_prepare_to_claim(struct block_device *bdev, void *holder); +struct blk_holder_ops { + void (*mark_dead)(struct block_device *bdev); +}; + +/* + * Return the correct open flags for blkdev_get_by_* for super block flags + * as stored in sb->s_flags. + */ +#define sb_open_mode(flags) \ + (BLK_OPEN_READ | (((flags) & SB_RDONLY) ? 0 : BLK_OPEN_WRITE)) + +struct block_device *blkdev_get_by_dev(dev_t dev, blk_mode_t mode, void *holder, + const struct blk_holder_ops *hops); +struct block_device *blkdev_get_by_path(const char *path, blk_mode_t mode, + void *holder, const struct blk_holder_ops *hops); +int bd_prepare_to_claim(struct block_device *bdev, void *holder, + const struct blk_holder_ops *hops); void bd_abort_claiming(struct block_device *bdev, void *holder); -void blkdev_put(struct block_device *bdev, fmode_t mode); +void blkdev_put(struct block_device *bdev, void *holder); /* just for blk-cgroup, don't use elsewhere */ struct block_device *blkdev_get_no_open(dev_t dev); void blkdev_put_no_open(struct block_device *bdev); -struct block_device *bdev_alloc(struct gendisk *disk, u8 partno); -void bdev_add(struct block_device *bdev, dev_t dev); struct block_device *I_BDEV(struct inode *inode); -int truncate_bdev_range(struct block_device *bdev, fmode_t mode, loff_t lstart, - loff_t lend); #ifdef CONFIG_BLOCK void invalidate_bdev(struct block_device *bdev); @@ -1490,6 +1494,7 @@ int sync_blockdev_nowait(struct block_device *bdev); void sync_bdevs(bool wait); void bdev_statx_dioalign(struct inode *inode, struct kstat *stat); void printk_all_partitions(void); +int __init early_lookup_bdev(const char *pathname, dev_t *dev); #else static inline void invalidate_bdev(struct block_device *bdev) { @@ -1511,6 +1516,10 @@ static inline void bdev_statx_dioalign(struct inode *inode, struct kstat *stat) static inline void printk_all_partitions(void) { } +static inline int early_lookup_bdev(const char *pathname, dev_t *dev) +{ + return -EINVAL; +} #endif /* CONFIG_BLOCK */ int fsync_bdev(struct block_device *bdev); diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index cfbda114348c..122c62e561fc 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -85,10 +85,14 @@ extern int blk_trace_remove(struct request_queue *q); # define blk_add_driver_data(rq, data, len) do {} while (0) # define blk_trace_setup(q, name, dev, bdev, arg) (-ENOTTY) # define blk_trace_startstop(q, start) (-ENOTTY) -# define blk_trace_remove(q) (-ENOTTY) # define blk_add_trace_msg(q, fmt, ...) do { } while (0) # define blk_add_cgroup_trace_msg(q, cg, fmt, ...) do { } while (0) # define blk_trace_note_message_enabled(q) (false) + +static inline int blk_trace_remove(struct request_queue *q) +{ + return -ENOTTY; +} #endif /* CONFIG_BLK_DEV_IO_TRACE */ #ifdef CONFIG_COMPAT diff --git a/include/linux/bpf.h b/include/linux/bpf.h index e53ceee1df37..f58895830ada 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1125,7 +1125,6 @@ struct bpf_trampoline { int progs_cnt[BPF_TRAMP_MAX]; /* Executable image of trampoline */ struct bpf_tramp_image *cur_image; - u64 selector; struct module *mod; }; @@ -1197,7 +1196,7 @@ enum bpf_dynptr_type { }; int bpf_dynptr_check_size(u32 size); -u32 bpf_dynptr_get_size(const struct bpf_dynptr_kern *ptr); +u32 __bpf_dynptr_size(const struct bpf_dynptr_kern *ptr); #ifdef CONFIG_BPF_JIT int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr); @@ -2078,8 +2077,8 @@ struct file *bpf_link_new_file(struct bpf_link *link, int *reserved_fd); struct bpf_link *bpf_link_get_from_fd(u32 ufd); struct bpf_link *bpf_link_get_curr_or_next(u32 *id); -int bpf_obj_pin_user(u32 ufd, const char __user *pathname); -int bpf_obj_get_user(const char __user *pathname, int flags); +int bpf_obj_pin_user(u32 ufd, int path_fd, const char __user *pathname); +int bpf_obj_get_user(int path_fd, const char __user *pathname, int flags); #define BPF_ITER_FUNC_PREFIX "bpf_iter_" #define DEFINE_BPF_ITER_FUNC(target, args...) \ diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 3dd29a53b711..f70f9ac884d2 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -18,8 +18,11 @@ * that converting umax_value to int cannot overflow. */ #define BPF_MAX_VAR_SIZ (1 << 29) -/* size of type_str_buf in bpf_verifier. */ -#define TYPE_STR_BUF_LEN 128 +/* size of tmp_str_buf in bpf_verifier. + * we need at least 306 bytes to fit full stack mask representation + * (in the "-8,-16,...,-512" form) + */ +#define TMP_STR_BUF_LEN 320 /* Liveness marks, used for registers and spilled-regs (in stack slots). * Read marks propagate upwards until they find a write mark; they record that @@ -238,6 +241,10 @@ enum bpf_stack_slot_type { #define BPF_REG_SIZE 8 /* size of eBPF register in bytes */ +#define BPF_REGMASK_ARGS ((1 << BPF_REG_1) | (1 << BPF_REG_2) | \ + (1 << BPF_REG_3) | (1 << BPF_REG_4) | \ + (1 << BPF_REG_5)) + #define BPF_DYNPTR_SIZE sizeof(struct bpf_dynptr_kern) #define BPF_DYNPTR_NR_SLOTS (BPF_DYNPTR_SIZE / BPF_REG_SIZE) @@ -306,11 +313,6 @@ struct bpf_idx_pair { u32 idx; }; -struct bpf_id_pair { - u32 old; - u32 cur; -}; - #define MAX_CALL_FRAMES 8 /* Maximum number of register states that can exist at once */ #define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) * MAX_CALL_FRAMES) @@ -541,6 +543,30 @@ struct bpf_subprog_info { bool is_async_cb; }; +struct bpf_verifier_env; + +struct backtrack_state { + struct bpf_verifier_env *env; + u32 frame; + u32 reg_masks[MAX_CALL_FRAMES]; + u64 stack_masks[MAX_CALL_FRAMES]; +}; + +struct bpf_id_pair { + u32 old; + u32 cur; +}; + +struct bpf_idmap { + u32 tmp_id_gen; + struct bpf_id_pair map[BPF_ID_MAP_SIZE]; +}; + +struct bpf_idset { + u32 count; + u32 ids[BPF_ID_MAP_SIZE]; +}; + /* single container for all structs * one verifier_env per bpf_check() call */ @@ -572,12 +598,16 @@ struct bpf_verifier_env { const struct bpf_line_info *prev_linfo; struct bpf_verifier_log log; struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1]; - struct bpf_id_pair idmap_scratch[BPF_ID_MAP_SIZE]; + union { + struct bpf_idmap idmap_scratch; + struct bpf_idset idset_scratch; + }; struct { int *insn_state; int *insn_stack; int cur_stack; } cfg; + struct backtrack_state bt; u32 pass_cnt; /* number of times do_check() was called */ u32 subprog_cnt; /* number of instructions analyzed by the verifier */ @@ -606,8 +636,10 @@ struct bpf_verifier_env { /* Same as scratched_regs but for stack slots */ u64 scratched_stack_slots; u64 prev_log_pos, prev_insn_print_pos; - /* buffer used in reg_type_str() to generate reg_type string */ - char type_str_buf[TYPE_STR_BUF_LEN]; + /* buffer used to generate temporary string representations, + * e.g., in reg_type_str() to generate reg_type string + */ + char tmp_str_buf[TMP_STR_BUF_LEN]; }; __printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log, diff --git a/include/linux/bpfilter.h b/include/linux/bpfilter.h index 2ae3c8e1d83c..736ded4905e0 100644 --- a/include/linux/bpfilter.h +++ b/include/linux/bpfilter.h @@ -11,7 +11,6 @@ int bpfilter_ip_set_sockopt(struct sock *sk, int optname, sockptr_t optval, unsigned int optlen); int bpfilter_ip_get_sockopt(struct sock *sk, int optname, char __user *optval, int __user *optlen); -void bpfilter_umh_cleanup(struct umd_info *info); struct bpfilter_umh_ops { struct umd_info info; diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index 9e77165f3ef6..5d732f48f787 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -89,6 +89,7 @@ #define MII_BCM54XX_EXP_SEL 0x17 /* Expansion register select */ #define MII_BCM54XX_EXP_SEL_TOP 0x0d00 /* TOP_MISC expansion register select */ #define MII_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */ +#define MII_BCM54XX_EXP_SEL_WOL 0x0e00 /* Wake-on-LAN expansion select register */ #define MII_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */ #define MII_BCM54XX_EXP_SEL_ETC 0x0d00 /* Expansion register spare + 2k mem */ @@ -160,6 +161,7 @@ #define BCM_LED_SRC_OPENSHORT 0xb #define BCM_LED_SRC_OFF 0xe /* Tied high */ #define BCM_LED_SRC_ON 0xf /* Tied low */ +#define BCM_LED_SRC_MASK GENMASK(3, 0) /* * Broadcom Multicolor LED configurations (expansion register 4) @@ -205,11 +207,13 @@ #define BCM_NO_ANEG_APD_EN 0x0060 /* bits 5 & 6 */ #define BCM_APD_SINGLELP_EN 0x0100 /* Bit 8 */ -#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ +#define BCM54XX_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */ /* LED3 / ~LINKSPD[2] selector */ -#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4) +#define BCM54XX_SHD_LEDS_SHIFT(led) (4 * (led)) +#define BCM54XX_SHD_LEDS1_LED3(src) ((src & 0xf) << 4) /* LED1 / ~LINKSPD[1] selector */ -#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0) +#define BCM54XX_SHD_LEDS1_LED1(src) ((src & 0xf) << 0) +#define BCM54XX_SHD_LEDS2 0x0e /* 01110: LED Selector 2 */ #define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */ #define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */ #define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */ @@ -253,6 +257,9 @@ #define BCM54XX_TOP_MISC_IDDQ_SD (1 << 2) #define BCM54XX_TOP_MISC_IDDQ_SR (1 << 3) +#define BCM54XX_TOP_MISC_LED_CTL (MII_BCM54XX_EXP_SEL_TOP + 0x0C) +#define BCM54XX_LED4_SEL_INTR BIT(1) + /* * BCM5482: Secondary SerDes registers */ @@ -272,6 +279,57 @@ #define BCM54612E_EXP_SPARE0 (MII_BCM54XX_EXP_SEL_ETC + 0x34) #define BCM54612E_LED4_CLK125OUT_EN (1 << 1) + +/* Wake-on-LAN registers */ +#define BCM54XX_WOL_MAIN_CTL (MII_BCM54XX_EXP_SEL_WOL + 0x80) +#define BCM54XX_WOL_EN BIT(0) +#define BCM54XX_WOL_MODE_SINGLE_MPD 0 +#define BCM54XX_WOL_MODE_SINGLE_MPDSEC 1 +#define BCM54XX_WOL_MODE_DUAL 2 +#define BCM54XX_WOL_MODE_SHIFT 1 +#define BCM54XX_WOL_MODE_MASK 0x3 +#define BCM54XX_WOL_MP_MSB_FF_EN BIT(3) +#define BCM54XX_WOL_SECKEY_OPT_4B 0 +#define BCM54XX_WOL_SECKEY_OPT_6B 1 +#define BCM54XX_WOL_SECKEY_OPT_8B 2 +#define BCM54XX_WOL_SECKEY_OPT_SHIFT 4 +#define BCM54XX_WOL_SECKEY_OPT_MASK 0x3 +#define BCM54XX_WOL_L2_TYPE_CHK BIT(6) +#define BCM54XX_WOL_L4IPV4UDP_CHK BIT(7) +#define BCM54XX_WOL_L4IPV6UDP_CHK BIT(8) +#define BCM54XX_WOL_UDPPORT_CHK BIT(9) +#define BCM54XX_WOL_CRC_CHK BIT(10) +#define BCM54XX_WOL_SECKEY_MODE BIT(11) +#define BCM54XX_WOL_RST BIT(12) +#define BCM54XX_WOL_DIR_PKT_EN BIT(13) +#define BCM54XX_WOL_MASK_MODE_DA_FF 0 +#define BCM54XX_WOL_MASK_MODE_DA_MPD 1 +#define BCM54XX_WOL_MASK_MODE_DA_ONLY 2 +#define BCM54XX_WOL_MASK_MODE_MPD 3 +#define BCM54XX_WOL_MASK_MODE_SHIFT 14 +#define BCM54XX_WOL_MASK_MODE_MASK 0x3 + +#define BCM54XX_WOL_INNER_PROTO (MII_BCM54XX_EXP_SEL_WOL + 0x81) +#define BCM54XX_WOL_OUTER_PROTO (MII_BCM54XX_EXP_SEL_WOL + 0x82) +#define BCM54XX_WOL_OUTER_PROTO2 (MII_BCM54XX_EXP_SEL_WOL + 0x83) + +#define BCM54XX_WOL_MPD_DATA1(x) (MII_BCM54XX_EXP_SEL_WOL + 0x84 + (x)) +#define BCM54XX_WOL_MPD_DATA2(x) (MII_BCM54XX_EXP_SEL_WOL + 0x87 + (x)) +#define BCM54XX_WOL_SEC_KEY_8B (MII_BCM54XX_EXP_SEL_WOL + 0x8A) +#define BCM54XX_WOL_MASK(x) (MII_BCM54XX_EXP_SEL_WOL + 0x8B + (x)) +#define BCM54XX_SEC_KEY_STORE(x) (MII_BCM54XX_EXP_SEL_WOL + 0x8E) +#define BCM54XX_WOL_SHARED_CNT (MII_BCM54XX_EXP_SEL_WOL + 0x92) + +#define BCM54XX_WOL_INT_MASK (MII_BCM54XX_EXP_SEL_WOL + 0x93) +#define BCM54XX_WOL_PKT1 BIT(0) +#define BCM54XX_WOL_PKT2 BIT(1) +#define BCM54XX_WOL_DIR BIT(2) +#define BCM54XX_WOL_ALL_INTRS (BCM54XX_WOL_PKT1 | \ + BCM54XX_WOL_PKT2 | \ + BCM54XX_WOL_DIR) + +#define BCM54XX_WOL_INT_STATUS (MII_BCM54XX_EXP_SEL_WOL + 0x94) + /*****************************************************************************/ /* Fast Ethernet Transceiver definitions. */ /*****************************************************************************/ @@ -304,6 +362,8 @@ #define LPI_FEATURE_EN 0x8000 #define LPI_FEATURE_EN_DIG1000X 0x4000 +#define BRCM_CL45VEN_EEE_LPI_CNT 0x803f + /* Core register definitions*/ #define MII_BRCM_CORE_BASE12 0x12 #define MII_BRCM_CORE_BASE13 0x13 diff --git a/include/linux/bsg.h b/include/linux/bsg.h index 1ac81c809da9..ee2df73edf83 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -9,7 +9,7 @@ struct device; struct request_queue; typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr, - fmode_t mode, unsigned int timeout); + bool open_for_write, unsigned int timeout); struct bsg_device *bsg_register_queue(struct request_queue *q, struct device *parent, const char *name, diff --git a/include/linux/btf.h b/include/linux/btf.h index 508199e38415..cac9f304e27a 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -98,10 +98,14 @@ struct btf_type; union bpf_attr; struct btf_show; struct btf_id_set; +struct bpf_prog; + +typedef int (*btf_kfunc_filter_t)(const struct bpf_prog *prog, u32 kfunc_id); struct btf_kfunc_id_set { struct module *owner; struct btf_id_set8 *set; + btf_kfunc_filter_t filter; }; struct btf_id_dtor_kfunc { @@ -479,7 +483,6 @@ static inline void *btf_id_set8_contains(const struct btf_id_set8 *set, u32 id) return bsearch(&id, set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func); } -struct bpf_prog; struct bpf_verifier_log; #ifdef CONFIG_BPF_SYSCALL @@ -487,10 +490,10 @@ const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id); const char *btf_name_by_offset(const struct btf *btf, u32 offset); struct btf *btf_parse_vmlinux(void); struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog); -u32 *btf_kfunc_id_set_contains(const struct btf *btf, - enum bpf_prog_type prog_type, - u32 kfunc_btf_id); -u32 *btf_kfunc_is_modify_return(const struct btf *btf, u32 kfunc_btf_id); +u32 *btf_kfunc_id_set_contains(const struct btf *btf, u32 kfunc_btf_id, + const struct bpf_prog *prog); +u32 *btf_kfunc_is_modify_return(const struct btf *btf, u32 kfunc_btf_id, + const struct bpf_prog *prog); int register_btf_kfunc_id_set(enum bpf_prog_type prog_type, const struct btf_kfunc_id_set *s); int register_btf_fmodret_id_set(const struct btf_kfunc_id_set *kset); @@ -517,8 +520,9 @@ static inline const char *btf_name_by_offset(const struct btf *btf, return NULL; } static inline u32 *btf_kfunc_id_set_contains(const struct btf *btf, - enum bpf_prog_type prog_type, - u32 kfunc_btf_id) + u32 kfunc_btf_id, + struct bpf_prog *prog) + { return NULL; } diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 1520793c72da..6cb3e9af78c9 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -217,6 +217,10 @@ int inode_has_buffers(struct inode *); void invalidate_inode_buffers(struct inode *); int remove_inode_buffers(struct inode *inode); int sync_mapping_buffers(struct address_space *mapping); +int generic_buffers_fsync_noflush(struct file *file, loff_t start, loff_t end, + bool datasync); +int generic_buffers_fsync(struct file *file, loff_t start, loff_t end, + bool datasync); void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len); static inline void clean_bdev_bh_alias(struct buffer_head *bh) @@ -263,7 +267,7 @@ extern int buffer_heads_over_limit; void block_invalidate_folio(struct folio *folio, size_t offset, size_t length); int block_write_full_page(struct page *page, get_block_t *get_block, struct writeback_control *wbc); -int __block_write_full_page(struct inode *inode, struct page *page, +int __block_write_full_folio(struct inode *inode, struct folio *folio, get_block_t *get_block, struct writeback_control *wbc, bh_end_io_t *handler); int block_read_full_folio(struct folio *, get_block_t *); @@ -278,7 +282,7 @@ int block_write_end(struct file *, struct address_space *, int generic_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *); -void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); +void folio_zero_new_buffers(struct folio *folio, size_t from, size_t to); void clean_page_buffers(struct page *page); int cont_write_begin(struct file *, struct address_space *, loff_t, unsigned, struct page **, void **, diff --git a/include/linux/cache.h b/include/linux/cache.h index 5da1bbd96154..9900d20b76c2 100644 --- a/include/linux/cache.h +++ b/include/linux/cache.h @@ -98,4 +98,10 @@ struct cacheline_padding { #define CACHELINE_PADDING(name) #endif +#ifdef ARCH_DMA_MINALIGN +#define ARCH_HAS_DMA_MINALIGN +#else +#define ARCH_DMA_MINALIGN __alignof__(unsigned long long) +#endif + #endif /* __LINUX_CACHE_H */ diff --git a/include/linux/can/length.h b/include/linux/can/length.h index 6995092b774e..abc978b38f79 100644 --- a/include/linux/can/length.h +++ b/include/linux/can/length.h @@ -1,126 +1,258 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2020 Oliver Hartkopp <socketcan@hartkopp.net> * Copyright (C) 2020 Marc Kleine-Budde <kernel@pengutronix.de> + * Copyright (C) 2020, 2023 Vincent Mailhol <mailhol.vincent@wanadoo.fr> */ #ifndef _CAN_LENGTH_H #define _CAN_LENGTH_H +#include <linux/bits.h> +#include <linux/can.h> +#include <linux/can/netlink.h> +#include <linux/math.h> + /* - * Size of a Classical CAN Standard Frame + * Size of a Classical CAN Standard Frame header in bits * - * Name of Field Bits + * Name of Field Bits * --------------------------------------------------------- - * Start-of-frame 1 - * Identifier 11 - * Remote transmission request (RTR) 1 - * Identifier extension bit (IDE) 1 - * Reserved bit (r0) 1 - * Data length code (DLC) 4 - * Data field 0...64 - * CRC 15 - * CRC delimiter 1 - * ACK slot 1 - * ACK delimiter 1 - * End-of-frame (EOF) 7 - * Inter frame spacing 3 + * Start Of Frame (SOF) 1 + * Arbitration field: + * base ID 11 + * Remote Transmission Request (RTR) 1 + * Control field: + * IDentifier Extension bit (IDE) 1 + * FD Format indicator (FDF) 1 + * Data Length Code (DLC) 4 + * + * including all fields preceding the data field, ignoring bitstuffing + */ +#define CAN_FRAME_HEADER_SFF_BITS 19 + +/* + * Size of a Classical CAN Extended Frame header in bits + * + * Name of Field Bits + * --------------------------------------------------------- + * Start Of Frame (SOF) 1 + * Arbitration field: + * base ID 11 + * Substitute Remote Request (SRR) 1 + * IDentifier Extension bit (IDE) 1 + * ID extension 18 + * Remote Transmission Request (RTR) 1 + * Control field: + * FD Format indicator (FDF) 1 + * Reserved bit (r0) 1 + * Data length code (DLC) 4 + * + * including all fields preceding the data field, ignoring bitstuffing + */ +#define CAN_FRAME_HEADER_EFF_BITS 39 + +/* + * Size of a CAN-FD Standard Frame in bits * - * rounded up and ignoring bitstuffing + * Name of Field Bits + * --------------------------------------------------------- + * Start Of Frame (SOF) 1 + * Arbitration field: + * base ID 11 + * Remote Request Substitution (RRS) 1 + * Control field: + * IDentifier Extension bit (IDE) 1 + * FD Format indicator (FDF) 1 + * Reserved bit (res) 1 + * Bit Rate Switch (BRS) 1 + * Error Status Indicator (ESI) 1 + * Data length code (DLC) 4 + * + * including all fields preceding the data field, ignoring bitstuffing + */ +#define CANFD_FRAME_HEADER_SFF_BITS 22 + +/* + * Size of a CAN-FD Extended Frame in bits + * + * Name of Field Bits + * --------------------------------------------------------- + * Start Of Frame (SOF) 1 + * Arbitration field: + * base ID 11 + * Substitute Remote Request (SRR) 1 + * IDentifier Extension bit (IDE) 1 + * ID extension 18 + * Remote Request Substitution (RRS) 1 + * Control field: + * FD Format indicator (FDF) 1 + * Reserved bit (res) 1 + * Bit Rate Switch (BRS) 1 + * Error Status Indicator (ESI) 1 + * Data length code (DLC) 4 + * + * including all fields preceding the data field, ignoring bitstuffing */ -#define CAN_FRAME_OVERHEAD_SFF DIV_ROUND_UP(47, 8) +#define CANFD_FRAME_HEADER_EFF_BITS 41 /* - * Size of a Classical CAN Extended Frame + * Size of a CAN CRC Field in bits * * Name of Field Bits * --------------------------------------------------------- - * Start-of-frame 1 - * Identifier A 11 - * Substitute remote request (SRR) 1 - * Identifier extension bit (IDE) 1 - * Identifier B 18 - * Remote transmission request (RTR) 1 - * Reserved bits (r1, r0) 2 - * Data length code (DLC) 4 - * Data field 0...64 - * CRC 15 - * CRC delimiter 1 - * ACK slot 1 - * ACK delimiter 1 - * End-of-frame (EOF) 7 - * Inter frame spacing 3 + * CRC sequence (CRC15) 15 + * CRC Delimiter 1 * - * rounded up and ignoring bitstuffing + * ignoring bitstuffing */ -#define CAN_FRAME_OVERHEAD_EFF DIV_ROUND_UP(67, 8) +#define CAN_FRAME_CRC_FIELD_BITS 16 /* - * Size of a CAN-FD Standard Frame + * Size of a CAN-FD CRC17 Field in bits (length: 0..16) * * Name of Field Bits * --------------------------------------------------------- - * Start-of-frame 1 - * Identifier 11 - * Reserved bit (r1) 1 - * Identifier extension bit (IDE) 1 - * Flexible data rate format (FDF) 1 - * Reserved bit (r0) 1 - * Bit Rate Switch (BRS) 1 - * Error Status Indicator (ESI) 1 - * Data length code (DLC) 4 - * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 - * CRC 0...16: 17 20...64:21 - * CRC delimiter (CD) 1 - * ACK slot (AS) 1 - * ACK delimiter (AD) 1 - * End-of-frame (EOF) 7 - * Inter frame spacing 3 - * - * assuming CRC21, rounded up and ignoring bitstuffing - */ -#define CANFD_FRAME_OVERHEAD_SFF DIV_ROUND_UP(61, 8) + * Stuff Count 4 + * CRC Sequence (CRC17) 17 + * CRC Delimiter 1 + * Fixed stuff bits 6 + */ +#define CANFD_FRAME_CRC17_FIELD_BITS 28 /* - * Size of a CAN-FD Extended Frame + * Size of a CAN-FD CRC21 Field in bits (length: 20..64) * * Name of Field Bits * --------------------------------------------------------- - * Start-of-frame 1 - * Identifier A 11 - * Substitute remote request (SRR) 1 - * Identifier extension bit (IDE) 1 - * Identifier B 18 - * Reserved bit (r1) 1 - * Flexible data rate format (FDF) 1 - * Reserved bit (r0) 1 - * Bit Rate Switch (BRS) 1 - * Error Status Indicator (ESI) 1 - * Data length code (DLC) 4 - * Data field 0...512 - * Stuff Bit Count (SBC) 0...16: 4 20...64:5 - * CRC 0...16: 17 20...64:21 - * CRC delimiter (CD) 1 - * ACK slot (AS) 1 - * ACK delimiter (AD) 1 - * End-of-frame (EOF) 7 - * Inter frame spacing 3 - * - * assuming CRC21, rounded up and ignoring bitstuffing - */ -#define CANFD_FRAME_OVERHEAD_EFF DIV_ROUND_UP(80, 8) + * Stuff Count 4 + * CRC sequence (CRC21) 21 + * CRC Delimiter 1 + * Fixed stuff bits 7 + */ +#define CANFD_FRAME_CRC21_FIELD_BITS 33 + +/* + * Size of a CAN(-FD) Frame footer in bits + * + * Name of Field Bits + * --------------------------------------------------------- + * ACK slot 1 + * ACK delimiter 1 + * End Of Frame (EOF) 7 + * + * including all fields following the CRC field + */ +#define CAN_FRAME_FOOTER_BITS 9 + +/* + * First part of the Inter Frame Space + * (a.k.a. IMF - intermission field) + */ +#define CAN_INTERMISSION_BITS 3 + +/** + * can_bitstuffing_len() - Calculate the maximum length with bitstuffing + * @destuffed_len: length of a destuffed bit stream + * + * The worst bit stuffing case is a sequence in which dominant and + * recessive bits alternate every four bits: + * + * Destuffed: 1 1111 0000 1111 0000 1111 + * Stuffed: 1 1111o 0000i 1111o 0000i 1111o + * + * Nomenclature + * + * - "0": dominant bit + * - "o": dominant stuff bit + * - "1": recessive bit + * - "i": recessive stuff bit + * + * Aside from the first bit, one stuff bit is added every four bits. + * + * Return: length of the stuffed bit stream in the worst case scenario. + */ +#define can_bitstuffing_len(destuffed_len) \ + (destuffed_len + (destuffed_len - 1) / 4) + +#define __can_bitstuffing_len(bitstuffing, destuffed_len) \ + (bitstuffing ? can_bitstuffing_len(destuffed_len) : \ + destuffed_len) + +#define __can_cc_frame_bits(is_eff, bitstuffing, \ + intermission, data_len) \ +( \ + __can_bitstuffing_len(bitstuffing, \ + (is_eff ? CAN_FRAME_HEADER_EFF_BITS : \ + CAN_FRAME_HEADER_SFF_BITS) + \ + (data_len) * BITS_PER_BYTE + \ + CAN_FRAME_CRC_FIELD_BITS) + \ + CAN_FRAME_FOOTER_BITS + \ + (intermission ? CAN_INTERMISSION_BITS : 0) \ +) + +#define __can_fd_frame_bits(is_eff, bitstuffing, \ + intermission, data_len) \ +( \ + __can_bitstuffing_len(bitstuffing, \ + (is_eff ? CANFD_FRAME_HEADER_EFF_BITS : \ + CANFD_FRAME_HEADER_SFF_BITS) + \ + (data_len) * BITS_PER_BYTE) + \ + ((data_len) <= 16 ? \ + CANFD_FRAME_CRC17_FIELD_BITS : \ + CANFD_FRAME_CRC21_FIELD_BITS) + \ + CAN_FRAME_FOOTER_BITS + \ + (intermission ? CAN_INTERMISSION_BITS : 0) \ +) + +/** + * can_frame_bits() - Calculate the number of bits on the wire in a + * CAN frame + * @is_fd: true: CAN-FD frame; false: Classical CAN frame. + * @is_eff: true: Extended frame; false: Standard frame. + * @bitstuffing: true: calculate the bitstuffing worst case; false: + * calculate the bitstuffing best case (no dynamic + * bitstuffing). CAN-FD's fixed stuff bits are always included. + * @intermission: if and only if true, include the inter frame space + * assuming no bus idle (i.e. only the intermission). Strictly + * speaking, the inter frame space is not part of the + * frame. However, it is needed when calculating the delay + * between the Start Of Frame of two consecutive frames. + * @data_len: length of the data field in bytes. Correspond to + * can(fd)_frame->len. Should be zero for remote frames. No + * sanitization is done on @data_len and it shall have no side + * effects. + * + * Return: the numbers of bits on the wire of a CAN frame. + */ +#define can_frame_bits(is_fd, is_eff, bitstuffing, \ + intermission, data_len) \ +( \ + is_fd ? __can_fd_frame_bits(is_eff, bitstuffing, \ + intermission, data_len) : \ + __can_cc_frame_bits(is_eff, bitstuffing, \ + intermission, data_len) \ +) + +/* + * Number of bytes in a CAN frame + * (rounded up, including intermission) + */ +#define can_frame_bytes(is_fd, is_eff, bitstuffing, data_len) \ + DIV_ROUND_UP(can_frame_bits(is_fd, is_eff, bitstuffing, \ + true, data_len), \ + BITS_PER_BYTE) /* * Maximum size of a Classical CAN frame - * (rounded up and ignoring bitstuffing) + * (rounded up, ignoring bitstuffing but including intermission) */ -#define CAN_FRAME_LEN_MAX (CAN_FRAME_OVERHEAD_EFF + CAN_MAX_DLEN) +#define CAN_FRAME_LEN_MAX can_frame_bytes(false, true, false, CAN_MAX_DLEN) /* * Maximum size of a CAN-FD frame - * (rounded up and ignoring bitstuffing) + * (rounded up, ignoring dynamic bitstuffing but including intermission) */ -#define CANFD_FRAME_LEN_MAX (CANFD_FRAME_OVERHEAD_EFF + CANFD_MAX_DLEN) +#define CANFD_FRAME_LEN_MAX can_frame_bytes(true, true, false, CANFD_MAX_DLEN) /* * can_cc_dlc2len(value) - convert a given data length code (dlc) of a diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 67caa909e3e6..98c6fd0b39b6 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -13,6 +13,7 @@ #include <linux/fs.h> /* not really needed, later.. */ #include <linux/list.h> +#include <linux/blkdev.h> #include <scsi/scsi_common.h> #include <uapi/linux/cdrom.h> @@ -61,9 +62,9 @@ struct cdrom_device_info { __u8 last_sense; __u8 media_written; /* dirty flag, DVD+RW bookkeeping */ unsigned short mmc3_profile; /* current MMC3 profile */ - int for_data; int (*exit)(struct cdrom_device_info *); int mrw_mode_page; + bool opened_for_data; __s64 last_media_change_ms; }; @@ -101,11 +102,10 @@ int cdrom_read_tocentry(struct cdrom_device_info *cdi, struct cdrom_tocentry *entry); /* the general block_device operations structure: */ -extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, - fmode_t mode); -extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode); -extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, - fmode_t mode, unsigned int cmd, unsigned long arg); +int cdrom_open(struct cdrom_device_info *cdi, blk_mode_t mode); +void cdrom_release(struct cdrom_device_info *cdi); +int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, + unsigned int cmd, unsigned long arg); extern unsigned int cdrom_check_events(struct cdrom_device_info *cdi, unsigned int clearing); diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index 35ef41d8a61a..bead71b7bc73 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -14,7 +14,6 @@ #include <linux/mod_devicetable.h> #define MAX_CDX_DEV_RESOURCES 4 -#define CDX_ANY_ID (0xFFFF) #define CDX_CONTROLLER_ID_SHIFT 4 #define CDX_BUS_NUM_MASK 0xF diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 885f5395fcd0..b307013b9c6c 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -118,7 +118,6 @@ int cgroup_rm_cftypes(struct cftype *cfts); void cgroup_file_notify(struct cgroup_file *cfile); void cgroup_file_show(struct cgroup_file *cfile, bool show); -int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry); int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *tsk); @@ -692,7 +691,6 @@ static inline void cgroup_path_from_kernfs_id(u64 id, char *buf, size_t buflen) */ void cgroup_rstat_updated(struct cgroup *cgrp, int cpu); void cgroup_rstat_flush(struct cgroup *cgrp); -void cgroup_rstat_flush_atomic(struct cgroup *cgrp); void cgroup_rstat_flush_hold(struct cgroup *cgrp); void cgroup_rstat_flush_release(void); diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h new file mode 100644 index 000000000000..53f1a7a932b0 --- /dev/null +++ b/include/linux/cleanup.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_GUARDS_H +#define __LINUX_GUARDS_H + +#include <linux/compiler.h> + +/* + * DEFINE_FREE(name, type, free): + * simple helper macro that defines the required wrapper for a __free() + * based cleanup function. @free is an expression using '_T' to access + * the variable. + * + * __free(name): + * variable attribute to add a scoped based cleanup to the variable. + * + * no_free_ptr(var): + * like a non-atomic xchg(var, NULL), such that the cleanup function will + * be inhibited -- provided it sanely deals with a NULL value. + * + * return_ptr(p): + * returns p while inhibiting the __free(). + * + * Ex. + * + * DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) + * + * struct obj *p __free(kfree) = kmalloc(...); + * if (!p) + * return NULL; + * + * if (!init_obj(p)) + * return NULL; + * + * return_ptr(p); + */ + +#define DEFINE_FREE(_name, _type, _free) \ + static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; } + +#define __free(_name) __cleanup(__free_##_name) + +#define no_free_ptr(p) \ + ({ __auto_type __ptr = (p); (p) = NULL; __ptr; }) + +#define return_ptr(p) return no_free_ptr(p) + + +/* + * DEFINE_CLASS(name, type, exit, init, init_args...): + * helper to define the destructor and constructor for a type. + * @exit is an expression using '_T' -- similar to FREE above. + * @init is an expression in @init_args resulting in @type + * + * EXTEND_CLASS(name, ext, init, init_args...): + * extends class @name to @name@ext with the new constructor + * + * CLASS(name, var)(args...): + * declare the variable @var as an instance of the named class + * + * Ex. + * + * DEFINE_CLASS(fdget, struct fd, fdput(_T), fdget(fd), int fd) + * + * CLASS(fdget, f)(fd); + * if (!f.file) + * return -EBADF; + * + * // use 'f' without concern + */ + +#define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...) \ +typedef _type class_##_name##_t; \ +static inline void class_##_name##_destructor(_type *p) \ +{ _type _T = *p; _exit; } \ +static inline _type class_##_name##_constructor(_init_args) \ +{ _type t = _init; return t; } + +#define EXTEND_CLASS(_name, ext, _init, _init_args...) \ +typedef class_##_name##_t class_##_name##ext##_t; \ +static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\ +{ class_##_name##_destructor(p); } \ +static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ +{ class_##_name##_t t = _init; return t; } + +#define CLASS(_name, var) \ + class_##_name##_t var __cleanup(class_##_name##_destructor) = \ + class_##_name##_constructor + + +/* + * DEFINE_GUARD(name, type, lock, unlock): + * trivial wrapper around DEFINE_CLASS() above specifically + * for locks. + * + * guard(name): + * an anonymous instance of the (guard) class + * + * scoped_guard (name, args...) { }: + * similar to CLASS(name, scope)(args), except the variable (with the + * explicit name 'scope') is declard in a for-loop such that its scope is + * bound to the next (compound) statement. + * + */ + +#define DEFINE_GUARD(_name, _type, _lock, _unlock) \ + DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T) + +#define guard(_name) \ + CLASS(_name, __UNIQUE_ID(guard)) + +#define scoped_guard(_name, args...) \ + for (CLASS(_name, scope)(args), \ + *done = NULL; !done; done = (void *)1) + +/* + * Additional helper macros for generating lock guards with types, either for + * locks that don't have a native type (eg. RCU, preempt) or those that need a + * 'fat' pointer (eg. spin_lock_irqsave). + * + * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...) + * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...) + * + * will result in the following type: + * + * typedef struct { + * type *lock; // 'type := void' for the _0 variant + * __VA_ARGS__; + * } class_##name##_t; + * + * As above, both _lock and _unlock are statements, except this time '_T' will + * be a pointer to the above struct. + */ + +#define __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, ...) \ +typedef struct { \ + _type *lock; \ + __VA_ARGS__; \ +} class_##_name##_t; \ + \ +static inline void class_##_name##_destructor(class_##_name##_t *_T) \ +{ \ + if (_T->lock) { _unlock; } \ +} + + +#define __DEFINE_LOCK_GUARD_1(_name, _type, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(_type *l) \ +{ \ + class_##_name##_t _t = { .lock = l }, *_T = &_t; \ + _lock; \ + return _t; \ +} + +#define __DEFINE_LOCK_GUARD_0(_name, _lock) \ +static inline class_##_name##_t class_##_name##_constructor(void) \ +{ \ + class_##_name##_t _t = { .lock = (void*)1 }, \ + *_T __maybe_unused = &_t; \ + _lock; \ + return _t; \ +} + +#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ +__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_1(_name, _type, _lock) + +#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ +__DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ +__DEFINE_LOCK_GUARD_0(_name, _lock) + +#endif /* __LINUX_GUARDS_H */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 28ff6f1a6ada..0f0cd01906b4 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -415,7 +415,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, * @flags: framework-specific flags * @fixed_rate: non-adjustable clock rate */ -#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_hw, flags, \ +#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_data, flags, \ fixed_rate) \ __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL, \ (parent_data), (flags), (fixed_rate), 0, \ @@ -1333,6 +1333,8 @@ int __clk_mux_determine_rate_closest(struct clk_hw *hw, int clk_mux_determine_rate_flags(struct clk_hw *hw, struct clk_rate_request *req, unsigned long flags); +int clk_hw_determine_rate_no_reparent(struct clk_hw *hw, + struct clk_rate_request *req); void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent); void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate, unsigned long *max_rate); diff --git a/include/linux/compaction.h b/include/linux/compaction.h index a6e512cfb670..e94776496049 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -89,89 +89,17 @@ extern enum compact_result try_to_compact_pages(gfp_t gfp_mask, const struct alloc_context *ac, enum compact_priority prio, struct page **page); extern void reset_isolation_suitable(pg_data_t *pgdat); -extern enum compact_result compaction_suitable(struct zone *zone, int order, - unsigned int alloc_flags, int highest_zoneidx); +extern bool compaction_suitable(struct zone *zone, int order, + int highest_zoneidx); extern void compaction_defer_reset(struct zone *zone, int order, bool alloc_success); -/* Compaction has made some progress and retrying makes sense */ -static inline bool compaction_made_progress(enum compact_result result) -{ - /* - * Even though this might sound confusing this in fact tells us - * that the compaction successfully isolated and migrated some - * pageblocks. - */ - if (result == COMPACT_SUCCESS) - return true; - - return false; -} - -/* Compaction has failed and it doesn't make much sense to keep retrying. */ -static inline bool compaction_failed(enum compact_result result) -{ - /* All zones were scanned completely and still not result. */ - if (result == COMPACT_COMPLETE) - return true; - - return false; -} - -/* Compaction needs reclaim to be performed first, so it can continue. */ -static inline bool compaction_needs_reclaim(enum compact_result result) -{ - /* - * Compaction backed off due to watermark checks for order-0 - * so the regular reclaim has to try harder and reclaim something. - */ - if (result == COMPACT_SKIPPED) - return true; - - return false; -} - -/* - * Compaction has backed off for some reason after doing some work or none - * at all. It might be throttling or lock contention. Retrying might be still - * worthwhile, but with a higher priority if allowed. - */ -static inline bool compaction_withdrawn(enum compact_result result) -{ - /* - * If compaction is deferred for high-order allocations, it is - * because sync compaction recently failed. If this is the case - * and the caller requested a THP allocation, we do not want - * to heavily disrupt the system, so we fail the allocation - * instead of entering direct reclaim. - */ - if (result == COMPACT_DEFERRED) - return true; - - /* - * If compaction in async mode encounters contention or blocks higher - * priority task we back off early rather than cause stalls. - */ - if (result == COMPACT_CONTENDED) - return true; - - /* - * Page scanners have met but we haven't scanned full zones so this - * is a back off in fact. - */ - if (result == COMPACT_PARTIAL_SKIPPED) - return true; - - return false; -} - - bool compaction_zonelist_suitable(struct alloc_context *ac, int order, int alloc_flags); -extern void kcompactd_run(int nid); -extern void kcompactd_stop(int nid); +extern void __meminit kcompactd_run(int nid); +extern void __meminit kcompactd_stop(int nid); extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx); #else @@ -179,32 +107,12 @@ static inline void reset_isolation_suitable(pg_data_t *pgdat) { } -static inline enum compact_result compaction_suitable(struct zone *zone, int order, - int alloc_flags, int highest_zoneidx) -{ - return COMPACT_SKIPPED; -} - -static inline bool compaction_made_progress(enum compact_result result) -{ - return false; -} - -static inline bool compaction_failed(enum compact_result result) -{ - return false; -} - -static inline bool compaction_needs_reclaim(enum compact_result result) +static inline bool compaction_suitable(struct zone *zone, int order, + int highest_zoneidx) { return false; } -static inline bool compaction_withdrawn(enum compact_result result) -{ - return true; -} - static inline void kcompactd_run(int nid) { } diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index 6cfd6902bd5b..9b673fefcef8 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -5,6 +5,15 @@ /* Compiler specific definitions for Clang compiler */ +/* + * Clang prior to 17 is being silly and considers many __cleanup() variables + * as unused (because they are, their sole purpose is to go out of scope). + * + * https://reviews.llvm.org/D152180 + */ +#undef __cleanup +#define __cleanup(func) __maybe_unused __attribute__((__cleanup__(func))) + /* same as gcc, this was present in clang-2.6 so we can assume it works * with any version that can compile the kernel */ diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 947a60b801db..d7779a18b24f 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -12,11 +12,10 @@ * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code * to disable branch tracing on a per file basis. */ -#if defined(CONFIG_TRACE_BRANCH_PROFILING) \ - && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__) void ftrace_likely_update(struct ftrace_likely_data *f, int val, int expect, int is_constant); - +#if defined(CONFIG_TRACE_BRANCH_PROFILING) \ + && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__) #define likely_notrace(x) __builtin_expect(!!(x), 1) #define unlikely_notrace(x) __builtin_expect(!!(x), 0) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index e659cb6fded3..00efa35c350f 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -70,6 +70,12 @@ #define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) /* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#cleanup + */ +#define __cleanup(func) __attribute__((__cleanup__(func))) + +/* * Note the long name. * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute @@ -124,6 +130,19 @@ #endif /* + * Optional: only supported since gcc >= 14 + * Optional: only supported since clang >= 17 + * + * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 + * clang: https://reviews.llvm.org/D148381 + */ +#if __has_attribute(__element_count__) +# define __counted_by(member) __attribute__((__element_count__(#member))) +#else +# define __counted_by(member) +#endif + +/* * Optional: only supported since clang >= 14.0 * * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-error-function-attribute @@ -256,6 +275,18 @@ #define __noreturn __attribute__((__noreturn__)) /* + * Optional: only supported since GCC >= 11.1, clang >= 7.0. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fstack_005fprotector-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#no-stack-protector-safebuffers + */ +#if __has_attribute(__no_stack_protector__) +# define __no_stack_protector __attribute__((__no_stack_protector__)) +#else +# define __no_stack_protector +#endif + +/* * Optional: not supported by gcc. * * clang: https://clang.llvm.org/docs/AttributeReference.html#overloadable diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index d3cbb6c16bab..6e76b9dba00e 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -119,7 +119,7 @@ extern void ct_idle_exit(void); */ static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void) { - return !(arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & RCU_DYNTICKS_IDX); + return !(raw_atomic_read(this_cpu_ptr(&context_tracking.state)) & RCU_DYNTICKS_IDX); } /* @@ -128,7 +128,7 @@ static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void) */ static __always_inline unsigned long ct_state_inc(int incby) { - return arch_atomic_add_return(incby, this_cpu_ptr(&context_tracking.state)); + return raw_atomic_add_return(incby, this_cpu_ptr(&context_tracking.state)); } static __always_inline bool warn_rcu_enter(void) diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index fdd537ea513f..bbff5f7f8803 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -51,7 +51,7 @@ DECLARE_PER_CPU(struct context_tracking, context_tracking); #ifdef CONFIG_CONTEXT_TRACKING_USER static __always_inline int __ct_state(void) { - return arch_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK; + return raw_atomic_read(this_cpu_ptr(&context_tracking.state)) & CT_STATE_MASK; } #endif diff --git a/include/linux/coresight.h b/include/linux/coresight.h index f19a47b9bb5a..bf70987240e4 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -41,10 +41,11 @@ enum coresight_dev_type { CORESIGHT_DEV_TYPE_LINKSINK, CORESIGHT_DEV_TYPE_SOURCE, CORESIGHT_DEV_TYPE_HELPER, - CORESIGHT_DEV_TYPE_ECT, + CORESIGHT_DEV_TYPE_MAX }; enum coresight_dev_subtype_sink { + CORESIGHT_DEV_SUBTYPE_SINK_DUMMY, CORESIGHT_DEV_SUBTYPE_SINK_PORT, CORESIGHT_DEV_SUBTYPE_SINK_BUFFER, CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM, @@ -66,12 +67,7 @@ enum coresight_dev_subtype_source { enum coresight_dev_subtype_helper { CORESIGHT_DEV_SUBTYPE_HELPER_CATU, -}; - -/* Embedded Cross Trigger (ECT) sub-types */ -enum coresight_dev_subtype_ect { - CORESIGHT_DEV_SUBTYPE_ECT_NONE, - CORESIGHT_DEV_SUBTYPE_ECT_CTI, + CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI }; /** @@ -84,8 +80,6 @@ enum coresight_dev_subtype_ect { * by @coresight_dev_subtype_source. * @helper_subtype: type of helper this component is, as defined * by @coresight_dev_subtype_helper. - * @ect_subtype: type of cross trigger this component is, as - * defined by @coresight_dev_subtype_ect */ union coresight_dev_subtype { /* We have some devices which acts as LINK and SINK */ @@ -95,21 +89,25 @@ union coresight_dev_subtype { }; enum coresight_dev_subtype_source source_subtype; enum coresight_dev_subtype_helper helper_subtype; - enum coresight_dev_subtype_ect ect_subtype; }; /** * struct coresight_platform_data - data harvested from the firmware * specification. * - * @nr_inport: Number of elements for the input connections. - * @nr_outport: Number of elements for the output connections. - * @conns: Sparse array of nr_outport connections from this component. + * @nr_inconns: Number of elements for the input connections. + * @nr_outconns: Number of elements for the output connections. + * @out_conns: Array of nr_outconns pointers to connections from this + * component. + * @in_conns: Sparse array of pointers to input connections. Sparse + * because the source device owns the connection so when it's + * unloaded the connection leaves an empty slot. */ struct coresight_platform_data { - int nr_inport; - int nr_outport; - struct coresight_connection *conns; + int nr_inconns; + int nr_outconns; + struct coresight_connection **out_conns; + struct coresight_connection **in_conns; }; /** @@ -164,19 +162,42 @@ struct coresight_desc { /** * struct coresight_connection - representation of a single connection - * @outport: a connection's output port number. - * @child_port: remote component's port number @output is connected to. - * @chid_fwnode: remote component's fwnode handle. - * @child_dev: a @coresight_device representation of the component - connected to @outport. + * @src_port: a connection's output port number. + * @dest_port: destination's input port number @src_port is connected to. + * @dest_fwnode: destination component's fwnode handle. + * @dest_dev: a @coresight_device representation of the component + connected to @src_port. NULL until the device is created * @link: Representation of the connection as a sysfs link. + * + * The full connection structure looks like this, where in_conns store + * references to same connection as the source device's out_conns. + * + * +-----------------------------+ +-----------------------------+ + * |coresight_device | |coresight_connection | + * |-----------------------------| |-----------------------------| + * | | | | + * | | | dest_dev*|<-- + * |pdata->out_conns[nr_outconns]|<->|src_dev* | | + * | | | | | + * +-----------------------------+ +-----------------------------+ | + * | + * +-----------------------------+ | + * |coresight_device | | + * |------------------------------ | + * | | | + * | pdata->in_conns[nr_inconns]|<-- + * | | + * +-----------------------------+ */ struct coresight_connection { - int outport; - int child_port; - struct fwnode_handle *child_fwnode; - struct coresight_device *child_dev; + int src_port; + int dest_port; + struct fwnode_handle *dest_fwnode; + struct coresight_device *dest_dev; struct coresight_sysfs_link *link; + struct coresight_device *src_dev; + atomic_t src_refcnt; + atomic_t dest_refcnt; }; /** @@ -211,8 +232,6 @@ struct coresight_sysfs_link { * from source to that sink. * @ea: Device attribute for sink representation under PMU directory. * @def_sink: cached reference to default sink found for this device. - * @ect_dev: Associated cross trigger device. Not part of the trace data - * path or connections. * @nr_links: number of sysfs links created to other components from this * device. These will appear in the "connections" group. * @has_conns_grp: Have added a "connections" group for sysfs links. @@ -228,19 +247,16 @@ struct coresight_device { const struct coresight_ops *ops; struct csdev_access access; struct device dev; - atomic_t *refcnt; + atomic_t refcnt; bool orphan; bool enable; /* true only if configured as part of a path */ /* sink specific fields */ bool activated; /* true only if a sink is part of a path */ struct dev_ext_attribute *ea; struct coresight_device *def_sink; - /* cross trigger handling */ - struct coresight_device *ect_dev; /* sysfs links between components */ int nr_links; bool has_conns_grp; - bool ect_enabled; /* true only if associated ect device is enabled */ /* system configuration and feature lists */ struct list_head feature_csdev_list; struct list_head config_csdev_list; @@ -272,6 +288,12 @@ static struct coresight_dev_list (var) = { \ #define to_coresight_device(d) container_of(d, struct coresight_device, dev) +enum cs_mode { + CS_MODE_DISABLED, + CS_MODE_SYSFS, + CS_MODE_PERF, +}; + #define source_ops(csdev) csdev->ops->source_ops #define sink_ops(csdev) csdev->ops->sink_ops #define link_ops(csdev) csdev->ops->link_ops @@ -288,7 +310,8 @@ static struct coresight_dev_list (var) = { \ * @update_buffer: update buffer pointers after a trace session. */ struct coresight_ops_sink { - int (*enable)(struct coresight_device *csdev, u32 mode, void *data); + int (*enable)(struct coresight_device *csdev, enum cs_mode mode, + void *data); int (*disable)(struct coresight_device *csdev); void *(*alloc_buffer)(struct coresight_device *csdev, struct perf_event *event, void **pages, @@ -306,8 +329,12 @@ struct coresight_ops_sink { * @disable: disables flow between iport and oport. */ struct coresight_ops_link { - int (*enable)(struct coresight_device *csdev, int iport, int oport); - void (*disable)(struct coresight_device *csdev, int iport, int oport); + int (*enable)(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out); + void (*disable)(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out); }; /** @@ -320,8 +347,8 @@ struct coresight_ops_link { */ struct coresight_ops_source { int (*cpu_id)(struct coresight_device *csdev); - int (*enable)(struct coresight_device *csdev, - struct perf_event *event, u32 mode); + int (*enable)(struct coresight_device *csdev, struct perf_event *event, + enum cs_mode mode); void (*disable)(struct coresight_device *csdev, struct perf_event *event); }; @@ -336,27 +363,16 @@ struct coresight_ops_source { * @disable : Disable the device */ struct coresight_ops_helper { - int (*enable)(struct coresight_device *csdev, void *data); + int (*enable)(struct coresight_device *csdev, enum cs_mode mode, + void *data); int (*disable)(struct coresight_device *csdev, void *data); }; -/** - * struct coresight_ops_ect - Ops for an embedded cross trigger device - * - * @enable : Enable the device - * @disable : Disable the device - */ -struct coresight_ops_ect { - int (*enable)(struct coresight_device *csdev); - int (*disable)(struct coresight_device *csdev); -}; - struct coresight_ops { const struct coresight_ops_sink *sink_ops; const struct coresight_ops_link *link_ops; const struct coresight_ops_source *source_ops; const struct coresight_ops_helper *helper_ops; - const struct coresight_ops_ect *ect_ops; }; #if IS_ENABLED(CONFIG_CORESIGHT) @@ -602,5 +618,18 @@ static inline void coresight_write64(struct coresight_device *csdev, u64 val, u3 extern int coresight_get_cpu(struct device *dev); struct coresight_platform_data *coresight_get_platform_data(struct device *dev); +struct coresight_connection * +coresight_add_out_conn(struct device *dev, + struct coresight_platform_data *pdata, + const struct coresight_connection *new_conn); +int coresight_add_in_conn(struct coresight_connection *conn); +struct coresight_device * +coresight_find_input_type(struct coresight_platform_data *pdata, + enum coresight_dev_type type, + union coresight_dev_subtype subtype); +struct coresight_device * +coresight_find_output_type(struct coresight_platform_data *pdata, + enum coresight_dev_type type, + union coresight_dev_subtype subtype); #endif /* _LINUX_COREISGHT_H */ diff --git a/include/linux/cper.h b/include/linux/cper.h index eacb7dd7b3af..c1a7dc325121 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -572,4 +572,10 @@ void cper_print_proc_ia(const char *pfx, int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg); int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg); +struct acpi_hest_generic_status; +void cper_estatus_print(const char *pfx, + const struct acpi_hest_generic_status *estatus); +int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus); +int cper_estatus_check(const struct acpi_hest_generic_status *estatus); + #endif diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 8582a7142623..6e6e57ec69e8 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -184,8 +184,12 @@ void arch_cpu_idle_enter(void); void arch_cpu_idle_exit(void); void __noreturn arch_cpu_idle_dead(void); -int cpu_report_state(int cpu); -int cpu_check_up_prepare(int cpu); +#ifdef CONFIG_ARCH_HAS_CPU_FINALIZE_INIT +void arch_cpu_finalize_init(void); +#else +static inline void arch_cpu_finalize_init(void) { } +#endif + void cpu_set_state_online(int cpu); void play_idle_precise(u64 duration_ns, u64 latency_ns); @@ -195,8 +199,6 @@ static inline void play_idle(unsigned long duration_us) } #ifdef CONFIG_HOTPLUG_CPU -bool cpu_wait_death(unsigned int cpu, int seconds); -bool cpu_report_death(void); void cpuhp_report_idle_dead(void); #else static inline void cpuhp_report_idle_dead(void) { } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 26e2eb399484..172ff51c1b2a 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -340,7 +340,10 @@ struct cpufreq_driver { /* * ->fast_switch() replacement for drivers that use an internal * representation of performance levels and can pass hints other than - * the target performance level to the hardware. + * the target performance level to the hardware. This can only be set + * if ->fast_switch is set too, because in those cases (under specific + * conditions) scale invariance can be disabled, which causes the + * schedutil governor to fall back to the latter. */ void (*adjust_perf)(unsigned int cpu, unsigned long min_perf, diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 0f1001dca0e0..25b6e6e6ba6b 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -133,6 +133,7 @@ enum cpuhp_state { CPUHP_MIPS_SOC_PREPARE, CPUHP_BP_PREPARE_DYN, CPUHP_BP_PREPARE_DYN_END = CPUHP_BP_PREPARE_DYN + 20, + CPUHP_BP_KICK_AP, CPUHP_BRINGUP_CPU, /* @@ -200,6 +201,7 @@ enum cpuhp_state { /* Online section invoked on the hotplugged CPU from the hotplug thread */ CPUHP_AP_ONLINE_IDLE, + CPUHP_AP_HYPERV_ONLINE, CPUHP_AP_KVM_ONLINE, CPUHP_AP_SCHED_WAIT_EMPTY, CPUHP_AP_SMPBOOT_THREADS, @@ -517,4 +519,20 @@ void cpuhp_online_idle(enum cpuhp_state state); static inline void cpuhp_online_idle(enum cpuhp_state state) { } #endif +struct task_struct; + +void cpuhp_ap_sync_alive(void); +void arch_cpuhp_sync_state_poll(void); +void arch_cpuhp_cleanup_kick_cpu(unsigned int cpu); +int arch_cpuhp_kick_ap_alive(unsigned int cpu, struct task_struct *tidle); +bool arch_cpuhp_init_parallel_bringup(void); + +#ifdef CONFIG_HOTPLUG_CORE_SYNC_DEAD +void cpuhp_ap_report_dead(void); +void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu); +#else +static inline void cpuhp_ap_report_dead(void) { } +static inline void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu) { } +#endif + #endif diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index ca736b05ec7b..0d2e2a38b92d 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -1071,7 +1071,7 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu) */ static __always_inline unsigned int num_online_cpus(void) { - return arch_atomic_read(&__num_online_cpus); + return raw_atomic_read(&__num_online_cpus); } #define num_possible_cpus() cpumask_weight(cpu_possible_mask) #define num_present_cpus() cpumask_weight(cpu_present_mask) diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 980b76a1237e..d629094fac6e 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -71,8 +71,10 @@ extern void cpuset_init_smp(void); extern void cpuset_force_rebuild(void); extern void cpuset_update_active_cpus(void); extern void cpuset_wait_for_hotplug(void); -extern void cpuset_read_lock(void); -extern void cpuset_read_unlock(void); +extern void inc_dl_tasks_cs(struct task_struct *task); +extern void dec_dl_tasks_cs(struct task_struct *task); +extern void cpuset_lock(void); +extern void cpuset_unlock(void); extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); extern bool cpuset_cpus_allowed_fallback(struct task_struct *p); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); @@ -189,8 +191,10 @@ static inline void cpuset_update_active_cpus(void) static inline void cpuset_wait_for_hotplug(void) { } -static inline void cpuset_read_lock(void) { } -static inline void cpuset_read_unlock(void) { } +static inline void inc_dl_tasks_cs(struct task_struct *task) { } +static inline void dec_dl_tasks_cs(struct task_struct *task) { } +static inline void cpuset_lock(void) { } +static inline void cpuset_unlock(void) { } static inline void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index fa310ac1db59..31f6fee0c36c 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -25,11 +25,12 @@ #define CRYPTO_ALG_TYPE_COMPRESS 0x00000002 #define CRYPTO_ALG_TYPE_AEAD 0x00000003 #define CRYPTO_ALG_TYPE_SKCIPHER 0x00000005 +#define CRYPTO_ALG_TYPE_AKCIPHER 0x00000006 +#define CRYPTO_ALG_TYPE_SIG 0x00000007 #define CRYPTO_ALG_TYPE_KPP 0x00000008 #define CRYPTO_ALG_TYPE_ACOMPRESS 0x0000000a #define CRYPTO_ALG_TYPE_SCOMPRESS 0x0000000b #define CRYPTO_ALG_TYPE_RNG 0x0000000c -#define CRYPTO_ALG_TYPE_AKCIPHER 0x0000000d #define CRYPTO_ALG_TYPE_HASH 0x0000000e #define CRYPTO_ALG_TYPE_SHASH 0x0000000e #define CRYPTO_ALG_TYPE_AHASH 0x0000000f diff --git a/include/linux/dax.h b/include/linux/dax.h index bf6258472e49..261944ec0887 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -261,6 +261,19 @@ static inline bool dax_mapping(struct address_space *mapping) return mapping->host && IS_DAX(mapping->host); } +/* + * Due to dax's memory and block duo personalities, hwpoison reporting + * takes into consideration which personality is presently visible. + * When dax acts like a block device, such as in block IO, an encounter of + * dax hwpoison is reported as -EIO. + * When dax acts like memory, such as in page fault, a detection of hwpoison + * is reported as -EHWPOISON which leads to VM_FAULT_HWPOISON. + */ +static inline int dax_mem2blk_err(int err) +{ + return (err == -EHWPOISON) ? -EIO : err; +} + #ifdef CONFIG_DEV_DAX_HMEM_DEVICES void hmem_register_resource(int target_nid, struct resource *r); #else diff --git a/include/linux/delay.h b/include/linux/delay.h index 039e7e0c7378..ff9cda975e30 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -56,6 +56,7 @@ static inline void ndelay(unsigned long x) extern unsigned long lpj_fine; void calibrate_delay(void); +unsigned long calibrate_delay_is_known(void); void __attribute__((weak)) calibration_delay_done(void); void msleep(unsigned int msecs); unsigned long msleep_interruptible(unsigned int msecs); diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7fd704bb8f3d..d312ffbac4dd 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -108,7 +108,6 @@ struct devfreq_dev_profile { unsigned long initial_freq; unsigned int polling_ms; enum devfreq_timer timer; - bool is_cooling_device; int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, @@ -118,6 +117,8 @@ struct devfreq_dev_profile { unsigned long *freq_table; unsigned int max_state; + + bool is_cooling_device; }; /** diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index a52d2b9a6846..69d0435c7ebb 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -166,17 +166,15 @@ void dm_error(const char *message); struct dm_dev { struct block_device *bdev; struct dax_device *dax_dev; - fmode_t mode; + blk_mode_t mode; char name[16]; }; -dev_t dm_get_dev_t(const char *path); - /* * Constructors should call these functions to ensure destination devices * are opened/closed correctly. */ -int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, +int dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode, struct dm_dev **result); void dm_put_device(struct dm_target *ti, struct dm_dev *d); @@ -545,7 +543,7 @@ int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); /* * First create an empty table. */ -int dm_table_create(struct dm_table **result, fmode_t mode, +int dm_table_create(struct dm_table **result, blk_mode_t mode, unsigned int num_targets, struct mapped_device *md); /* @@ -588,7 +586,7 @@ void dm_sync_table(struct mapped_device *md); * Queries */ sector_t dm_table_get_size(struct dm_table *t); -fmode_t dm_table_get_mode(struct dm_table *t); +blk_mode_t dm_table_get_mode(struct dm_table *t); struct mapped_device *dm_table_get_md(struct dm_table *t); const char *dm_table_device_name(struct dm_table *t); diff --git a/include/linux/device.h b/include/linux/device.h index 472dd24d4823..bbaeabd04b0d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -30,6 +30,7 @@ #include <linux/device/bus.h> #include <linux/device/class.h> #include <linux/device/driver.h> +#include <linux/cleanup.h> #include <asm/device.h> struct device; @@ -96,7 +97,12 @@ struct device_type { const struct dev_pm_ops *pm; }; -/* interface for exporting device attributes */ +/** + * struct device_attribute - Interface for exporting device attributes. + * @attr: sysfs attribute definition. + * @show: Show handler. + * @store: Store handler. + */ struct device_attribute { struct attribute attr; ssize_t (*show)(struct device *dev, struct device_attribute *attr, @@ -105,6 +111,11 @@ struct device_attribute { const char *buf, size_t count); }; +/** + * struct dev_ext_attribute - Exported device attribute with extra context. + * @attr: Exported device attribute. + * @var: Pointer to context. + */ struct dev_ext_attribute { struct device_attribute attr; void *var; @@ -123,30 +134,124 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +/** + * DEVICE_ATTR - Define a device attribute. + * @_name: Attribute name. + * @_mode: File mode. + * @_show: Show handler. Optional, but mandatory if attribute is readable. + * @_store: Store handler. Optional, but mandatory if attribute is writable. + * + * Convenience macro for defining a struct device_attribute. + * + * For example, ``DEVICE_ATTR(foo, 0644, foo_show, foo_store);`` expands to: + * + * .. code-block:: c + * + * struct device_attribute dev_attr_foo = { + * .attr = { .name = "foo", .mode = 0644 }, + * .show = foo_show, + * .store = foo_store, + * }; + */ #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) + +/** + * DEVICE_ATTR_PREALLOC - Define a preallocated device attribute. + * @_name: Attribute name. + * @_mode: File mode. + * @_show: Show handler. Optional, but mandatory if attribute is readable. + * @_store: Store handler. Optional, but mandatory if attribute is writable. + * + * Like DEVICE_ATTR(), but ``SYSFS_PREALLOC`` is set on @_mode. + */ #define DEVICE_ATTR_PREALLOC(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = \ __ATTR_PREALLOC(_name, _mode, _show, _store) + +/** + * DEVICE_ATTR_RW - Define a read-write device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0644, @_show is <_name>_show, + * and @_store is <_name>_store. + */ #define DEVICE_ATTR_RW(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RW(_name) + +/** + * DEVICE_ATTR_ADMIN_RW - Define an admin-only read-write device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR_RW(), but @_mode is 0600. + */ #define DEVICE_ATTR_ADMIN_RW(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RW_MODE(_name, 0600) + +/** + * DEVICE_ATTR_RO - Define a readable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0444 and @_show is <_name>_show. + */ #define DEVICE_ATTR_RO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RO(_name) + +/** + * DEVICE_ATTR_ADMIN_RO - Define an admin-only readable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR_RO(), but @_mode is 0400. + */ #define DEVICE_ATTR_ADMIN_RO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_RO_MODE(_name, 0400) + +/** + * DEVICE_ATTR_WO - Define an admin-only writable device attribute. + * @_name: Attribute name. + * + * Like DEVICE_ATTR(), but @_mode is 0200 and @_store is <_name>_store. + */ #define DEVICE_ATTR_WO(_name) \ struct device_attribute dev_attr_##_name = __ATTR_WO(_name) + +/** + * DEVICE_ULONG_ATTR - Define a device attribute backed by an unsigned long. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of unsigned long. + * + * Like DEVICE_ATTR(), but @_show and @_store are automatically provided + * such that reads and writes to the attribute from userspace affect @_var. + */ #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } + +/** + * DEVICE_INT_ATTR - Define a device attribute backed by an int. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of int. + * + * Like DEVICE_ULONG_ATTR(), but @_var is an int. + */ #define DEVICE_INT_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) } + +/** + * DEVICE_BOOL_ATTR - Define a device attribute backed by a bool. + * @_name: Attribute name. + * @_mode: File mode. + * @_var: Identifier of bool. + * + * Like DEVICE_ULONG_ATTR(), but @_var is a bool. + */ #define DEVICE_BOOL_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) } + #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = \ __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) @@ -223,6 +328,17 @@ static inline void *devm_kcalloc(struct device *dev, { return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO); } +static inline __realloc_size(3, 4) void * __must_check +devm_krealloc_array(struct device *dev, void *p, size_t new_n, size_t new_size, gfp_t flags) +{ + size_t bytes; + + if (unlikely(check_mul_overflow(new_n, new_size, &bytes))) + return NULL; + + return devm_krealloc(dev, p, bytes, flags); +} + void devm_kfree(struct device *dev, const void *p); char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc; const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp); @@ -700,6 +816,11 @@ static inline bool device_iommu_mapped(struct device *dev) /* Get the wakeup routines, which depend on struct device */ #include <linux/pm_wakeup.h> +/** + * dev_name - Return a device's name. + * @dev: Device with name to get. + * Return: The kobject name of the device, or its initial name if unavailable. + */ static inline const char *dev_name(const struct device *dev) { /* Use the init name until the kobject becomes available */ @@ -899,6 +1020,9 @@ void device_unregister(struct device *dev); void device_initialize(struct device *dev); int __must_check device_add(struct device *dev); void device_del(struct device *dev); + +DEFINE_FREE(device_del, struct device *, if (_T) device_del(_T)) + int device_for_each_child(struct device *dev, void *data, int (*fn)(struct device *dev, void *data)); int device_for_each_child_reverse(struct device *dev, void *data, @@ -1066,6 +1190,9 @@ extern int (*platform_notify_remove)(struct device *dev); */ struct device *get_device(struct device *dev); void put_device(struct device *dev); + +DEFINE_FREE(put_device, struct device *, if (_T) put_device(_T)) + bool kill_device(struct device *dev); #ifdef CONFIG_DEVTMPFS diff --git a/include/linux/device/class.h b/include/linux/device/class.h index 9deeaeb457bb..abf3d3bfb6fe 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -74,6 +74,7 @@ struct class { struct class_dev_iter { struct klist_iter ki; const struct device_type *type; + struct subsys_private *sp; }; int __must_check class_register(const struct class *class); diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index c244267a6744..7738f458995f 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -126,7 +126,7 @@ int __must_check driver_register(struct device_driver *drv); void driver_unregister(struct device_driver *drv); struct device_driver *driver_find(const char *name, const struct bus_type *bus); -int driver_probe_done(void); +bool __init driver_probe_done(void); void wait_for_device_probe(void); void __init wait_for_init_devices_probe(void); diff --git a/include/linux/dim.h b/include/linux/dim.h index 6c5733981563..f343bc9aa2ec 100644 --- a/include/linux/dim.h +++ b/include/linux/dim.h @@ -236,8 +236,9 @@ void dim_park_tired(struct dim *dim); * * Calculate the delta between two samples (in data rates). * Takes into consideration counter wrap-around. + * Returned boolean indicates whether curr_stats are reliable. */ -void dim_calc_stats(struct dim_sample *start, struct dim_sample *end, +bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end, struct dim_stats *curr_stats); /** diff --git a/include/linux/dm-bufio.h b/include/linux/dm-bufio.h index 681656a1c03d..75e7d8cbb532 100644 --- a/include/linux/dm-bufio.h +++ b/include/linux/dm-bufio.h @@ -38,6 +38,8 @@ dm_bufio_client_create(struct block_device *bdev, unsigned int block_size, */ void dm_bufio_client_destroy(struct dm_bufio_client *c); +void dm_bufio_client_reset(struct dm_bufio_client *c); + /* * Set the sector range. * When this function is called, there must be no I/O in progress on the bufio diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index 31f114f486c4..9bf19b5bf755 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -8,6 +8,7 @@ #include <linux/dma-mapping.h> #include <linux/pgtable.h> +#include <linux/slab.h> struct cma; @@ -277,6 +278,66 @@ static inline bool dev_is_dma_coherent(struct device *dev) } #endif /* CONFIG_ARCH_HAS_DMA_COHERENCE_H */ +/* + * Check whether potential kmalloc() buffers are safe for non-coherent DMA. + */ +static inline bool dma_kmalloc_safe(struct device *dev, + enum dma_data_direction dir) +{ + /* + * If DMA bouncing of kmalloc() buffers is disabled, the kmalloc() + * caches have already been aligned to a DMA-safe size. + */ + if (!IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC)) + return true; + + /* + * kmalloc() buffers are DMA-safe irrespective of size if the device + * is coherent or the direction is DMA_TO_DEVICE (non-desctructive + * cache maintenance and benign cache line evictions). + */ + if (dev_is_dma_coherent(dev) || dir == DMA_TO_DEVICE) + return true; + + return false; +} + +/* + * Check whether the given size, assuming it is for a kmalloc()'ed buffer, is + * sufficiently aligned for non-coherent DMA. + */ +static inline bool dma_kmalloc_size_aligned(size_t size) +{ + /* + * Larger kmalloc() sizes are guaranteed to be aligned to + * ARCH_DMA_MINALIGN. + */ + if (size >= 2 * ARCH_DMA_MINALIGN || + IS_ALIGNED(kmalloc_size_roundup(size), dma_get_cache_alignment())) + return true; + + return false; +} + +/* + * Check whether the given object size may have originated from a kmalloc() + * buffer with a slab alignment below the DMA-safe alignment and needs + * bouncing for non-coherent DMA. The pointer alignment is not considered and + * in-structure DMA-safe offsets are the responsibility of the caller. Such + * code should use the static ARCH_DMA_MINALIGN for compiler annotations. + * + * The heuristics can have false positives, bouncing unnecessarily, though the + * buffers would be small. False negatives are theoretically possible if, for + * example, multiple small kmalloc() buffers are coalesced into a larger + * buffer that passes the alignment check. There are no such known constructs + * in the kernel. + */ +static inline bool dma_kmalloc_needs_bounce(struct device *dev, size_t size, + enum dma_data_direction dir) +{ + return !dma_kmalloc_safe(dev, dir) && !dma_kmalloc_size_aligned(size); +} + void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs); void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 0ee20b764000..e13050eb9777 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -2,6 +2,7 @@ #ifndef _LINUX_DMA_MAPPING_H #define _LINUX_DMA_MAPPING_H +#include <linux/cache.h> #include <linux/sizes.h> #include <linux/string.h> #include <linux/device.h> @@ -543,13 +544,15 @@ static inline int dma_set_min_align_mask(struct device *dev, return 0; } +#ifndef dma_get_cache_alignment static inline int dma_get_cache_alignment(void) { -#ifdef ARCH_DMA_MINALIGN +#ifdef ARCH_HAS_DMA_MINALIGN return ARCH_DMA_MINALIGN; #endif return 1; } +#endif static inline void *dmam_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 725d5e6acec0..27dbd4c64860 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -202,67 +202,74 @@ static inline void detect_intel_iommu(void) struct irte { union { - /* Shared between remapped and posted mode*/ struct { - __u64 present : 1, /* 0 */ - fpd : 1, /* 1 */ - __res0 : 6, /* 2 - 6 */ - avail : 4, /* 8 - 11 */ - __res1 : 3, /* 12 - 14 */ - pst : 1, /* 15 */ - vector : 8, /* 16 - 23 */ - __res2 : 40; /* 24 - 63 */ + union { + /* Shared between remapped and posted mode*/ + struct { + __u64 present : 1, /* 0 */ + fpd : 1, /* 1 */ + __res0 : 6, /* 2 - 6 */ + avail : 4, /* 8 - 11 */ + __res1 : 3, /* 12 - 14 */ + pst : 1, /* 15 */ + vector : 8, /* 16 - 23 */ + __res2 : 40; /* 24 - 63 */ + }; + + /* Remapped mode */ + struct { + __u64 r_present : 1, /* 0 */ + r_fpd : 1, /* 1 */ + dst_mode : 1, /* 2 */ + redir_hint : 1, /* 3 */ + trigger_mode : 1, /* 4 */ + dlvry_mode : 3, /* 5 - 7 */ + r_avail : 4, /* 8 - 11 */ + r_res0 : 4, /* 12 - 15 */ + r_vector : 8, /* 16 - 23 */ + r_res1 : 8, /* 24 - 31 */ + dest_id : 32; /* 32 - 63 */ + }; + + /* Posted mode */ + struct { + __u64 p_present : 1, /* 0 */ + p_fpd : 1, /* 1 */ + p_res0 : 6, /* 2 - 7 */ + p_avail : 4, /* 8 - 11 */ + p_res1 : 2, /* 12 - 13 */ + p_urgent : 1, /* 14 */ + p_pst : 1, /* 15 */ + p_vector : 8, /* 16 - 23 */ + p_res2 : 14, /* 24 - 37 */ + pda_l : 26; /* 38 - 63 */ + }; + __u64 low; + }; + + union { + /* Shared between remapped and posted mode*/ + struct { + __u64 sid : 16, /* 64 - 79 */ + sq : 2, /* 80 - 81 */ + svt : 2, /* 82 - 83 */ + __res3 : 44; /* 84 - 127 */ + }; + + /* Posted mode*/ + struct { + __u64 p_sid : 16, /* 64 - 79 */ + p_sq : 2, /* 80 - 81 */ + p_svt : 2, /* 82 - 83 */ + p_res3 : 12, /* 84 - 95 */ + pda_h : 32; /* 96 - 127 */ + }; + __u64 high; + }; }; - - /* Remapped mode */ - struct { - __u64 r_present : 1, /* 0 */ - r_fpd : 1, /* 1 */ - dst_mode : 1, /* 2 */ - redir_hint : 1, /* 3 */ - trigger_mode : 1, /* 4 */ - dlvry_mode : 3, /* 5 - 7 */ - r_avail : 4, /* 8 - 11 */ - r_res0 : 4, /* 12 - 15 */ - r_vector : 8, /* 16 - 23 */ - r_res1 : 8, /* 24 - 31 */ - dest_id : 32; /* 32 - 63 */ - }; - - /* Posted mode */ - struct { - __u64 p_present : 1, /* 0 */ - p_fpd : 1, /* 1 */ - p_res0 : 6, /* 2 - 7 */ - p_avail : 4, /* 8 - 11 */ - p_res1 : 2, /* 12 - 13 */ - p_urgent : 1, /* 14 */ - p_pst : 1, /* 15 */ - p_vector : 8, /* 16 - 23 */ - p_res2 : 14, /* 24 - 37 */ - pda_l : 26; /* 38 - 63 */ - }; - __u64 low; - }; - - union { - /* Shared between remapped and posted mode*/ - struct { - __u64 sid : 16, /* 64 - 79 */ - sq : 2, /* 80 - 81 */ - svt : 2, /* 82 - 83 */ - __res3 : 44; /* 84 - 127 */ - }; - - /* Posted mode*/ - struct { - __u64 p_sid : 16, /* 64 - 79 */ - p_sq : 2, /* 80 - 81 */ - p_svt : 2, /* 82 - 83 */ - p_res3 : 12, /* 84 - 95 */ - pda_h : 32; /* 96 - 127 */ - }; - __u64 high; +#ifdef CONFIG_IRQ_REMAP + __u128 irte; +#endif }; }; diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h index 159e43171ccc..c177322f793d 100644 --- a/include/linux/dsa/sja1105.h +++ b/include/linux/dsa/sja1105.h @@ -48,13 +48,9 @@ struct sja1105_deferred_xmit_work { /* Global tagger data */ struct sja1105_tagger_data { - /* Tagger to switch */ void (*xmit_work_fn)(struct kthread_work *work); void (*meta_tstamp_handler)(struct dsa_switch *ds, int port, u8 ts_id, enum sja1110_meta_tstamp dir, u64 tstamp); - /* Switch to tagger */ - bool (*rxtstamp_get_state)(struct dsa_switch *ds); - void (*rxtstamp_set_state)(struct dsa_switch *ds, bool on); }; struct sja1105_skb_cb { diff --git a/include/linux/efi.h b/include/linux/efi.h index 7aa62c92185f..ab088c662e88 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -108,7 +108,8 @@ typedef struct { #define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12 #define EFI_PAL_CODE 13 #define EFI_PERSISTENT_MEMORY 14 -#define EFI_MAX_MEMORY_TYPE 15 +#define EFI_UNACCEPTED_MEMORY 15 +#define EFI_MAX_MEMORY_TYPE 16 /* Attribute values: */ #define EFI_MEMORY_UC ((u64)0x0000000000000001ULL) /* uncached */ @@ -417,6 +418,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) #define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) +#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) @@ -435,6 +437,9 @@ void efi_native_runtime_setup(void); #define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55) #define AMD_SEV_MEM_ENCRYPT_GUID EFI_GUID(0x0cf29b71, 0x9e51, 0x433a, 0xa3, 0xb7, 0x81, 0xf3, 0xab, 0x16, 0xb8, 0x75) +/* OVMF protocol GUIDs */ +#define OVMF_SEV_MEMORY_ACCEPTANCE_PROTOCOL_GUID EFI_GUID(0xc5a010fe, 0x38a7, 0x4531, 0x8a, 0x4a, 0x05, 0x00, 0xd2, 0xfd, 0x16, 0x49) + typedef struct { efi_guid_t guid; u64 table; @@ -534,6 +539,14 @@ struct efi_boot_memmap { efi_memory_desc_t map[]; }; +struct efi_unaccepted_memory { + u32 version; + u32 unit_size; + u64 phys_base; + u64 size; + unsigned long bitmap[]; +}; + /* * Architecture independent structure for describing a memory map for the * benefit of efi_memmap_init_early(), and for passing context between @@ -636,6 +649,7 @@ extern struct efi { unsigned long tpm_final_log; /* TPM2 Final Events Log table */ unsigned long mokvar_table; /* MOK variable config table */ unsigned long coco_secret; /* Confidential computing secret table */ + unsigned long unaccepted; /* Unaccepted memory table */ efi_get_time_t *get_time; efi_set_time_t *set_time; @@ -1042,6 +1056,7 @@ struct efivar_operations { efi_set_variable_t *set_variable; efi_set_variable_t *set_variable_nonblocking; efi_query_variable_store_t *query_variable_store; + efi_query_variable_info_t *query_variable_info; }; struct efivars { @@ -1049,6 +1064,12 @@ struct efivars { const struct efivar_operations *ops; }; +#ifdef CONFIG_X86 +u64 __attribute_const__ efivar_reserved_space(void); +#else +static inline u64 efivar_reserved_space(void) { return 0; } +#endif + /* * The maximum size of VariableName + Data = 1024 * Therefore, it's reasonable to save that much @@ -1087,6 +1108,10 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor, efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data); +efi_status_t efivar_query_variable_info(u32 attr, u64 *storage_space, + u64 *remaining_space, + u64 *max_variable_size); + #if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER) extern bool efi_capsule_pending(int *reset_type); @@ -1338,4 +1363,6 @@ bool efi_config_table_is_usable(const efi_guid_t *guid, unsigned long table) return xen_efi_config_table_is_usable(guid, table); } +umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n); + #endif /* _LINUX_EFI_H */ diff --git a/include/linux/err.h b/include/linux/err.h index a139c64aef2a..b5d9bb2a2349 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -19,23 +19,54 @@ #ifndef __ASSEMBLY__ +/** + * IS_ERR_VALUE - Detect an error pointer. + * @x: The pointer to check. + * + * Like IS_ERR(), but does not generate a compiler warning if result is unused. + */ #define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO) +/** + * ERR_PTR - Create an error pointer. + * @error: A negative error code. + * + * Encodes @error into a pointer value. Users should consider the result + * opaque and not assume anything about how the error is encoded. + * + * Return: A pointer with @error encoded within its value. + */ static inline void * __must_check ERR_PTR(long error) { return (void *) error; } +/** + * PTR_ERR - Extract the error code from an error pointer. + * @ptr: An error pointer. + * Return: The error code within @ptr. + */ static inline long __must_check PTR_ERR(__force const void *ptr) { return (long) ptr; } +/** + * IS_ERR - Detect an error pointer. + * @ptr: The pointer to check. + * Return: true if @ptr is an error pointer, false otherwise. + */ static inline bool __must_check IS_ERR(__force const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } +/** + * IS_ERR_OR_NULL - Detect an error pointer or a null pointer. + * @ptr: The pointer to check. + * + * Like IS_ERR(), but also returns true for a null pointer. + */ static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) { return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); @@ -54,6 +85,23 @@ static inline void * __must_check ERR_CAST(__force const void *ptr) return (void *) ptr; } +/** + * PTR_ERR_OR_ZERO - Extract the error code from a pointer if it has one. + * @ptr: A potential error pointer. + * + * Convenience function that can be used inside a function that returns + * an error code to propagate errors received as error pointers. + * For example, ``return PTR_ERR_OR_ZERO(ptr);`` replaces: + * + * .. code-block:: c + * + * if (IS_ERR(ptr)) + * return PTR_ERR(ptr); + * else + * return 0; + * + * Return: The error code within @ptr if it is an error pointer; 0 otherwise. + */ static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) { if (IS_ERR(ptr)) diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index 36a486505b08..b9d83652c097 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -9,12 +9,12 @@ #ifndef _LINUX_EVENTFD_H #define _LINUX_EVENTFD_H -#include <linux/fcntl.h> #include <linux/wait.h> #include <linux/err.h> #include <linux/percpu-defs.h> #include <linux/percpu.h> #include <linux/sched.h> +#include <uapi/linux/eventfd.h> /* * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining @@ -23,10 +23,6 @@ * from eventfd, in order to leave a free define-space for * shared O_* flags. */ -#define EFD_SEMAPHORE (1 << 0) -#define EFD_CLOEXEC O_CLOEXEC -#define EFD_NONBLOCK O_NONBLOCK - #define EFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK) #define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE) @@ -40,7 +36,7 @@ struct file *eventfd_fget(int fd); struct eventfd_ctx *eventfd_ctx_fdget(int fd); struct eventfd_ctx *eventfd_ctx_fileget(struct file *file); __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n); -__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask); +__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, __poll_t mask); int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait, __u64 *cnt); void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt); diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h index fe7e6ba918f1..1c849db953a5 100644 --- a/include/linux/export-internal.h +++ b/include/linux/export-internal.h @@ -10,6 +10,55 @@ #include <linux/compiler.h> #include <linux/types.h> +#if defined(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS) +/* + * relative reference: this reduces the size by half on 64-bit architectures, + * and eliminates the need for absolute relocations that require runtime + * processing on relocatable kernels. + */ +#define __KSYM_REF(sym) ".long " #sym "- ." +#elif defined(CONFIG_64BIT) +#define __KSYM_REF(sym) ".quad " #sym +#else +#define __KSYM_REF(sym) ".long " #sym +#endif + +/* + * For every exported symbol, do the following: + * + * - Put the name of the symbol and namespace (empty string "" for none) in + * __ksymtab_strings. + * - Place a struct kernel_symbol entry in the __ksymtab section. + * + * Note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) + * section flag requires it. Use '%progbits' instead of '@progbits' since the + * former apparently works on all arches according to the binutils source. + */ +#define __KSYMTAB(name, sym, sec, ns) \ + asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1" "\n" \ + "__kstrtab_" #name ":" "\n" \ + " .asciz \"" #name "\"" "\n" \ + "__kstrtabns_" #name ":" "\n" \ + " .asciz \"" ns "\"" "\n" \ + " .previous" "\n" \ + " .section \"___ksymtab" sec "+" #name "\", \"a\"" "\n" \ + " .balign 4" "\n" \ + "__ksymtab_" #name ":" "\n" \ + __KSYM_REF(sym) "\n" \ + __KSYM_REF(__kstrtab_ ##name) "\n" \ + __KSYM_REF(__kstrtabns_ ##name) "\n" \ + " .previous" "\n" \ + ) + +#ifdef CONFIG_IA64 +#define KSYM_FUNC(name) @fptr(name) +#else +#define KSYM_FUNC(name) name +#endif + +#define KSYMTAB_FUNC(name, sec, ns) __KSYMTAB(name, KSYM_FUNC(name), sec, ns) +#define KSYMTAB_DATA(name, sec, ns) __KSYMTAB(name, name, sec, ns) + #define SYMBOL_CRC(sym, crc, sec) \ asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \ "__crc_" #sym ":" "\n" \ diff --git a/include/linux/export.h b/include/linux/export.h index 3f31ced0d977..beed8387e0a4 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -2,6 +2,8 @@ #ifndef _LINUX_EXPORT_H #define _LINUX_EXPORT_H +#include <linux/compiler.h> +#include <linux/linkage.h> #include <linux/stringify.h> /* @@ -28,74 +30,25 @@ extern struct module __this_module; #else #define THIS_MODULE ((struct module *)0) #endif +#endif /* __ASSEMBLY__ */ -#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#include <linux/compiler.h> -/* - * Emit the ksymtab entry as a pair of relative references: this reduces - * the size by half on 64-bit architectures, and eliminates the need for - * absolute relocations that require runtime processing on relocatable - * kernels. - */ -#define __KSYMTAB_ENTRY(sym, sec) \ - __ADDRESSABLE(sym) \ - asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ - " .balign 4 \n" \ - "__ksymtab_" #sym ": \n" \ - " .long " #sym "- . \n" \ - " .long __kstrtab_" #sym "- . \n" \ - " .long __kstrtabns_" #sym "- . \n" \ - " .previous \n") - -struct kernel_symbol { - int value_offset; - int name_offset; - int namespace_offset; -}; +#ifdef CONFIG_64BIT +#define __EXPORT_SYMBOL_REF(sym) \ + .balign 8 ASM_NL \ + .quad sym #else -#define __KSYMTAB_ENTRY(sym, sec) \ - static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("___ksymtab" sec "+" #sym), used)) \ - __aligned(sizeof(void *)) \ - = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym } - -struct kernel_symbol { - unsigned long value; - const char *name; - const char *namespace; -}; +#define __EXPORT_SYMBOL_REF(sym) \ + .balign 4 ASM_NL \ + .long sym #endif -#ifdef __GENKSYMS__ - -#define ___EXPORT_SYMBOL(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym) - -#else - -/* - * For every exported symbol, do the following: - * - * - Put the name of the symbol and namespace (empty string "" for none) in - * __ksymtab_strings. - * - Place a struct kernel_symbol entry in the __ksymtab section. - * - * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) - * section flag requires it. Use '%progbits' instead of '@progbits' since the - * former apparently works on all arches according to the binutils source. - */ -#define ___EXPORT_SYMBOL(sym, sec, ns) \ - extern typeof(sym) sym; \ - extern const char __kstrtab_##sym[]; \ - extern const char __kstrtabns_##sym[]; \ - asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ - "__kstrtab_" #sym ": \n" \ - " .asciz \"" #sym "\" \n" \ - "__kstrtabns_" #sym ": \n" \ - " .asciz \"" ns "\" \n" \ - " .previous \n"); \ - __KSYMTAB_ENTRY(sym, sec) - -#endif +#define ___EXPORT_SYMBOL(sym, license, ns) \ + .section ".export_symbol","a" ASM_NL \ + __export_symbol_##sym: ASM_NL \ + .asciz license ASM_NL \ + .asciz ns ASM_NL \ + __EXPORT_SYMBOL_REF(sym) ASM_NL \ + .previous #if !defined(CONFIG_MODULES) || defined(__DISABLE_EXPORTS) @@ -104,54 +57,35 @@ struct kernel_symbol { * be reused in other execution contexts such as the UEFI stub or the * decompressor. */ -#define __EXPORT_SYMBOL(sym, sec, ns) +#define __EXPORT_SYMBOL(sym, license, ns) -#elif defined(CONFIG_TRIM_UNUSED_KSYMS) +#elif defined(__GENKSYMS__) -#include <generated/autoksyms.h> +#define __EXPORT_SYMBOL(sym, license, ns) __GENKSYMS_EXPORT_SYMBOL(sym) -/* - * For fine grained build dependencies, we want to tell the build system - * about each possible exported symbol even if they're not actually exported. - * We use a symbol pattern __ksym_marker_<symbol> that the build system filters - * from the $(NM) output (see scripts/gen_ksymdeps.sh). These symbols are - * discarded in the final link stage. - */ -#define __ksym_marker(sym) \ - static int __ksym_marker_##sym[0] __section(".discard.ksym") __used - -#define __EXPORT_SYMBOL(sym, sec, ns) \ - __ksym_marker(sym); \ - __cond_export_sym(sym, sec, ns, __is_defined(__KSYM_##sym)) -#define __cond_export_sym(sym, sec, ns, conf) \ - ___cond_export_sym(sym, sec, ns, conf) -#define ___cond_export_sym(sym, sec, ns, enabled) \ - __cond_export_sym_##enabled(sym, sec, ns) -#define __cond_export_sym_1(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns) - -#ifdef __GENKSYMS__ -#define __cond_export_sym_0(sym, sec, ns) __GENKSYMS_EXPORT_SYMBOL(sym) -#else -#define __cond_export_sym_0(sym, sec, ns) /* nothing */ -#endif +#elif defined(__ASSEMBLY__) + +#define __EXPORT_SYMBOL(sym, license, ns) \ + ___EXPORT_SYMBOL(sym, license, ns) #else -#define __EXPORT_SYMBOL(sym, sec, ns) ___EXPORT_SYMBOL(sym, sec, ns) +#define __EXPORT_SYMBOL(sym, license, ns) \ + extern typeof(sym) sym; \ + __ADDRESSABLE(sym) \ + asm(__stringify(___EXPORT_SYMBOL(sym, license, ns))) #endif /* CONFIG_MODULES */ #ifdef DEFAULT_SYMBOL_NAMESPACE -#define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, __stringify(DEFAULT_SYMBOL_NAMESPACE)) +#define _EXPORT_SYMBOL(sym, license) __EXPORT_SYMBOL(sym, license, __stringify(DEFAULT_SYMBOL_NAMESPACE)) #else -#define _EXPORT_SYMBOL(sym, sec) __EXPORT_SYMBOL(sym, sec, "") +#define _EXPORT_SYMBOL(sym, license) __EXPORT_SYMBOL(sym, license, "") #endif #define EXPORT_SYMBOL(sym) _EXPORT_SYMBOL(sym, "") -#define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "_gpl") +#define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") #define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL(sym, "", __stringify(ns)) -#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "_gpl", __stringify(ns)) - -#endif /* !__ASSEMBLY__ */ +#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL(sym, "GPL", __stringify(ns)) #endif /* _LINUX_EXPORT_H */ diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 9edb29101ec8..11fbd0ee1370 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -135,6 +135,9 @@ struct fid { }; }; +#define EXPORT_FH_CONNECTABLE 0x1 /* Encode file handle with parent */ +#define EXPORT_FH_FID 0x2 /* File handle may be non-decodeable */ + /** * struct export_operations - for nfsd to communicate with file systems * @encode_fh: encode a file handle fragment from a dentry @@ -150,7 +153,7 @@ struct fid { * encode_fh: * @encode_fh should store in the file handle fragment @fh (using at most * @max_len bytes) information that can be used by @decode_fh to recover the - * file referred to by the &struct dentry @de. If the @connectable flag is + * file referred to by the &struct dentry @de. If @flag has CONNECTABLE bit * set, the encode_fh() should store sufficient information so that a good * attempt can be made to find not only the file but also it's place in the * filesystem. This typically means storing a reference to de->d_parent in @@ -225,9 +228,18 @@ struct export_operations { }; extern int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid, - int *max_len, struct inode *parent); + int *max_len, struct inode *parent, + int flags); extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, - int *max_len, int connectable); + int *max_len, int flags); + +static inline int exportfs_encode_fid(struct inode *inode, struct fid *fid, + int *max_len) +{ + return exportfs_encode_inode_fh(inode, fid, max_len, NULL, + EXPORT_FH_FID); +} + extern struct dentry *exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len, int fileid_type, diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 1d6402529d10..a82a4bb6ce68 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -103,6 +103,7 @@ enum f2fs_error { ERROR_INCONSISTENT_SIT, ERROR_CORRUPTED_VERITY_XATTR, ERROR_CORRUPTED_XATTR, + ERROR_INVALID_NODE_REFERENCE, ERROR_MAX, }; diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h index 481abf530b3c..6d5edef09d45 100644 --- a/include/linux/fault-inject.h +++ b/include/linux/fault-inject.h @@ -93,6 +93,15 @@ struct kmem_cache; bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order); +#ifdef CONFIG_FAIL_PAGE_ALLOC +bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order); +#else +static inline bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) +{ + return false; +} +#endif /* CONFIG_FAIL_PAGE_ALLOC */ + int should_failslab(struct kmem_cache *s, gfp_t gfpflags); #ifdef CONFIG_FAILSLAB extern bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags); diff --git a/include/linux/fb.h b/include/linux/fb.h index 08cb47da71f8..ce7d588edc3e 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -15,7 +15,8 @@ #include <linux/list.h> #include <linux/backlight.h> #include <linux/slab.h> -#include <asm/io.h> + +#include <asm/fb.h> struct vm_area_struct; struct fb_info; @@ -511,58 +512,6 @@ struct fb_info { */ #define STUPID_ACCELF_TEXT_SHIT -// This will go away -#if defined(__sparc__) - -/* We map all of our framebuffers such that big-endian accesses - * are what we want, so the following is sufficient. - */ - -// This will go away -#define fb_readb sbus_readb -#define fb_readw sbus_readw -#define fb_readl sbus_readl -#define fb_readq sbus_readq -#define fb_writeb sbus_writeb -#define fb_writew sbus_writew -#define fb_writel sbus_writel -#define fb_writeq sbus_writeq -#define fb_memset sbus_memset_io -#define fb_memcpy_fromfb sbus_memcpy_fromio -#define fb_memcpy_tofb sbus_memcpy_toio - -#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || \ - defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || \ - defined(__arm__) || defined(__aarch64__) || defined(__mips__) - -#define fb_readb __raw_readb -#define fb_readw __raw_readw -#define fb_readl __raw_readl -#define fb_readq __raw_readq -#define fb_writeb __raw_writeb -#define fb_writew __raw_writew -#define fb_writel __raw_writel -#define fb_writeq __raw_writeq -#define fb_memset memset_io -#define fb_memcpy_fromfb memcpy_fromio -#define fb_memcpy_tofb memcpy_toio - -#else - -#define fb_readb(addr) (*(volatile u8 *) (addr)) -#define fb_readw(addr) (*(volatile u16 *) (addr)) -#define fb_readl(addr) (*(volatile u32 *) (addr)) -#define fb_readq(addr) (*(volatile u64 *) (addr)) -#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b)) -#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b)) -#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) -#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) -#define fb_memset memset -#define fb_memcpy_fromfb memcpy -#define fb_memcpy_tofb memcpy - -#endif - #define FB_LEFT_POS(p, bpp) (fb_be_math(p) ? (32 - (bpp)) : 0) #define FB_SHIFT_HIGH(p, val, bits) (fb_be_math(p) ? (val) >> (bits) : \ (val) << (bits)) @@ -576,12 +525,44 @@ struct fb_info { extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); extern int fb_blank(struct fb_info *info, int blank); + +/* + * Drawing operations where framebuffer is in I/O memory + */ + extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image); +extern ssize_t fb_io_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos); +extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos); + +/* + * Initializes struct fb_ops for framebuffers in I/O memory. + */ + +#define __FB_DEFAULT_IO_OPS_RDWR \ + .fb_read = fb_io_read, \ + .fb_write = fb_io_write + +#define __FB_DEFAULT_IO_OPS_DRAW \ + .fb_fillrect = cfb_fillrect, \ + .fb_copyarea = cfb_copyarea, \ + .fb_imageblit = cfb_imageblit + +#define __FB_DEFAULT_IO_OPS_MMAP \ + .fb_mmap = NULL /* default implementation */ + +#define FB_DEFAULT_IO_OPS \ + __FB_DEFAULT_IO_OPS_RDWR, \ + __FB_DEFAULT_IO_OPS_DRAW, \ + __FB_DEFAULT_IO_OPS_MMAP + /* * Drawing operations where framebuffer is in system RAM */ + extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area); extern void sys_imageblit(struct fb_info *info, const struct fb_image *image); @@ -590,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, char __user *buf, extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos); +/* + * Initializes struct fb_ops for framebuffers in system memory. + */ + +#define __FB_DEFAULT_SYS_OPS_RDWR \ + .fb_read = fb_sys_read, \ + .fb_write = fb_sys_write + +#define __FB_DEFAULT_SYS_OPS_DRAW \ + .fb_fillrect = sys_fillrect, \ + .fb_copyarea = sys_copyarea, \ + .fb_imageblit = sys_imageblit + +#define __FB_DEFAULT_SYS_OPS_MMAP \ + .fb_mmap = NULL /* default implementation */ + +#define FB_DEFAULT_SYS_OPS \ + __FB_DEFAULT_SYS_OPS_RDWR, \ + __FB_DEFAULT_SYS_OPS_DRAW, \ + __FB_DEFAULT_SYS_OPS_MMAP + /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern void unregister_framebuffer(struct fb_info *fb_info); @@ -645,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info *info); extern int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasync); +/* + * Generate callbacks for deferred I/O + */ + +#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, __mode) \ + static ssize_t __prefix ## _defio_read(struct fb_info *info, char __user *buf, \ + size_t count, loff_t *ppos) \ + { \ + return fb_ ## __mode ## _read(info, buf, count, ppos); \ + } \ + static ssize_t __prefix ## _defio_write(struct fb_info *info, const char __user *buf, \ + size_t count, loff_t *ppos) \ + { \ + unsigned long offset = *ppos; \ + ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \ + if (ret > 0) \ + __damage_range(info, offset, ret); \ + return ret; \ + } + +#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, __mode) \ + static void __prefix ## _defio_fillrect(struct fb_info *info, \ + const struct fb_fillrect *rect) \ + { \ + __mode ## _fillrect(info, rect); \ + __damage_area(info, rect->dx, rect->dy, rect->width, rect->height); \ + } \ + static void __prefix ## _defio_copyarea(struct fb_info *info, \ + const struct fb_copyarea *area) \ + { \ + __mode ## _copyarea(info, area); \ + __damage_area(info, area->dx, area->dy, area->width, area->height); \ + } \ + static void __prefix ## _defio_imageblit(struct fb_info *info, \ + const struct fb_image *image) \ + { \ + __mode ## _imageblit(info, image); \ + __damage_area(info, image->dx, image->dy, image->width, image->height); \ + } + +#define FB_GEN_DEFAULT_DEFERRED_IO_OPS(__prefix, __damage_range, __damage_area) \ + __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, io) \ + __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, cfb) + +#define FB_GEN_DEFAULT_DEFERRED_SYS_OPS(__prefix, __damage_range, __damage_area) \ + __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, sys) \ + __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, sys) + +/* + * Initializes struct fb_ops for deferred I/O. + */ + +#define __FB_DEFAULT_DEFERRED_OPS_RDWR(__prefix) \ + .fb_read = __prefix ## _defio_read, \ + .fb_write = __prefix ## _defio_write + +#define __FB_DEFAULT_DEFERRED_OPS_DRAW(__prefix) \ + .fb_fillrect = __prefix ## _defio_fillrect, \ + .fb_copyarea = __prefix ## _defio_copyarea, \ + .fb_imageblit = __prefix ## _defio_imageblit + +#define __FB_DEFAULT_DEFERRED_OPS_MMAP(__prefix) \ + .fb_mmap = fb_deferred_io_mmap + +#define FB_DEFAULT_DEFERRED_OPS(__prefix) \ + __FB_DEFAULT_DEFERRED_OPS_RDWR(__prefix), \ + __FB_DEFAULT_DEFERRED_OPS_DRAW(__prefix), \ + __FB_DEFAULT_DEFERRED_OPS_MMAP(__prefix) + static inline bool fb_be_math(struct fb_info *info) { #ifdef CONFIG_FB_FOREIGN_ENDIAN diff --git a/include/linux/file.h b/include/linux/file.h index 39704eae83e2..6e9099d29343 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -10,6 +10,7 @@ #include <linux/types.h> #include <linux/posix_types.h> #include <linux/errno.h> +#include <linux/cleanup.h> struct file; @@ -80,6 +81,8 @@ static inline void fdput_pos(struct fd f) fdput(f); } +DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd) + extern int f_dupfd(unsigned int from, struct file *file, unsigned flags); extern int replace_fd(unsigned fd, struct file *file, unsigned flags); extern void set_close_on_exec(unsigned int fd, int flag); @@ -88,6 +91,9 @@ extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile); extern int get_unused_fd_flags(unsigned flags); extern void put_unused_fd(unsigned int fd); +DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T), + get_unused_fd_flags(flags), unsigned flags) + extern void fd_install(unsigned int fd, struct file *file); extern int __receive_fd(struct file *file, int __user *ufd, diff --git a/include/linux/filter.h b/include/linux/filter.h index bbce89937fde..f69114083ec7 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -874,7 +874,6 @@ void bpf_prog_free(struct bpf_prog *fp); bool bpf_opcode_in_insntable(u8 code); -void bpf_prog_free_linfo(struct bpf_prog *prog); void bpf_prog_fill_jited_linfo(struct bpf_prog *prog, const u32 *insn_to_jit_off); int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 1716c01c4e54..bd3fc75d4f14 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -261,6 +261,15 @@ typedef void (*fw_packet_callback_t)(struct fw_packet *packet, typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode, void *data, size_t length, void *callback_data); +typedef void (*fw_transaction_callback_with_tstamp_t)(struct fw_card *card, int rcode, + u32 request_tstamp, u32 response_tstamp, void *data, + size_t length, void *callback_data); + +union fw_transaction_callback { + fw_transaction_callback_t without_tstamp; + fw_transaction_callback_with_tstamp_t with_tstamp; +}; + /* * This callback handles an inbound request subaction. It is called in * RCU read-side context, therefore must not sleep. @@ -312,6 +321,7 @@ struct fw_transaction { struct fw_card *card; bool is_split_transaction; struct timer_list split_timeout_timer; + u32 split_timeout_cycle; struct fw_packet packet; @@ -319,7 +329,8 @@ struct fw_transaction { * The data passed to the callback is valid only during the * callback. */ - fw_transaction_callback_t callback; + union fw_transaction_callback callback; + bool with_tstamp; void *callback_data; }; @@ -345,10 +356,71 @@ void fw_send_response(struct fw_card *card, struct fw_request *request, int rcode); int fw_get_request_speed(struct fw_request *request); u32 fw_request_get_timestamp(const struct fw_request *request); -void fw_send_request(struct fw_card *card, struct fw_transaction *t, - int tcode, int destination_id, int generation, int speed, - unsigned long long offset, void *payload, size_t length, - fw_transaction_callback_t callback, void *callback_data); + +void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, + int destination_id, int generation, int speed, unsigned long long offset, + void *payload, size_t length, union fw_transaction_callback callback, + bool with_tstamp, void *callback_data); + +/** + * fw_send_request() - submit a request packet for transmission to generate callback for response + * subaction without time stamp. + * @card: interface to send the request at + * @t: transaction instance to which the request belongs + * @tcode: transaction code + * @destination_id: destination node ID, consisting of bus_ID and phy_ID + * @generation: bus generation in which request and response are valid + * @speed: transmission speed + * @offset: 48bit wide offset into destination's address space + * @payload: data payload for the request subaction + * @length: length of the payload, in bytes + * @callback: function to be called when the transaction is completed + * @callback_data: data to be passed to the transaction completion callback + * + * A variation of __fw_send_request() to generate callback for response subaction without time + * stamp. + */ +static inline void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, + int destination_id, int generation, int speed, + unsigned long long offset, void *payload, size_t length, + fw_transaction_callback_t callback, void *callback_data) +{ + union fw_transaction_callback cb = { + .without_tstamp = callback, + }; + __fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload, + length, cb, false, callback_data); +} + +/** + * fw_send_request_with_tstamp() - submit a request packet for transmission to generate callback for + * response with time stamp. + * @card: interface to send the request at + * @t: transaction instance to which the request belongs + * @tcode: transaction code + * @destination_id: destination node ID, consisting of bus_ID and phy_ID + * @generation: bus generation in which request and response are valid + * @speed: transmission speed + * @offset: 48bit wide offset into destination's address space + * @payload: data payload for the request subaction + * @length: length of the payload, in bytes + * @callback: function to be called when the transaction is completed + * @callback_data: data to be passed to the transaction completion callback + * + * A variation of __fw_send_request() to generate callback for response subaction with time stamp. + */ +static inline void fw_send_request_with_tstamp(struct fw_card *card, struct fw_transaction *t, + int tcode, int destination_id, int generation, int speed, unsigned long long offset, + void *payload, size_t length, fw_transaction_callback_with_tstamp_t callback, + void *callback_data) +{ + union fw_transaction_callback cb = { + .with_tstamp = callback, + }; + __fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload, + length, cb, true, callback_data); +} + int fw_cancel_transaction(struct fw_card *card, struct fw_transaction *transaction); int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, @@ -391,7 +463,7 @@ struct fw_iso_packet { u32 tag:2; /* tx: Tag in packet header */ u32 sy:4; /* tx: Sy in packet header */ u32 header_length:8; /* Length of immediate header */ - u32 header[0]; /* tx: Top of 1394 isoch. data_block */ + u32 header[]; /* tx: Top of 1394 isoch. data_block */ }; #define FW_ISO_CONTEXT_TRANSMIT 0 diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index f5da51677069..9dda7d9898ff 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -4,7 +4,7 @@ * * Copyright (C) 2014-2021 Xilinx * - * Michal Simek <michal.simek@xilinx.com> + * Michal Simek <michal.simek@amd.com> * Davorin Mista <davorin.mista@aggios.com> * Jolly Shah <jollys@xilinx.com> * Rajan Vaja <rajanv@xilinx.com> diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index c9de1f59ee80..da51a83b2829 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -20,7 +20,7 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning(" ({ \ char *__p = (char *)(p); \ size_t __ret = SIZE_MAX; \ - size_t __p_size = __member_size(p); \ + const size_t __p_size = __member_size(p); \ if (__p_size != SIZE_MAX && \ __builtin_constant_p(*__p)) { \ size_t __p_len = __p_size - 1; \ @@ -142,7 +142,7 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3) char *strncpy(char * const POS p, const char *q, __kernel_size_t size) { - size_t p_size = __member_size(p); + const size_t p_size = __member_size(p); if (__compiletime_lessthan(p_size, size)) __write_overflow(); @@ -151,33 +151,6 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size) return __underlying_strncpy(p, q, size); } -/** - * strcat - Append a string to an existing string - * - * @p: pointer to NUL-terminated string to append to - * @q: pointer to NUL-terminated source string to append from - * - * Do not use this function. While FORTIFY_SOURCE tries to avoid - * read and write overflows, this is only possible when the - * destination buffer size is known to the compiler. Prefer - * building the string with formatting, via scnprintf() or similar. - * At the very least, use strncat(). - * - * Returns @p. - * - */ -__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2) -char *strcat(char * const POS p, const char *q) -{ - size_t p_size = __member_size(p); - - if (p_size == SIZE_MAX) - return __underlying_strcat(p, q); - if (strlcat(p, q, p_size) >= p_size) - fortify_panic(__func__); - return p; -} - extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen); /** * strnlen - Return bounded count of characters in a NUL-terminated string @@ -191,8 +164,8 @@ extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(st */ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen) { - size_t p_size = __member_size(p); - size_t p_len = __compiletime_strlen(p); + const size_t p_size = __member_size(p); + const size_t p_len = __compiletime_strlen(p); size_t ret; /* We can take compile-time actions when maxlen is const. */ @@ -233,8 +206,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) __kernel_size_t __fortify_strlen(const char * const POS p) { + const size_t p_size = __member_size(p); __kernel_size_t ret; - size_t p_size = __member_size(p); /* Give up if we don't know how large p is. */ if (p_size == SIZE_MAX) @@ -267,8 +240,8 @@ extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy); */ __FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size) { - size_t p_size = __member_size(p); - size_t q_size = __member_size(q); + const size_t p_size = __member_size(p); + const size_t q_size = __member_size(q); size_t q_len; /* Full count of source string length. */ size_t len; /* Count of characters going into destination. */ @@ -299,8 +272,8 @@ extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy); * @q: Where to copy the string from * @size: Size of destination buffer * - * Copy the source string @p, or as much of it as fits, into the destination - * @q buffer. The behavior is undefined if the string buffers overlap. The + * Copy the source string @q, or as much of it as fits, into the destination + * @p buffer. The behavior is undefined if the string buffers overlap. The * destination @p buffer is always NUL terminated, unless it's zero-sized. * * Preferred to strlcpy() since the API doesn't require reading memory @@ -318,10 +291,10 @@ extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy); */ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, size_t size) { - size_t len; /* Use string size rather than possible enclosing struct size. */ - size_t p_size = __member_size(p); - size_t q_size = __member_size(q); + const size_t p_size = __member_size(p); + const size_t q_size = __member_size(q); + size_t len; /* If we cannot get size of p and q default to call strscpy. */ if (p_size == SIZE_MAX && q_size == SIZE_MAX) @@ -371,6 +344,96 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s return __real_strscpy(p, q, len); } +/* Defined after fortified strlen() to reuse it. */ +extern size_t __real_strlcat(char *p, const char *q, size_t avail) __RENAME(strlcat); +/** + * strlcat - Append a string to an existing string + * + * @p: pointer to %NUL-terminated string to append to + * @q: pointer to %NUL-terminated string to append from + * @avail: Maximum bytes available in @p + * + * Appends %NUL-terminated string @q after the %NUL-terminated + * string at @p, but will not write beyond @avail bytes total, + * potentially truncating the copy from @q. @p will stay + * %NUL-terminated only if a %NUL already existed within + * the @avail bytes of @p. If so, the resulting number of + * bytes copied from @q will be at most "@avail - strlen(@p) - 1". + * + * Do not use this function. While FORTIFY_SOURCE tries to avoid + * read and write overflows, this is only possible when the sizes + * of @p and @q are known to the compiler. Prefer building the + * string with formatting, via scnprintf(), seq_buf, or similar. + * + * Returns total bytes that _would_ have been contained by @p + * regardless of truncation, similar to snprintf(). If return + * value is >= @avail, the string has been truncated. + * + */ +__FORTIFY_INLINE +size_t strlcat(char * const POS p, const char * const POS q, size_t avail) +{ + const size_t p_size = __member_size(p); + const size_t q_size = __member_size(q); + size_t p_len, copy_len; + size_t actual, wanted; + + /* Give up immediately if both buffer sizes are unknown. */ + if (p_size == SIZE_MAX && q_size == SIZE_MAX) + return __real_strlcat(p, q, avail); + + p_len = strnlen(p, avail); + copy_len = strlen(q); + wanted = actual = p_len + copy_len; + + /* Cannot append any more: report truncation. */ + if (avail <= p_len) + return wanted; + + /* Give up if string is already overflowed. */ + if (p_size <= p_len) + fortify_panic(__func__); + + if (actual >= avail) { + copy_len = avail - p_len - 1; + actual = p_len + copy_len; + } + + /* Give up if copy will overflow. */ + if (p_size <= actual) + fortify_panic(__func__); + __underlying_memcpy(p + p_len, q, copy_len); + p[actual] = '\0'; + + return wanted; +} + +/* Defined after fortified strlcat() to reuse it. */ +/** + * strcat - Append a string to an existing string + * + * @p: pointer to NUL-terminated string to append to + * @q: pointer to NUL-terminated source string to append from + * + * Do not use this function. While FORTIFY_SOURCE tries to avoid + * read and write overflows, this is only possible when the + * destination buffer size is known to the compiler. Prefer + * building the string with formatting, via scnprintf() or similar. + * At the very least, use strncat(). + * + * Returns @p. + * + */ +__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2) +char *strcat(char * const POS p, const char *q) +{ + const size_t p_size = __member_size(p); + + if (strlcat(p, q, p_size) >= p_size) + fortify_panic(__func__); + return p; +} + /** * strncat - Append a string to an existing string * @@ -394,9 +457,9 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s __FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3) char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count) { + const size_t p_size = __member_size(p); + const size_t q_size = __member_size(q); size_t p_len, copy_len; - size_t p_size = __member_size(p); - size_t q_size = __member_size(q); if (p_size == SIZE_MAX && q_size == SIZE_MAX) return __underlying_strncat(p, q, count); @@ -639,7 +702,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) { - size_t p_size = __struct_size(p); + const size_t p_size = __struct_size(p); if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -651,8 +714,8 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) __FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3) int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t size) { - size_t p_size = __struct_size(p); - size_t q_size = __struct_size(q); + const size_t p_size = __struct_size(p); + const size_t q_size = __struct_size(q); if (__builtin_constant_p(size)) { if (__compiletime_lessthan(p_size, size)) @@ -668,7 +731,7 @@ int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t __FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3) void *memchr(const void * const POS0 p, int c, __kernel_size_t size) { - size_t p_size = __struct_size(p); + const size_t p_size = __struct_size(p); if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -680,7 +743,7 @@ void *memchr(const void * const POS0 p, int c, __kernel_size_t size) void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv); __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size) { - size_t p_size = __struct_size(p); + const size_t p_size = __struct_size(p); if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -693,7 +756,7 @@ extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kme __realloc_size(2); __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp) { - size_t p_size = __struct_size(p); + const size_t p_size = __struct_size(p); if (__compiletime_lessthan(p_size, size)) __read_overflow(); @@ -720,8 +783,8 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp __FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2) char *strcpy(char * const POS p, const char * const POS q) { - size_t p_size = __member_size(p); - size_t q_size = __member_size(q); + const size_t p_size = __member_size(p); + const size_t q_size = __member_size(q); size_t size; /* If neither buffer size is known, immediately give up. */ diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h index 47fefc7f363b..3e03758151f4 100644 --- a/include/linux/fprobe.h +++ b/include/linux/fprobe.h @@ -35,9 +35,11 @@ struct fprobe { int nr_maxactive; int (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, - struct pt_regs *regs, void *entry_data); + unsigned long ret_ip, struct pt_regs *regs, + void *entry_data); void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, - struct pt_regs *regs, void *entry_data); + unsigned long ret_ip, struct pt_regs *regs, + void *entry_data); }; /* This fprobe is soft-disabled. */ @@ -64,6 +66,7 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num); int register_fprobe_syms(struct fprobe *fp, const char **syms, int num); int unregister_fprobe(struct fprobe *fp); +bool fprobe_is_registered(struct fprobe *fp); #else static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) { @@ -81,6 +84,10 @@ static inline int unregister_fprobe(struct fprobe *fp) { return -EOPNOTSUPP; } +static inline bool fprobe_is_registered(struct fprobe *fp) +{ + return false; +} #endif /** diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h index a631bac12220..eaa0ac5f9003 100644 --- a/include/linux/frontswap.h +++ b/include/linux/frontswap.h @@ -10,7 +10,7 @@ struct frontswap_ops { void (*init)(unsigned); /* this swap type was just swapon'ed */ int (*store)(unsigned, pgoff_t, struct page *); /* store a page */ - int (*load)(unsigned, pgoff_t, struct page *); /* load a page */ + int (*load)(unsigned, pgoff_t, struct page *, bool *); /* load a page */ void (*invalidate_page)(unsigned, pgoff_t); /* page no longer needed */ void (*invalidate_area)(unsigned); /* swap type just swapoff'ed */ }; diff --git a/include/linux/fs.h b/include/linux/fs.h index 21a981680856..6867512907d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -119,13 +119,6 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define FMODE_PWRITE ((__force fmode_t)0x10) /* File is opened for execution with sys_execve / sys_uselib */ #define FMODE_EXEC ((__force fmode_t)0x20) -/* File is opened with O_NDELAY (only set for block devices) */ -#define FMODE_NDELAY ((__force fmode_t)0x40) -/* File is opened with O_EXCL (only set for block devices) */ -#define FMODE_EXCL ((__force fmode_t)0x80) -/* File is opened using open(.., 3, ..) and is writeable only for ioctls - (specialy hack for floppy.c) */ -#define FMODE_WRITE_IOCTL ((__force fmode_t)0x100) /* 32bit hashes as llseek() offset (for directories) */ #define FMODE_32BITHASH ((__force fmode_t)0x200) /* 64bit hashes as llseek() offset (for directories) */ @@ -171,6 +164,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, /* File supports non-exclusive O_DIRECT writes from multiple threads */ #define FMODE_DIO_PARALLEL_WRITE ((__force fmode_t)0x1000000) +/* File is embedded in backing_file object */ +#define FMODE_BACKING ((__force fmode_t)0x2000000) + /* File was opened by fanotify and shouldn't generate fanotify events */ #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) @@ -956,29 +952,35 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index) index < ra->start + ra->size); } +/* + * f_{lock,count,pos_lock} members can be highly contended and share + * the same cacheline. f_{lock,mode} are very frequently used together + * and so share the same cacheline as well. The read-mostly + * f_{path,inode,op} are kept on a separate cacheline. + */ struct file { union { struct llist_node f_llist; struct rcu_head f_rcuhead; unsigned int f_iocb_flags; }; - struct path f_path; - struct inode *f_inode; /* cached value */ - const struct file_operations *f_op; /* * Protects f_ep, f_flags. * Must not be taken from IRQ context. */ spinlock_t f_lock; - atomic_long_t f_count; - unsigned int f_flags; fmode_t f_mode; + atomic_long_t f_count; struct mutex f_pos_lock; loff_t f_pos; + unsigned int f_flags; struct fown_struct f_owner; const struct cred *f_cred; struct file_ra_state f_ra; + struct path f_path; + struct inode *f_inode; /* cached value */ + const struct file_operations *f_op; u64 f_version; #ifdef CONFIG_SECURITY @@ -1076,29 +1078,29 @@ extern int send_sigurg(struct fown_struct *fown); * sb->s_flags. Note that these mirror the equivalent MS_* flags where * represented in both. */ -#define SB_RDONLY 1 /* Mount read-only */ -#define SB_NOSUID 2 /* Ignore suid and sgid bits */ -#define SB_NODEV 4 /* Disallow access to device special files */ -#define SB_NOEXEC 8 /* Disallow program execution */ -#define SB_SYNCHRONOUS 16 /* Writes are synced at once */ -#define SB_MANDLOCK 64 /* Allow mandatory locks on an FS */ -#define SB_DIRSYNC 128 /* Directory modifications are synchronous */ -#define SB_NOATIME 1024 /* Do not update access times. */ -#define SB_NODIRATIME 2048 /* Do not update directory access times */ -#define SB_SILENT 32768 -#define SB_POSIXACL (1<<16) /* VFS does not apply the umask */ -#define SB_INLINECRYPT (1<<17) /* Use blk-crypto for encrypted files */ -#define SB_KERNMOUNT (1<<22) /* this is a kern_mount call */ -#define SB_I_VERSION (1<<23) /* Update inode I_version field */ -#define SB_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define SB_RDONLY BIT(0) /* Mount read-only */ +#define SB_NOSUID BIT(1) /* Ignore suid and sgid bits */ +#define SB_NODEV BIT(2) /* Disallow access to device special files */ +#define SB_NOEXEC BIT(3) /* Disallow program execution */ +#define SB_SYNCHRONOUS BIT(4) /* Writes are synced at once */ +#define SB_MANDLOCK BIT(6) /* Allow mandatory locks on an FS */ +#define SB_DIRSYNC BIT(7) /* Directory modifications are synchronous */ +#define SB_NOATIME BIT(10) /* Do not update access times. */ +#define SB_NODIRATIME BIT(11) /* Do not update directory access times */ +#define SB_SILENT BIT(15) +#define SB_POSIXACL BIT(16) /* VFS does not apply the umask */ +#define SB_INLINECRYPT BIT(17) /* Use blk-crypto for encrypted files */ +#define SB_KERNMOUNT BIT(22) /* this is a kern_mount call */ +#define SB_I_VERSION BIT(23) /* Update inode I_version field */ +#define SB_LAZYTIME BIT(25) /* Update the on-disk [acm]times lazily */ /* These sb flags are internal to the kernel */ -#define SB_SUBMOUNT (1<<26) -#define SB_FORCE (1<<27) -#define SB_NOSEC (1<<28) -#define SB_BORN (1<<29) -#define SB_ACTIVE (1<<30) -#define SB_NOUSER (1<<31) +#define SB_SUBMOUNT BIT(26) +#define SB_FORCE BIT(27) +#define SB_NOSEC BIT(28) +#define SB_BORN BIT(29) +#define SB_ACTIVE BIT(30) +#define SB_NOUSER BIT(31) /* These flags relate to encoding and casefolding */ #define SB_ENC_STRICT_MODE_FL (1 << 0) @@ -1146,7 +1148,6 @@ enum { struct sb_writers { int frozen; /* Is sb frozen? */ - wait_queue_head_t wait_unfrozen; /* wait for thaw */ struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS]; }; @@ -1215,7 +1216,6 @@ struct super_block { uuid_t s_uuid; /* UUID */ unsigned int s_max_links; - fmode_t s_mode; /* * The next field is for VFS *only*. No filesystems have any business @@ -1242,7 +1242,7 @@ struct super_block { */ atomic_long_t s_fsnotify_connectors; - /* Being remounted read-only */ + /* Read-only state of the superblock is being changed */ int s_readonly_remount; /* per-sb errseq_t for reporting writeback errors via syncfs */ @@ -1672,9 +1672,12 @@ static inline int vfs_whiteout(struct mnt_idmap *idmap, WHITEOUT_DEV); } -struct file *vfs_tmpfile_open(struct mnt_idmap *idmap, - const struct path *parentpath, - umode_t mode, int open_flag, const struct cred *cred); +struct file *kernel_tmpfile_open(struct mnt_idmap *idmap, + const struct path *parentpath, + umode_t mode, int open_flag, + const struct cred *cred); +struct file *kernel_file_open(const struct path *path, int flags, + struct inode *inode, const struct cred *cred); int vfs_mkobj(struct dentry *, umode_t, int (*f)(struct dentry *, umode_t, void *), @@ -1790,12 +1793,12 @@ struct file_operations { int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); - ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); + void (*splice_eof)(struct file *file); int (*setlease)(struct file *, long, struct file_lock **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); @@ -1932,6 +1935,7 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + void (*shutdown)(struct super_block *sb); }; /* @@ -2349,11 +2353,31 @@ static inline struct file *file_open_root_mnt(struct vfsmount *mnt, return file_open_root(&(struct path){.mnt = mnt, .dentry = mnt->mnt_root}, name, flags, mode); } -extern struct file * dentry_open(const struct path *, int, const struct cred *); -extern struct file *dentry_create(const struct path *path, int flags, - umode_t mode, const struct cred *cred); -extern struct file * open_with_fake_path(const struct path *, int, - struct inode*, const struct cred *); +struct file *dentry_open(const struct path *path, int flags, + const struct cred *creds); +struct file *dentry_create(const struct path *path, int flags, umode_t mode, + const struct cred *cred); +struct file *backing_file_open(const struct path *path, int flags, + const struct path *real_path, + const struct cred *cred); +struct path *backing_file_real_path(struct file *f); + +/* + * file_real_path - get the path corresponding to f_inode + * + * When opening a backing file for a stackable filesystem (e.g., + * overlayfs) f_path may be on the stackable filesystem and f_inode on + * the underlying filesystem. When the path associated with f_inode is + * needed, this helper should be used instead of accessing f_path + * directly. +*/ +static inline const struct path *file_real_path(struct file *f) +{ + if (unlikely(f->f_mode & FMODE_BACKING)) + return backing_file_real_path(f); + return &f->f_path; +} + static inline struct file *file_clone_open(struct file *file) { return dentry_open(&file->f_path, file->f_flags, file->f_cred); @@ -2669,7 +2693,7 @@ extern void evict_inodes(struct super_block *sb); void dump_mapping(const struct address_space *); /* - * Userspace may rely on the the inode number being non-zero. For example, glibc + * Userspace may rely on the inode number being non-zero. For example, glibc * simply ignores files with zero i_ino in unlink() and other places. * * As an additional complication, if userspace was compiled with @@ -2738,6 +2762,8 @@ extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *); ssize_t generic_perform_write(struct kiocb *, struct iov_iter *); +ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter, + ssize_t direct_written, ssize_t buffered_written); ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos, rwf_t flags); @@ -2752,15 +2778,11 @@ ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb, ssize_t filemap_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); -ssize_t direct_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, - size_t len, unsigned int flags); -extern ssize_t generic_file_splice_read(struct file *, loff_t *, - struct pipe_inode_info *, size_t, unsigned int); +ssize_t copy_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags); extern ssize_t iter_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, - struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len, unsigned int flags); @@ -2837,11 +2859,6 @@ static inline void inode_dio_end(struct inode *inode) wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); } -/* - * Warn about a page cache invalidation failure diring a direct I/O write. - */ -void dio_warn_stale_pagecache(struct file *filp); - extern void inode_set_flags(struct inode *inode, unsigned int flags, unsigned int mask); diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index a86115bc799c..a1b3de87a3d1 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h @@ -48,7 +48,7 @@ struct fsl_mc_driver { struct device_driver driver; const struct fsl_mc_device_id *match_id_table; int (*probe)(struct fsl_mc_device *dev); - int (*remove)(struct fsl_mc_device *dev); + void (*remove)(struct fsl_mc_device *dev); void (*shutdown)(struct fsl_mc_device *dev); int (*suspend)(struct fsl_mc_device *dev, pm_message_t state); int (*resume)(struct fsl_mc_device *dev); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index bb8467cd11ae..ed48e4f1e755 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -91,11 +91,13 @@ static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask) static inline int fsnotify_file(struct file *file, __u32 mask) { - const struct path *path = &file->f_path; + const struct path *path; if (file->f_mode & FMODE_NONOTIFY) return 0; + /* Overlayfs internal files have fake f_path */ + path = file_real_path(file); return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH); } diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index e76605d5b36e..1eb7eae580be 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -143,8 +143,8 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *arg); int fsverity_ioctl_measure(struct file *filp, void __user *arg); int fsverity_get_digest(struct inode *inode, - u8 digest[FS_VERITY_MAX_DIGEST_SIZE], - enum hash_algo *alg); + u8 raw_digest[FS_VERITY_MAX_DIGEST_SIZE], + u8 *alg, enum hash_algo *halg); /* open.c */ @@ -197,10 +197,14 @@ static inline int fsverity_ioctl_measure(struct file *filp, void __user *arg) } static inline int fsverity_get_digest(struct inode *inode, - u8 digest[FS_VERITY_MAX_DIGEST_SIZE], - enum hash_algo *alg) + u8 raw_digest[FS_VERITY_MAX_DIGEST_SIZE], + u8 *alg, enum hash_algo *halg) { - return -EOPNOTSUPP; + /* + * fsverity is not enabled in the kernel configuration, so always report + * that the file doesn't have fsverity enabled (digest size 0). + */ + return 0; } /* open.c */ diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b23bdd414394..8e59bd954153 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -633,6 +633,7 @@ enum { FTRACE_ITER_MOD = (1 << 5), FTRACE_ITER_ENABLED = (1 << 6), FTRACE_ITER_TOUCHED = (1 << 7), + FTRACE_ITER_ADDRS = (1 << 8), }; void arch_ftrace_update_code(int command); @@ -1018,6 +1019,9 @@ struct ftrace_graph_ent { */ struct ftrace_graph_ret { unsigned long func; /* Current function */ +#ifdef CONFIG_FUNCTION_GRAPH_RETVAL + unsigned long retval; +#endif int depth; /* Number of functions that overran the depth limit for current task */ unsigned int overrun; diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 8c2f00018e89..0a221e768ea4 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -5,7 +5,6 @@ #ifndef _GAMEPORT_H #define _GAMEPORT_H -#include <asm/io.h> #include <linux/types.h> #include <linux/list.h> #include <linux/mutex.h> @@ -165,18 +164,12 @@ void gameport_unregister_driver(struct gameport_driver *drv); static inline void gameport_trigger(struct gameport *gameport) { - if (gameport->trigger) - gameport->trigger(gameport); - else - outb(0xff, gameport->io); + gameport->trigger(gameport); } static inline unsigned char gameport_read(struct gameport *gameport) { - if (gameport->read) - return gameport->read(gameport); - else - return inb(gameport->io); + return gameport->read(gameport); } static inline int gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index ed8cb537c6a7..665f06675c83 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -338,19 +338,12 @@ extern gfp_t gfp_allowed_mask; /* Returns true if the gfp_mask allows use of ALLOC_NO_WATERMARK */ bool gfp_pfmemalloc_allowed(gfp_t gfp_mask); -extern void pm_restrict_gfp_mask(void); -extern void pm_restore_gfp_mask(void); - -extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma); - -#ifdef CONFIG_PM_SLEEP -extern bool pm_suspended_storage(void); -#else -static inline bool pm_suspended_storage(void) +static inline bool gfp_has_io_fs(gfp_t gfp) { - return false; + return (gfp & (__GFP_IO | __GFP_FS)) == (__GFP_IO | __GFP_FS); } -#endif /* CONFIG_PM_SLEEP */ + +extern gfp_t vma_thp_gfp_mask(struct vm_area_struct *vma); #ifdef CONFIG_CONTIG_ALLOC /* The below functions must be run on a range from a single zone. */ diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 8528353e073b..7ecc25c543ce 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -32,17 +32,6 @@ struct device; /* Gpio pin is active-low */ #define GPIOF_ACTIVE_LOW (1 << 2) -/* Gpio pin is open drain */ -#define GPIOF_OPEN_DRAIN (1 << 3) - -/* Gpio pin is open source */ -#define GPIOF_OPEN_SOURCE (1 << 4) - -#define GPIOF_EXPORT (1 << 5) -#define GPIOF_EXPORT_CHANGEABLE (1 << 6) -#define GPIOF_EXPORT_DIR_FIXED (GPIOF_EXPORT) -#define GPIOF_EXPORT_DIR_CHANGEABLE (GPIOF_EXPORT | GPIOF_EXPORT_CHANGEABLE) - /** * struct gpio - a structure describing a GPIO with configuration * @gpio: the GPIO number @@ -119,11 +108,6 @@ static inline void gpio_set_value(unsigned gpio, int value) return gpiod_set_raw_value(gpio_to_desc(gpio), value); } -static inline int gpio_cansleep(unsigned gpio) -{ - return gpiod_cansleep(gpio_to_desc(gpio)); -} - static inline int gpio_to_irq(unsigned gpio) { return gpiod_to_irq(gpio_to_desc(gpio)); @@ -206,13 +190,6 @@ static inline void gpio_set_value(unsigned gpio, int value) WARN_ON(1); } -static inline int gpio_cansleep(unsigned gpio) -{ - /* GPIO can never have been requested or set as {in,out}put */ - WARN_ON(1); - return 0; -} - static inline int gpio_get_value_cansleep(unsigned gpio) { /* GPIO can never have been requested or set as {in,out}put */ diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 5c6db5533be6..4f0c5d62c8f3 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -61,13 +61,6 @@ struct gpio_irq_chip { */ struct irq_domain *domain; - /** - * @domain_ops: - * - * Table of interrupt domain operations for this IRQ chip. - */ - const struct irq_domain_ops *domain_ops; - #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY /** * @fwnode: @@ -252,6 +245,14 @@ struct gpio_irq_chip { bool initialized; /** + * @domain_is_allocated_externally: + * + * True it the irq_domain was allocated outside of gpiolib, in which + * case gpiolib won't free the irq_domain itself. + */ + bool domain_is_allocated_externally; + + /** * @init_hw: optional routine to initialize hardware before * an IRQ chip will be added. This is quite useful when * a particular driver wants to clear IRQ related registers diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 2f4dcc8d060e..3bb87bf6bc65 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -170,19 +170,19 @@ struct hdmi_avi_infoframe { enum hdmi_infoframe_type type; unsigned char version; unsigned char length; + bool itc; + unsigned char pixel_repeat; enum hdmi_colorspace colorspace; enum hdmi_scan_mode scan_mode; enum hdmi_colorimetry colorimetry; enum hdmi_picture_aspect picture_aspect; enum hdmi_active_aspect active_aspect; - bool itc; enum hdmi_extended_colorimetry extended_colorimetry; enum hdmi_quantization_range quantization_range; enum hdmi_nups nups; unsigned char video_code; enum hdmi_ycc_quantization_range ycc_quantization_range; enum hdmi_content_type content_type; - unsigned char pixel_repeat; unsigned short top_bar; unsigned short bottom_bar; unsigned short left_bar; diff --git a/include/linux/hid.h b/include/linux/hid.h index 4e4c4fe36911..39e21e3815ad 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -597,6 +597,7 @@ struct hid_device { /* device report descriptor */ struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; + void *devres_group_id; /* ID of probe devres group */ const struct hid_ll_driver *ll_driver; struct mutex ll_open_lock; diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 4de1dbcd3ef6..68da30625a6c 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -507,7 +507,7 @@ static inline void folio_zero_range(struct folio *folio, zero_user_segments(&folio->page, start, start + length, 0, 0); } -static inline void put_and_unmap_page(struct page *page, void *addr) +static inline void unmap_and_put_page(struct page *page, void *addr) { kunmap_local(addr); put_page(page); diff --git a/include/linux/hsi/ssi_protocol.h b/include/linux/hsi/ssi_protocol.h index 2d6f3cfa7dea..972434daa000 100644 --- a/include/linux/hsi/ssi_protocol.h +++ b/include/linux/hsi/ssi_protocol.h @@ -24,6 +24,7 @@ int ssip_slave_stop_tx(struct hsi_client *master); void ssip_reset_event(struct hsi_client *master); int ssip_slave_running(struct hsi_client *master); +void ssi_waketest(struct hsi_client *cl, unsigned int enable); #endif /* __LINUX_SSIP_SLAVE_H__ */ diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 6d041aa9f0fe..ca3c8e10f24a 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -133,9 +133,8 @@ int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct page *hugetlb_follow_page_mask(struct vm_area_struct *vma, unsigned long address, unsigned int flags); long follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, - struct page **, struct vm_area_struct **, - unsigned long *, unsigned long *, long, unsigned int, - int *); + struct page **, unsigned long *, unsigned long *, + long, unsigned int, int *); void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long, struct page *, zap_flags_t); @@ -306,9 +305,8 @@ static inline struct page *hugetlb_follow_page_mask(struct vm_area_struct *vma, static inline long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, struct page **pages, - struct vm_area_struct **vmas, unsigned long *position, - unsigned long *nr_pages, long i, unsigned int flags, - int *nonblocking) + unsigned long *position, unsigned long *nr_pages, + long i, unsigned int flags, int *nonblocking) { BUG(); return 0; @@ -757,26 +755,12 @@ static inline struct hugepage_subpool *hugetlb_folio_subpool(struct folio *folio return folio->_hugetlb_subpool; } -/* - * hugetlb page subpool pointer located in hpage[2].hugetlb_subpool - */ -static inline struct hugepage_subpool *hugetlb_page_subpool(struct page *hpage) -{ - return hugetlb_folio_subpool(page_folio(hpage)); -} - static inline void hugetlb_set_folio_subpool(struct folio *folio, struct hugepage_subpool *subpool) { folio->_hugetlb_subpool = subpool; } -static inline void hugetlb_set_page_subpool(struct page *hpage, - struct hugepage_subpool *subpool) -{ - hugetlb_set_folio_subpool(page_folio(hpage), subpool); -} - static inline struct hstate *hstate_file(struct file *f) { return hstate_inode(file_inode(f)); @@ -1031,11 +1015,6 @@ static inline struct hugepage_subpool *hugetlb_folio_subpool(struct folio *folio return NULL; } -static inline struct hugepage_subpool *hugetlb_page_subpool(struct page *hpage) -{ - return NULL; -} - static inline int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list) { @@ -1200,7 +1179,11 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm) static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { +#ifdef CONFIG_MMU + return ptep_get(ptep); +#else return *ptep; +#endif } static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 492dd27a5dd8..8cd6a6b33593 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -44,6 +44,7 @@ enum hwmon_chip_attributes { hwmon_chip_in_samples, hwmon_chip_power_samples, hwmon_chip_temp_samples, + hwmon_chip_beep_enable, }; #define HWMON_C_TEMP_RESET_HISTORY BIT(hwmon_chip_temp_reset_history) @@ -58,6 +59,7 @@ enum hwmon_chip_attributes { #define HWMON_C_IN_SAMPLES BIT(hwmon_chip_in_samples) #define HWMON_C_POWER_SAMPLES BIT(hwmon_chip_power_samples) #define HWMON_C_TEMP_SAMPLES BIT(hwmon_chip_temp_samples) +#define HWMON_C_BEEP_ENABLE BIT(hwmon_chip_beep_enable) enum hwmon_temp_attributes { hwmon_temp_enable, @@ -87,6 +89,7 @@ enum hwmon_temp_attributes { hwmon_temp_reset_history, hwmon_temp_rated_min, hwmon_temp_rated_max, + hwmon_temp_beep, }; #define HWMON_T_ENABLE BIT(hwmon_temp_enable) @@ -116,6 +119,7 @@ enum hwmon_temp_attributes { #define HWMON_T_RESET_HISTORY BIT(hwmon_temp_reset_history) #define HWMON_T_RATED_MIN BIT(hwmon_temp_rated_min) #define HWMON_T_RATED_MAX BIT(hwmon_temp_rated_max) +#define HWMON_T_BEEP BIT(hwmon_temp_beep) enum hwmon_in_attributes { hwmon_in_enable, @@ -136,6 +140,7 @@ enum hwmon_in_attributes { hwmon_in_crit_alarm, hwmon_in_rated_min, hwmon_in_rated_max, + hwmon_in_beep, }; #define HWMON_I_ENABLE BIT(hwmon_in_enable) @@ -156,6 +161,7 @@ enum hwmon_in_attributes { #define HWMON_I_CRIT_ALARM BIT(hwmon_in_crit_alarm) #define HWMON_I_RATED_MIN BIT(hwmon_in_rated_min) #define HWMON_I_RATED_MAX BIT(hwmon_in_rated_max) +#define HWMON_I_BEEP BIT(hwmon_in_beep) enum hwmon_curr_attributes { hwmon_curr_enable, @@ -176,6 +182,7 @@ enum hwmon_curr_attributes { hwmon_curr_crit_alarm, hwmon_curr_rated_min, hwmon_curr_rated_max, + hwmon_curr_beep, }; #define HWMON_C_ENABLE BIT(hwmon_curr_enable) @@ -196,6 +203,7 @@ enum hwmon_curr_attributes { #define HWMON_C_CRIT_ALARM BIT(hwmon_curr_crit_alarm) #define HWMON_C_RATED_MIN BIT(hwmon_curr_rated_min) #define HWMON_C_RATED_MAX BIT(hwmon_curr_rated_max) +#define HWMON_C_BEEP BIT(hwmon_curr_beep) enum hwmon_power_attributes { hwmon_power_enable, @@ -312,6 +320,7 @@ enum hwmon_fan_attributes { hwmon_fan_min_alarm, hwmon_fan_max_alarm, hwmon_fan_fault, + hwmon_fan_beep, }; #define HWMON_F_ENABLE BIT(hwmon_fan_enable) @@ -326,6 +335,7 @@ enum hwmon_fan_attributes { #define HWMON_F_MIN_ALARM BIT(hwmon_fan_min_alarm) #define HWMON_F_MAX_ALARM BIT(hwmon_fan_max_alarm) #define HWMON_F_FAULT BIT(hwmon_fan_fault) +#define HWMON_F_BEEP BIT(hwmon_fan_beep) enum hwmon_pwm_attributes { hwmon_pwm_input, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 13a1ce38cb0c..3430cc2b05a6 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -367,6 +367,8 @@ struct i2c_adapter *i2c_verify_adapter(struct device *dev); const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, const struct i2c_client *client); +const void *i2c_get_match_data(const struct i2c_client *client); + static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) { struct device * const dev = kobj_to_dev(kobj); diff --git a/include/linux/i8042.h b/include/linux/i8042.h index 0261e2fb3636..95b07f8b77fe 100644 --- a/include/linux/i8042.h +++ b/include/linux/i8042.h @@ -3,6 +3,7 @@ #define _LINUX_I8042_H +#include <linux/errno.h> #include <linux/types.h> /* diff --git a/include/linux/i8254.h b/include/linux/i8254.h new file mode 100644 index 000000000000..a675c309232b --- /dev/null +++ b/include/linux/i8254.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) William Breathitt Gray */ +#ifndef _I8254_H_ +#define _I8254_H_ + +struct device; +struct regmap; + +/** + * struct i8254_regmap_config - Configuration for the register map of an i8254 + * @parent: parent device + * @map: regmap for the i8254 + */ +struct i8254_regmap_config { + struct device *parent; + struct regmap *map; +}; + +int devm_i8254_regmap_register(struct device *dev, const struct i8254_regmap_config *config); + +#endif /* _I8254_H_ */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index c4cf296e7eaf..4b998090898e 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1349,8 +1349,11 @@ struct ieee80211_mgmt { /* Supported rates membership selectors */ #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 #define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 -#define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 +#define BSS_MEMBERSHIP_SELECTOR_GLK 125 +#define BSS_MEMBERSHIP_SELECTOR_EPS 124 #define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123 +#define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122 +#define BSS_MEMBERSHIP_SELECTOR_EHT_PHY 121 /* mgmt header + 1 byte category code */ #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) @@ -1993,12 +1996,18 @@ struct ieee80211_mu_edca_param_set { * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams * supported for reception and the maximum number of spatial streams * supported for transmission for MCS 12 - 13. + * @rx_tx_max_nss: array of the previous fields for easier loop access */ struct ieee80211_eht_mcs_nss_supp_20mhz_only { - u8 rx_tx_mcs7_max_nss; - u8 rx_tx_mcs9_max_nss; - u8 rx_tx_mcs11_max_nss; - u8 rx_tx_mcs13_max_nss; + union { + struct { + u8 rx_tx_mcs7_max_nss; + u8 rx_tx_mcs9_max_nss; + u8 rx_tx_mcs11_max_nss; + u8 rx_tx_mcs13_max_nss; + }; + u8 rx_tx_max_nss[4]; + }; }; /** @@ -2018,11 +2027,17 @@ struct ieee80211_eht_mcs_nss_supp_20mhz_only { * @rx_tx_mcs13_max_nss: indicates the maximum number of spatial streams * supported for reception and the maximum number of spatial streams * supported for transmission for MCS 12 - 13. + * @rx_tx_max_nss: array of the previous fields for easier loop access */ struct ieee80211_eht_mcs_nss_supp_bw { - u8 rx_tx_mcs9_max_nss; - u8 rx_tx_mcs11_max_nss; - u8 rx_tx_mcs13_max_nss; + union { + struct { + u8 rx_tx_mcs9_max_nss; + u8 rx_tx_mcs11_max_nss; + u8 rx_tx_mcs13_max_nss; + }; + u8 rx_tx_max_nss[3]; + }; }; /** @@ -2075,7 +2090,7 @@ struct ieee80211_eht_cap_elem { */ struct ieee80211_eht_operation { u8 params; - __le32 basic_mcs_nss; + struct ieee80211_eht_mcs_nss_supp_20mhz_only basic_mcs_nss; u8 optional[]; } __packed; @@ -2856,6 +2871,7 @@ ieee80211_he_spr_size(const u8 *he_spr_ie) /* Maximum number of supported EHT LTF is split */ #define IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK 0xc0 +#define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF 0x40 #define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK 0x07 #define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK 0x78 @@ -4477,8 +4493,8 @@ static inline bool for_each_element_completed(const struct element *element, #define IEEE80211_AP_INFO_TBTT_HDR_FILTERED 0x04 #define IEEE80211_AP_INFO_TBTT_HDR_COLOC 0x08 #define IEEE80211_AP_INFO_TBTT_HDR_COUNT 0xF0 -#define IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM 9 -#define IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM 13 +#define IEEE80211_TBTT_INFO_TYPE_TBTT 0 +#define IEEE80211_TBTT_INFO_TYPE_MLD 1 #define IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED 0x01 #define IEEE80211_RNR_TBTT_PARAMS_SAME_SSID 0x02 @@ -4488,6 +4504,9 @@ static inline bool for_each_element_completed(const struct element *element, #define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20 #define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40 +#define IEEE80211_RNR_TBTT_PARAMS_PSD_NO_LIMIT 127 +#define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128 + struct ieee80211_neighbor_ap_info { u8 tbtt_info_hdr; u8 tbtt_info_len; @@ -4502,6 +4521,42 @@ enum ieee80211_range_params_max_total_ltf { IEEE80211_RANGE_PARAMS_MAX_TOTAL_LTF_UNSPECIFIED, }; +/* + * reduced neighbor report, based on Draft P802.11be_D3.0, + * section 9.4.2.170.2. + */ +struct ieee80211_rnr_mld_params { + u8 mld_id; + __le16 params; +} __packed; + +#define IEEE80211_RNR_MLD_PARAMS_LINK_ID 0x000F +#define IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT 0x0FF0 +#define IEEE80211_RNR_MLD_PARAMS_UPDATES_INCLUDED 0x1000 +#define IEEE80211_RNR_MLD_PARAMS_DISABLED_LINK 0x2000 + +/* Format of the TBTT information element if it has 7, 8 or 9 bytes */ +struct ieee80211_tbtt_info_7_8_9 { + u8 tbtt_offset; + u8 bssid[ETH_ALEN]; + + /* The following element is optional, structure may not grow */ + u8 bss_params; + s8 psd_20; +} __packed; + +/* Format of the TBTT information element if it has >= 11 bytes */ +struct ieee80211_tbtt_info_ge_11 { + u8 tbtt_offset; + u8 bssid[ETH_ALEN]; + __le32 short_ssid; + + /* The following elements are optional, structure may grow */ + u8 bss_params; + s8 psd_20; + struct ieee80211_rnr_mld_params mld_params; +} __packed; + /* multi-link device */ #define IEEE80211_MLD_MAX_NUM_LINKS 15 @@ -4529,6 +4584,14 @@ struct ieee80211_multi_link_elem { #define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00 #define IEEE80211_MED_SYNC_DELAY_SYNC_MAX_NUM_TXOPS 0xf000 +/* + * Described in P802.11be_D3.0 + * dot11MSDTimerDuration should default to 5484 (i.e. 171.375) + * dot11MSDOFDMEDthreshold defaults to -72 (i.e. 0) + * dot11MSDTXOPMAX defaults to 1 + */ +#define IEEE80211_MED_SYNC_DELAY_DEFAULT 0x10ac + #define IEEE80211_EML_CAP_EMLSR_SUPP 0x0001 #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY 0x000e #define IEEE80211_EML_CAP_EMLSR_PADDING_DELAY_0US 0 @@ -4611,15 +4674,12 @@ static inline u8 ieee80211_mle_common_size(const u8 *data) case IEEE80211_ML_CONTROL_TYPE_BASIC: case IEEE80211_ML_CONTROL_TYPE_PREQ: case IEEE80211_ML_CONTROL_TYPE_TDLS: + case IEEE80211_ML_CONTROL_TYPE_RECONF: /* * The length is the first octet pointed by mle->variable so no * need to add anything */ break; - case IEEE80211_ML_CONTROL_TYPE_RECONF: - if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR) - common += ETH_ALEN; - return common; case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: if (control & IEEE80211_MLC_PRIO_ACCESS_PRES_AP_MLD_MAC_ADDR) common += ETH_ALEN; @@ -4633,6 +4693,95 @@ static inline u8 ieee80211_mle_common_size(const u8 *data) } /** + * ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count + * @mle: the basic multi link element + * + * The element is assumed to be of the correct type (BASIC) and big enough, + * this must be checked using ieee80211_mle_type_ok(). + * + * If the BSS parameter change count value can't be found (the presence bit + * for it is clear), 0 will be returned. + */ +static inline u8 +ieee80211_mle_get_bss_param_ch_cnt(const struct ieee80211_multi_link_elem *mle) +{ + u16 control = le16_to_cpu(mle->control); + const u8 *common = mle->variable; + + /* common points now at the beginning of ieee80211_mle_basic_common_info */ + common += sizeof(struct ieee80211_mle_basic_common_info); + + if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)) + return 0; + + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + + return *common; +} + +/** + * ieee80211_mle_get_eml_sync_delay - returns the medium sync delay + * @data: pointer to the multi link EHT IE + * + * The element is assumed to be of the correct type (BASIC) and big enough, + * this must be checked using ieee80211_mle_type_ok(). + * + * If the medium synchronization is not present, then the default value is + * returned. + */ +static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data) +{ + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control = le16_to_cpu(mle->control); + const u8 *common = mle->variable; + + /* common points now at the beginning of ieee80211_mle_basic_common_info */ + common += sizeof(struct ieee80211_mle_basic_common_info); + + if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)) + return IEEE80211_MED_SYNC_DELAY_DEFAULT; + + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) + common += 1; + + return get_unaligned_le16(common); +} + +/** + * ieee80211_mle_get_eml_cap - returns the EML capability + * @data: pointer to the multi link EHT IE + * + * The element is assumed to be of the correct type (BASIC) and big enough, + * this must be checked using ieee80211_mle_type_ok(). + * + * If the EML capability is not present, 0 will be returned. + */ +static inline u16 ieee80211_mle_get_eml_cap(const u8 *data) +{ + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control = le16_to_cpu(mle->control); + const u8 *common = mle->variable; + + /* common points now at the beginning of ieee80211_mle_basic_common_info */ + common += sizeof(struct ieee80211_mle_basic_common_info); + + if (!(control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)) + return 0; + + if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) + common += 1; + if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY) + common += 2; + + return get_unaligned_le16(common); +} + +/** * ieee80211_mle_size_ok - validate multi-link element size * @data: pointer to the element data * @len: length of the containing element @@ -4700,6 +4849,28 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len) return mle->variable[0] >= common; } +/** + * ieee80211_mle_type_ok - validate multi-link element type and size + * @data: pointer to the element data + * @type: expected type of the element + * @len: length of the containing element + */ +static inline bool ieee80211_mle_type_ok(const u8 *data, u8 type, size_t len) +{ + const struct ieee80211_multi_link_elem *mle = (const void *)data; + u16 control; + + if (!ieee80211_mle_size_ok(data, len)) + return false; + + control = le16_to_cpu(mle->control); + + if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) == type) + return true; + + return false; +} + enum ieee80211_mle_subelems { IEEE80211_MLE_SUBELEM_PER_STA_PROFILE = 0, IEEE80211_MLE_SUBELEM_FRAGMENT = 254, @@ -4722,11 +4893,13 @@ struct ieee80211_mle_per_sta_profile { } __packed; /** - * ieee80211_mle_sta_prof_size_ok - validate multi-link element sta profile size + * ieee80211_mle_basic_sta_prof_size_ok - validate basic multi-link element sta + * profile size * @data: pointer to the sub element data * @len: length of the containing sub element */ -static inline bool ieee80211_mle_sta_prof_size_ok(const u8 *data, size_t len) +static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data, + size_t len) { const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; u16 control; @@ -4746,21 +4919,93 @@ static inline bool ieee80211_mle_sta_prof_size_ok(const u8 *data, size_t len) info_len += 8; if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) info_len += 2; - if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) - info_len += 1; - if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && - control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) { + control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) info_len += 2; else info_len += 1; } + if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT) + info_len += 1; return prof->sta_info_len >= info_len && fixed + prof->sta_info_len <= len; } +/** + * ieee80211_mle_basic_sta_prof_bss_param_ch_cnt - get per-STA profile BSS + * parameter change count + * @prof: the per-STA profile, having been checked with + * ieee80211_mle_basic_sta_prof_size_ok() for the correct length + * + * Return: The BSS parameter change count value if present, 0 otherwise. + */ +static inline u8 +ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta_profile *prof) +{ + u16 control = le16_to_cpu(prof->control); + const u8 *pos = prof->variable; + + if (!(control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)) + return 0; + + if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT) + pos += 6; + if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) + pos += 2; + if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) + pos += 8; + if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT) + pos += 2; + if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE && + control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) { + if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) + pos += 2; + else + pos += 1; + } + + return *pos; +} + +#define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f +#define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010 +#define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020 +#define IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT 0x0040 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_UPDATE_TYPE 0x0780 +#define IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT 0x0800 + +/** + * ieee80211_mle_reconf_sta_prof_size_ok - validate reconfiguration multi-link + * element sta profile size. + * @data: pointer to the sub element data + * @len: length of the containing sub element + */ +static inline bool ieee80211_mle_reconf_sta_prof_size_ok(const u8 *data, + size_t len) +{ + const struct ieee80211_mle_per_sta_profile *prof = (const void *)data; + u16 control; + u8 fixed = sizeof(*prof); + u8 info_len = 1; + + if (len < fixed) + return false; + + control = le16_to_cpu(prof->control); + + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT) + info_len += ETH_ALEN; + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_AP_REM_TIMER_PRESENT) + info_len += 2; + if (control & IEEE80211_MLE_STA_RECONF_CONTROL_OPERATION_PARAMS_PRESENT) + info_len += 2; + + return prof->sta_info_len >= info_len && + fixed + prof->sta_info_len - 1 <= len; +} + #define for_each_mle_subelement(_elem, _data, _len) \ if (ieee80211_mle_size_ok(_data, _len)) \ for_each_element(_elem, \ diff --git a/include/linux/if_team.h b/include/linux/if_team.h index fc985e5c739d..8de6b6e67829 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -208,6 +208,7 @@ struct team { bool queue_override_enabled; struct list_head *qom_lists; /* array of queue override mapping lists */ bool port_mtu_change_allowed; + bool notifier_ctx; struct { unsigned int count; unsigned int interval; /* in ms */ diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 0f40f379d75c..6ba71957851e 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -637,6 +637,23 @@ static inline __be16 vlan_get_protocol(const struct sk_buff *skb) return __vlan_get_protocol(skb, skb->protocol, NULL); } +/* This version of __vlan_get_protocol() also pulls mac header in skb->head */ +static inline __be16 vlan_get_protocol_and_depth(struct sk_buff *skb, + __be16 type, int *depth) +{ + int maclen; + + type = __vlan_get_protocol(skb, type, &maclen); + + if (type) { + if (!pskb_may_pull(skb, maclen)) + type = 0; + else if (depth) + *depth = maclen; + } + return type; +} + /* A getter for the SKB protocol field which will handle VLAN tags consistently * whether VLAN acceleration is enabled or not. */ diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index f5f3ee57bc70..607c3a89a647 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -22,6 +22,7 @@ #include <linux/platform_data/st_sensors_pdata.h> #define LSM9DS0_IMU_DEV_NAME "lsm9ds0" +#define LSM303D_IMU_DEV_NAME "lsm303d" /* * Buffer size max case: 2bytes per channel, 3 channels in total + diff --git a/include/linux/iio/iio-gts-helper.h b/include/linux/iio/iio-gts-helper.h index dd64e544a3da..9cb6c80dea71 100644 --- a/include/linux/iio/iio-gts-helper.h +++ b/include/linux/iio/iio-gts-helper.h @@ -135,7 +135,7 @@ static inline int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel) /** * iio_gts_find_sel_by_int_time - find selector matching integration time * @gts: Gain time scale descriptor - * @gain: HW-gain for which matching selector is searched for + * @time: Integration time for which matching selector is searched for * * Return: a selector matching given integration time or -EINVAL if * selector was not found. diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 81413cd3a3e7..202e55b0a28b 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -221,6 +221,9 @@ struct iio_event_spec { * @extend_name: Allows labeling of channel attributes with an * informative name. Note this has no effect codes etc, * unlike modifiers. + * This field is deprecated in favour of providing + * iio_info->read_label() to override the label, which + * unlike @extend_name does not affect sysfs filenames. * @datasheet_name: A name used in in-kernel mapping of channels. It should * correspond to the first name that the channel is referred * to by in the datasheet (e.g. IND), or the nearest @@ -722,7 +725,7 @@ static inline void *iio_device_get_drvdata(const struct iio_dev *indio_dev) * must not share cachelines with the rest of the structure, thus making * them safe for use with non-coherent DMA. */ -#define IIO_DMA_MINALIGN ARCH_KMALLOC_MINALIGN +#define IIO_DMA_MINALIGN ARCH_DMA_MINALIGN struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv); /* The information at the returned address is guaranteed to be cacheline aligned */ diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index 51f52c5c6092..bce3b1788199 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -171,6 +171,7 @@ void iio_trigger_free(struct iio_trigger *trig); */ bool iio_trigger_using_own(struct iio_dev *indio_dev); +int iio_validate_own_trigger(struct iio_dev *idev, struct iio_trigger *trig); int iio_trigger_validate_own_device(struct iio_trigger *trig, struct iio_dev *indio_dev); diff --git a/include/linux/init.h b/include/linux/init.h index c5fe6d26f5b1..266c3e1640d4 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -152,6 +152,23 @@ extern unsigned int reset_devices; void setup_arch(char **); void prepare_namespace(void); void __init init_rootfs(void); + +void init_IRQ(void); +void time_init(void); +void poking_init(void); +void pgtable_cache_init(void); + +extern initcall_entry_t __initcall_start[]; +extern initcall_entry_t __initcall0_start[]; +extern initcall_entry_t __initcall1_start[]; +extern initcall_entry_t __initcall2_start[]; +extern initcall_entry_t __initcall3_start[]; +extern initcall_entry_t __initcall4_start[]; +extern initcall_entry_t __initcall5_start[]; +extern initcall_entry_t __initcall6_start[]; +extern initcall_entry_t __initcall7_start[]; +extern initcall_entry_t __initcall_end[]; + extern struct file_system_type rootfs_fs_type; #if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) @@ -309,6 +326,8 @@ struct obs_kernel_param { int early; }; +extern const struct obs_kernel_param __setup_start[], __setup_end[]; + /* * Only for really core code. See moduleparam.h for the normal way. * diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h index 9f4b6f5b822f..e6936cb25047 100644 --- a/include/linux/intel_rapl.h +++ b/include/linux/intel_rapl.h @@ -14,6 +14,12 @@ #include <linux/powercap.h> #include <linux/cpuhotplug.h> +enum rapl_if_type { + RAPL_IF_MSR, /* RAPL I/F using MSR registers */ + RAPL_IF_MMIO, /* RAPL I/F using MMIO registers */ + RAPL_IF_TPMI, /* RAPL I/F using TPMI registers */ +}; + enum rapl_domain_type { RAPL_DOMAIN_PACKAGE, /* entire package/socket */ RAPL_DOMAIN_PP0, /* core power plane */ @@ -30,17 +36,23 @@ enum rapl_domain_reg_id { RAPL_DOMAIN_REG_POLICY, RAPL_DOMAIN_REG_INFO, RAPL_DOMAIN_REG_PL4, + RAPL_DOMAIN_REG_UNIT, + RAPL_DOMAIN_REG_PL2, RAPL_DOMAIN_REG_MAX, }; struct rapl_domain; enum rapl_primitives { - ENERGY_COUNTER, POWER_LIMIT1, POWER_LIMIT2, POWER_LIMIT4, + ENERGY_COUNTER, FW_LOCK, + FW_HIGH_LOCK, + PL1_LOCK, + PL2_LOCK, + PL4_LOCK, PL1_ENABLE, /* power limit 1, aka long term */ PL1_CLAMP, /* allow frequency to go below OS request */ @@ -74,12 +86,13 @@ struct rapl_domain_data { unsigned long timestamp; }; -#define NR_POWER_LIMITS (3) +#define NR_POWER_LIMITS (POWER_LIMIT4 + 1) + struct rapl_power_limit { struct powercap_zone_constraint *constraint; - int prim_id; /* primitive ID used to enable */ struct rapl_domain *domain; const char *name; + bool locked; u64 last_power_limit; }; @@ -96,7 +109,9 @@ struct rapl_domain { struct rapl_power_limit rpl[NR_POWER_LIMITS]; u64 attr_map; /* track capabilities */ unsigned int state; - unsigned int domain_energy_unit; + unsigned int power_unit; + unsigned int energy_unit; + unsigned int time_unit; struct rapl_package *rp; }; @@ -121,16 +136,20 @@ struct reg_action { * registers. * @write_raw: Callback for writing RAPL interface specific * registers. + * @defaults: internal pointer to interface default settings + * @rpi: internal pointer to interface primitive info */ struct rapl_if_priv { + enum rapl_if_type type; struct powercap_control_type *control_type; - struct rapl_domain *platform_rapl_domain; enum cpuhp_state pcap_rapl_online; u64 reg_unit; u64 regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; int limits[RAPL_DOMAIN_MAX]; - int (*read_raw)(int cpu, struct reg_action *ra); - int (*write_raw)(int cpu, struct reg_action *ra); + int (*read_raw)(int id, struct reg_action *ra); + int (*write_raw)(int id, struct reg_action *ra); + void *defaults; + void *rpi; }; /* maximum rapl package domain name: package-%d-die-%d */ @@ -140,9 +159,6 @@ struct rapl_package { unsigned int id; /* logical die id, equals physical 1-die systems */ unsigned int nr_domains; unsigned long domain_map; /* bit map of active domains */ - unsigned int power_unit; - unsigned int energy_unit; - unsigned int time_unit; struct rapl_domain *domains; /* array of domains, sized at runtime */ struct powercap_zone *power_zone; /* keep track of parent zone */ unsigned long power_limit_irq; /* keep track of package power limit @@ -156,8 +172,8 @@ struct rapl_package { struct rapl_if_priv *priv; }; -struct rapl_package *rapl_find_package_domain(int cpu, struct rapl_if_priv *priv); -struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv); +struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu); +struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu); void rapl_remove_package(struct rapl_package *rp); #endif /* __INTEL_RAPL_H__ */ diff --git a/include/linux/interconnect-clk.h b/include/linux/interconnect-clk.h new file mode 100644 index 000000000000..0cd80112bea5 --- /dev/null +++ b/include/linux/interconnect-clk.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2023, Linaro Ltd. + */ + +#ifndef __LINUX_INTERCONNECT_CLK_H +#define __LINUX_INTERCONNECT_CLK_H + +struct device; + +struct icc_clk_data { + struct clk *clk; + const char *name; +}; + +struct icc_provider *icc_clk_register(struct device *dev, + unsigned int first_id, + unsigned int num_clocks, + const struct icc_clk_data *data); +void icc_clk_unregister(struct icc_provider *provider); + +#endif diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h index 2b0e784ba771..97ac253df62c 100644 --- a/include/linux/interconnect.h +++ b/include/linux/interconnect.h @@ -40,8 +40,6 @@ struct icc_bulk_data { #if IS_ENABLED(CONFIG_INTERCONNECT) -struct icc_path *icc_get(struct device *dev, const int src_id, - const int dst_id); struct icc_path *of_icc_get(struct device *dev, const char *name); struct icc_path *devm_of_icc_get(struct device *dev, const char *name); int devm_of_icc_bulk_get(struct device *dev, int num_paths, struct icc_bulk_data *paths); @@ -61,12 +59,6 @@ void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths); #else -static inline struct icc_path *icc_get(struct device *dev, const int src_id, - const int dst_id) -{ - return NULL; -} - static inline struct icc_path *of_icc_get(struct device *dev, const char *name) { diff --git a/include/linux/io.h b/include/linux/io.h index 308f4f0cfb93..7304f2a69960 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -68,6 +68,11 @@ void *devm_memremap(struct device *dev, resource_size_t offset, size_t size, unsigned long flags); void devm_memunmap(struct device *dev, void *addr); +/* architectures can override this */ +pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr, + unsigned long size, pgprot_t prot); + + #ifdef CONFIG_PCI /* * The PCI specifications (Rev 3.0, 3.2.5 "Transaction Ordering and diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h index 3399d979ee1c..bb9c666bd584 100644 --- a/include/linux/io_uring.h +++ b/include/linux/io_uring.h @@ -36,18 +36,33 @@ struct io_uring_cmd { u8 pdu[32]; /* available inline for free use */ }; +static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe) +{ + return sqe->cmd; +} + #if defined(CONFIG_IO_URING) int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct iov_iter *iter, void *ioucmd); void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2, unsigned issue_flags); -void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, - void (*task_work_cb)(struct io_uring_cmd *, unsigned)); struct sock *io_uring_get_socket(struct file *file); void __io_uring_cancel(bool cancel_all); void __io_uring_free(struct task_struct *tsk); void io_uring_unreg_ringfd(void); const char *io_uring_get_opcode(u8 opcode); +void __io_uring_cmd_do_in_task(struct io_uring_cmd *ioucmd, + void (*task_work_cb)(struct io_uring_cmd *, unsigned), + unsigned flags); +/* users should follow semantics of IOU_F_TWQ_LAZY_WAKE */ +void io_uring_cmd_do_in_task_lazy(struct io_uring_cmd *ioucmd, + void (*task_work_cb)(struct io_uring_cmd *, unsigned)); + +static inline void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, + void (*task_work_cb)(struct io_uring_cmd *, unsigned)) +{ + __io_uring_cmd_do_in_task(ioucmd, task_work_cb, 0); +} static inline void io_uring_files_cancel(void) { @@ -66,11 +81,6 @@ static inline void io_uring_free(struct task_struct *tsk) if (tsk->io_uring) __io_uring_free(tsk); } - -static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe) -{ - return sqe->cmd; -} #else static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct iov_iter *iter, void *ioucmd) @@ -85,6 +95,10 @@ static inline void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, void (*task_work_cb)(struct io_uring_cmd *, unsigned)) { } +static inline void io_uring_cmd_do_in_task_lazy(struct io_uring_cmd *ioucmd, + void (*task_work_cb)(struct io_uring_cmd *, unsigned)) +{ +} static inline struct sock *io_uring_get_socket(struct file *file) { return NULL; diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 1b2a20a42413..f04ce513fadb 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -211,6 +211,16 @@ struct io_ring_ctx { unsigned int compat: 1; enum task_work_notify_mode notify_method; + + /* + * If IORING_SETUP_NO_MMAP is used, then the below holds + * the gup'ed pages for the two rings, and the sqes. + */ + unsigned short n_ring_pages; + unsigned short n_sqe_pages; + struct page **ring_pages; + struct page **sqe_pages; + struct io_rings *rings; struct task_struct *submitter_task; struct percpu_ref refs; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e8c9a7da1060..d31642596675 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -65,6 +65,7 @@ struct iommu_domain_geometry { #define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */ +#define IOMMU_DOMAIN_ALLOC_FLAGS ~__IOMMU_DOMAIN_DMA_FQ /* * This are the possible domain-types * @@ -127,6 +128,11 @@ enum iommu_cap { * this device. */ IOMMU_CAP_ENFORCE_CACHE_COHERENCY, + /* + * IOMMU driver does not issue TLB maintenance during .unmap, so can + * usefully support the non-strict DMA flush queue. + */ + IOMMU_CAP_DEFERRED_FLUSH, }; /* These are the possible reserved region types */ diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index 2c8860e406bd..19a7b00baff4 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h @@ -53,6 +53,7 @@ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ + cpu_relax(); \ } \ (cond) ? 0 : -ETIMEDOUT; \ }) @@ -73,6 +74,10 @@ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either * case, the last read value at @args is stored in @val. * + * This macro does not rely on timekeeping. Hence it is safe to call even when + * timekeeping is suspended, at the expense of an underestimation of wall clock + * time, which is rather minimal with a non-zero delay_us. + * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. */ @@ -80,21 +85,30 @@ delay_before_read, args...) \ ({ \ u64 __timeout_us = (timeout_us); \ + s64 __left_ns = __timeout_us * NSEC_PER_USEC; \ unsigned long __delay_us = (delay_us); \ - ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ - if (delay_before_read && __delay_us) \ + u64 __delay_ns = __delay_us * NSEC_PER_USEC; \ + if (delay_before_read && __delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ for (;;) { \ (val) = op(args); \ if (cond) \ break; \ - if (__timeout_us && \ - ktime_compare(ktime_get(), __timeout) > 0) { \ + if (__timeout_us && __left_ns < 0) { \ (val) = op(args); \ break; \ } \ - if (__delay_us) \ + if (__delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ + cpu_relax(); \ + if (__timeout_us) \ + __left_ns--; \ } \ (cond) ? 0 : -ETIMEDOUT; \ }) diff --git a/include/linux/irq.h b/include/linux/irq.h index b1b28affb32a..d8a6fdce9373 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -223,32 +223,35 @@ struct irq_data { * irq_chip::irq_set_affinity() when deactivated. * IRQD_IRQ_ENABLED_ON_SUSPEND - Interrupt is enabled on suspend by irq pm if * irqchip have flag IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND set. + * IRQD_RESEND_WHEN_IN_PROGRESS - Interrupt may fire when already in progress in which + * case it must be resent at the next available opportunity. */ enum { IRQD_TRIGGER_MASK = 0xf, - IRQD_SETAFFINITY_PENDING = (1 << 8), - IRQD_ACTIVATED = (1 << 9), - IRQD_NO_BALANCING = (1 << 10), - IRQD_PER_CPU = (1 << 11), - IRQD_AFFINITY_SET = (1 << 12), - IRQD_LEVEL = (1 << 13), - IRQD_WAKEUP_STATE = (1 << 14), - IRQD_MOVE_PCNTXT = (1 << 15), - IRQD_IRQ_DISABLED = (1 << 16), - IRQD_IRQ_MASKED = (1 << 17), - IRQD_IRQ_INPROGRESS = (1 << 18), - IRQD_WAKEUP_ARMED = (1 << 19), - IRQD_FORWARDED_TO_VCPU = (1 << 20), - IRQD_AFFINITY_MANAGED = (1 << 21), - IRQD_IRQ_STARTED = (1 << 22), - IRQD_MANAGED_SHUTDOWN = (1 << 23), - IRQD_SINGLE_TARGET = (1 << 24), - IRQD_DEFAULT_TRIGGER_SET = (1 << 25), - IRQD_CAN_RESERVE = (1 << 26), - IRQD_MSI_NOMASK_QUIRK = (1 << 27), - IRQD_HANDLE_ENFORCE_IRQCTX = (1 << 28), - IRQD_AFFINITY_ON_ACTIVATE = (1 << 29), - IRQD_IRQ_ENABLED_ON_SUSPEND = (1 << 30), + IRQD_SETAFFINITY_PENDING = BIT(8), + IRQD_ACTIVATED = BIT(9), + IRQD_NO_BALANCING = BIT(10), + IRQD_PER_CPU = BIT(11), + IRQD_AFFINITY_SET = BIT(12), + IRQD_LEVEL = BIT(13), + IRQD_WAKEUP_STATE = BIT(14), + IRQD_MOVE_PCNTXT = BIT(15), + IRQD_IRQ_DISABLED = BIT(16), + IRQD_IRQ_MASKED = BIT(17), + IRQD_IRQ_INPROGRESS = BIT(18), + IRQD_WAKEUP_ARMED = BIT(19), + IRQD_FORWARDED_TO_VCPU = BIT(20), + IRQD_AFFINITY_MANAGED = BIT(21), + IRQD_IRQ_STARTED = BIT(22), + IRQD_MANAGED_SHUTDOWN = BIT(23), + IRQD_SINGLE_TARGET = BIT(24), + IRQD_DEFAULT_TRIGGER_SET = BIT(25), + IRQD_CAN_RESERVE = BIT(26), + IRQD_MSI_NOMASK_QUIRK = BIT(27), + IRQD_HANDLE_ENFORCE_IRQCTX = BIT(28), + IRQD_AFFINITY_ON_ACTIVATE = BIT(29), + IRQD_IRQ_ENABLED_ON_SUSPEND = BIT(30), + IRQD_RESEND_WHEN_IN_PROGRESS = BIT(31), }; #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) @@ -448,6 +451,16 @@ static inline bool irqd_affinity_on_activate(struct irq_data *d) return __irqd_to_state(d) & IRQD_AFFINITY_ON_ACTIVATE; } +static inline void irqd_set_resend_when_in_progress(struct irq_data *d) +{ + __irqd_to_state(d) |= IRQD_RESEND_WHEN_IN_PROGRESS; +} + +static inline bool irqd_needs_resend_when_in_progress(struct irq_data *d) +{ + return __irqd_to_state(d) & IRQD_RESEND_WHEN_IN_PROGRESS; +} + #undef __irqd_to_state static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) diff --git a/include/linux/irqchip/mmp.h b/include/linux/irqchip/mmp.h deleted file mode 100644 index aa1813749a4f..000000000000 --- a/include/linux/irqchip/mmp.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IRQCHIP_MMP_H -#define __IRQCHIP_MMP_H - -extern struct irq_chip icu_irq_chip; - -extern void icu_init_irq(void); -extern void mmp2_init_icu(void); - -#endif /* __IRQCHIP_MMP_H */ diff --git a/include/linux/irqchip/mxs.h b/include/linux/irqchip/mxs.h deleted file mode 100644 index 4f447e3f0f3a..000000000000 --- a/include/linux/irqchip/mxs.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2013 Freescale Semiconductor, Inc. - */ - -#ifndef __LINUX_IRQCHIP_MXS_H -#define __LINUX_IRQCHIP_MXS_H - -extern void icoll_handle_irq(struct pt_regs *); - -#endif diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 844a8e30e6de..d9451d456a73 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -102,6 +102,9 @@ struct irq_desc { int parent_irq; struct module *owner; const char *name; +#ifdef CONFIG_HARDIRQS_SW_RESEND + struct hlist_node resend_node; +#endif } ____cacheline_internodealigned_in_smp; #ifdef CONFIG_SPARSE_IRQ diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 5ec0fa71399e..2b665c32f5fe 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -13,6 +13,7 @@ #define _LINUX_TRACE_IRQFLAGS_H #include <linux/typecheck.h> +#include <linux/cleanup.h> #include <asm/irqflags.h> #include <asm/percpu.h> @@ -267,4 +268,10 @@ extern void warn_bogus_irq_restore(void); #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) +DEFINE_LOCK_GUARD_0(irq, local_irq_disable(), local_irq_enable()) +DEFINE_LOCK_GUARD_0(irqsave, + local_irq_save(_T->flags), + local_irq_restore(_T->flags), + unsigned long flags) + #endif diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h index 790e7fcfc1a6..e2742748104d 100644 --- a/include/linux/iscsi_ibft.h +++ b/include/linux/iscsi_ibft.h @@ -21,12 +21,20 @@ */ extern phys_addr_t ibft_phys_addr; +#ifdef CONFIG_ISCSI_IBFT_FIND + /* * Routine used to find and reserve the iSCSI Boot Format Table. The * physical address is set in the ibft_phys_addr variable. */ -#ifdef CONFIG_ISCSI_IBFT_FIND void reserve_ibft_region(void); + +/* + * Physical bounds to search for the iSCSI Boot Format Table. + */ +#define IBFT_START 0x80000 /* 512kB */ +#define IBFT_END 0x100000 /* 1MB */ + #else static inline void reserve_ibft_region(void) {} #endif diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index f619bae1dcc5..d860499e15e4 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -265,8 +265,10 @@ typedef struct journal_superblock_s __u8 s_padding2[3]; /* 0x0054 */ __be32 s_num_fc_blks; /* Number of fast commit blocks */ -/* 0x0058 */ - __u32 s_padding[41]; + __be32 s_head; /* blocknr of head of log, only uptodate + * while the filesystem is clean */ +/* 0x005C */ + __u32 s_padding[40]; __be32 s_checksum; /* crc32c(superblock) */ /* 0x0100 */ @@ -274,17 +276,6 @@ typedef struct journal_superblock_s /* 0x0400 */ } journal_superblock_t; -/* Use the jbd2_{has,set,clear}_feature_* helpers; these will be removed */ -#define JBD2_HAS_COMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask)))) -#define JBD2_HAS_RO_COMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask)))) -#define JBD2_HAS_INCOMPAT_FEATURE(j,mask) \ - ((j)->j_format_version >= 2 && \ - ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) - #define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 #define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 @@ -804,11 +795,6 @@ struct journal_s journal_superblock_t *j_superblock; /** - * @j_format_version: Version of the superblock format. - */ - int j_format_version; - - /** * @j_state_lock: Protect the various scalars in the journal. */ rwlock_t j_state_lock; @@ -1324,11 +1310,22 @@ struct journal_s rwsem_release(&j->j_trans_commit_map, _THIS_IP_); \ } while (0) +/* + * We can support any known requested features iff the + * superblock is not in version 1. Otherwise we fail to support any + * extended sb features. + */ +static inline bool jbd2_format_support_feature(journal_t *j) +{ + return j->j_superblock->s_header.h_blocktype != + cpu_to_be32(JBD2_SUPERBLOCK_V1); +} + /* journal feature predicate functions */ #define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \ static inline bool jbd2_has_feature_##name(journal_t *j) \ { \ - return ((j)->j_format_version >= 2 && \ + return (jbd2_format_support_feature(j) && \ ((j)->j_superblock->s_feature_compat & \ cpu_to_be32(JBD2_FEATURE_COMPAT_##flagname)) != 0); \ } \ @@ -1346,7 +1343,7 @@ static inline void jbd2_clear_feature_##name(journal_t *j) \ #define JBD2_FEATURE_RO_COMPAT_FUNCS(name, flagname) \ static inline bool jbd2_has_feature_##name(journal_t *j) \ { \ - return ((j)->j_format_version >= 2 && \ + return (jbd2_format_support_feature(j) && \ ((j)->j_superblock->s_feature_ro_compat & \ cpu_to_be32(JBD2_FEATURE_RO_COMPAT_##flagname)) != 0); \ } \ @@ -1364,7 +1361,7 @@ static inline void jbd2_clear_feature_##name(journal_t *j) \ #define JBD2_FEATURE_INCOMPAT_FUNCS(name, flagname) \ static inline bool jbd2_has_feature_##name(journal_t *j) \ { \ - return ((j)->j_format_version >= 2 && \ + return (jbd2_format_support_feature(j) && \ ((j)->j_superblock->s_feature_incompat & \ cpu_to_be32(JBD2_FEATURE_INCOMPAT_##flagname)) != 0); \ } \ @@ -1400,6 +1397,9 @@ JBD2_FEATURE_INCOMPAT_FUNCS(fast_commit, FAST_COMMIT) #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file * data write error in ordered * mode */ +#define JBD2_CYCLE_RECORD 0x080 /* Journal cycled record log on + * clean and empty filesystem + * logging area */ #define JBD2_FAST_COMMIT_ONGOING 0x100 /* Fast commit is ongoing */ #define JBD2_FULL_COMMIT_ONGOING 0x200 /* Full commit is ongoing */ #define JBD2_JOURNAL_FLUSH_DISCARD 0x0001 diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 4e968ebadce6..f0a949b7c973 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -257,7 +257,7 @@ extern enum jump_label_type jump_label_init_type(struct jump_entry *entry); static __always_inline int static_key_count(struct static_key *key) { - return arch_atomic_read(&key->enabled); + return raw_atomic_read(&key->enabled); } static __always_inline void jump_label_init(void) diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index fe3c9993b5bf..c3f075e8f60c 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -65,6 +65,9 @@ static inline void *dereference_symbol_descriptor(void *ptr) return ptr; } +/* How and when do we show kallsyms values? */ +extern bool kallsyms_show_value(const struct cred *cred); + #ifdef CONFIG_KALLSYMS unsigned long kallsyms_sym_address(int idx); int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long), @@ -93,10 +96,6 @@ extern int sprint_backtrace(char *buffer, unsigned long address); extern int sprint_backtrace_build_id(char *buffer, unsigned long address); int lookup_symbol_name(unsigned long addr, char *symname); -int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); - -/* How and when do we show kallsyms values? */ -extern bool kallsyms_show_value(const struct cred *cred); #else /* !CONFIG_KALLSYMS */ @@ -155,16 +154,6 @@ static inline int lookup_symbol_name(unsigned long addr, char *symname) return -ERANGE; } -static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name) -{ - return -ERANGE; -} - -static inline bool kallsyms_show_value(const struct cred *cred) -{ - return false; -} - static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long), void *data) { diff --git a/include/linux/kasan.h b/include/linux/kasan.h index f7ef70661ce2..819b6bc8ac08 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -343,7 +343,7 @@ static inline void *kasan_reset_tag(const void *addr) * @is_write: whether the bad access is a write or a read * @ip: instruction pointer for the accessibility check or the bad access itself */ -bool kasan_report(unsigned long addr, size_t size, +bool kasan_report(const void *addr, size_t size, bool is_write, unsigned long ip); #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ diff --git a/include/linux/kcov.h b/include/linux/kcov.h index ee04256f28af..b851ba415e03 100644 --- a/include/linux/kcov.h +++ b/include/linux/kcov.h @@ -72,6 +72,23 @@ static inline void kcov_remote_stop_softirq(void) kcov_remote_stop(); } +#ifdef CONFIG_64BIT +typedef unsigned long kcov_u64; +#else +typedef unsigned long long kcov_u64; +#endif + +void __sanitizer_cov_trace_pc(void); +void __sanitizer_cov_trace_cmp1(u8 arg1, u8 arg2); +void __sanitizer_cov_trace_cmp2(u16 arg1, u16 arg2); +void __sanitizer_cov_trace_cmp4(u32 arg1, u32 arg2); +void __sanitizer_cov_trace_cmp8(kcov_u64 arg1, kcov_u64 arg2); +void __sanitizer_cov_trace_const_cmp1(u8 arg1, u8 arg2); +void __sanitizer_cov_trace_const_cmp2(u16 arg1, u16 arg2); +void __sanitizer_cov_trace_const_cmp4(u32 arg1, u32 arg2); +void __sanitizer_cov_trace_const_cmp8(kcov_u64 arg1, kcov_u64 arg2); +void __sanitizer_cov_trace_switch(kcov_u64 val, void *cases); + #else static inline void kcov_task_init(struct task_struct *t) {} diff --git a/include/linux/kdb.h b/include/linux/kdb.h index 07dfb6a20a1c..f6c2ddb16b95 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -196,6 +196,8 @@ int kdb_process_cpu(const struct task_struct *p) return cpu; } +extern void kdb_send_sig(struct task_struct *p, int sig); + #ifdef CONFIG_KALLSYMS extern const char *kdb_walk_kallsyms(loff_t *pos); #else /* ! CONFIG_KALLSYMS */ diff --git a/include/linux/key.h b/include/linux/key.h index 8dc7f7c3088b..938d7ecfb495 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -490,9 +490,6 @@ do { \ rcu_assign_pointer((KEY)->payload.rcu_data0, (PAYLOAD)); \ } while (0) -#ifdef CONFIG_SYSCTL -extern struct ctl_table key_sysctls[]; -#endif /* * the userspace interface */ diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 258cdde8d356..76e891ee9e37 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -365,5 +365,6 @@ extern void kgdb_free_init_mem(void); #define dbg_late_init() static inline void kgdb_panic(const char *msg) {} static inline void kgdb_free_init_mem(void) { } +static inline int kgdb_nmicallback(int cpu, void *regs) { return 1; } #endif /* ! CONFIG_KGDB */ #endif /* _KGDB_H_ */ diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 30e5bec81d2b..f1f95a71a4bc 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -89,6 +89,7 @@ int kthread_stop(struct task_struct *k); bool kthread_should_stop(void); bool kthread_should_park(void); bool __kthread_should_park(struct task_struct *k); +bool kthread_should_stop_or_park(void); bool kthread_freezable_should_stop(bool *was_frozen); void *kthread_func(struct task_struct *k); void *kthread_data(struct task_struct *k); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0e571e973bc2..9d3ac7720da9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -849,7 +849,7 @@ static inline void kvm_vm_bugged(struct kvm *kvm) #define KVM_BUG(cond, kvm, fmt...) \ ({ \ - int __ret = (cond); \ + bool __ret = !!(cond); \ \ if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt)) \ kvm_vm_bugged(kvm); \ @@ -858,7 +858,7 @@ static inline void kvm_vm_bugged(struct kvm *kvm) #define KVM_BUG_ON(cond, kvm) \ ({ \ - int __ret = (cond); \ + bool __ret = !!(cond); \ \ if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged)) \ kvm_vm_bugged(kvm); \ @@ -991,6 +991,8 @@ static inline bool kvm_memslots_empty(struct kvm_memslots *slots) return RB_EMPTY_ROOT(&slots->gfn_tree); } +bool kvm_are_all_memslots_empty(struct kvm *kvm); + #define kvm_for_each_memslot(memslot, bkt, slots) \ hash_for_each(slots->id_hash, bkt, memslot, id_node[slots->node_idx]) \ if (WARN_ON_ONCE(!memslot->npages)) { \ @@ -2237,9 +2239,6 @@ static inline long kvm_arch_vcpu_async_ioctl(struct file *filp, } #endif /* CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL */ -void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, - unsigned long start, unsigned long end); - void kvm_arch_guest_memory_reclaimed(struct kvm *kvm); #ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE diff --git a/include/linux/leds.h b/include/linux/leds.h index c39bbf17a25b..7d428100b42b 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -124,6 +124,10 @@ struct led_classdev { #define LED_BLINK_INVERT 3 #define LED_BLINK_BRIGHTNESS_CHANGE 4 #define LED_BLINK_DISABLE 5 + /* Brightness off also disables hw-blinking so it is a separate action */ +#define LED_SET_BRIGHTNESS_OFF 6 +#define LED_SET_BRIGHTNESS 7 +#define LED_SET_BLINK 8 /* Set LED brightness level * Must not sleep. Use brightness_set_blocking for drivers @@ -147,6 +151,10 @@ struct led_classdev { * match the values specified exactly. * Deactivate blinking again when the brightness is set to LED_OFF * via the brightness_set() callback. + * For led_blink_set_nosleep() the LED core assumes that blink_set + * implementations, of drivers which do not use brightness_set_blocking, + * will not sleep. Therefor if brightness_set_blocking is not set + * this function must not sleep! */ int (*blink_set)(struct led_classdev *led_cdev, unsigned long *delay_on, @@ -170,6 +178,8 @@ struct led_classdev { struct work_struct set_brightness_work; int delayed_set_value; + unsigned long delayed_delay_on; + unsigned long delayed_delay_off; #ifdef CONFIG_LEDS_TRIGGERS /* Protects the trigger data below */ @@ -183,6 +193,49 @@ struct led_classdev { /* LEDs that have private triggers have this set */ struct led_hw_trigger_type *trigger_type; + + /* Unique trigger name supported by LED set in hw control mode */ + const char *hw_control_trigger; + /* + * Check if the LED driver supports the requested mode provided by the + * defined supported trigger to setup the LED to hw control mode. + * + * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not + * supported and software fallback needs to be used. + * Return a negative error number on any other case for check fail due + * to various reason like device not ready or timeouts. + */ + int (*hw_control_is_supported)(struct led_classdev *led_cdev, + unsigned long flags); + /* + * Activate hardware control, LED driver will use the provided flags + * from the supported trigger and setup the LED to be driven by hardware + * following the requested mode from the trigger flags. + * Deactivate hardware blink control by setting brightness to LED_OFF via + * the brightness_set() callback. + * + * Return 0 on success, a negative error number on flags apply fail. + */ + int (*hw_control_set)(struct led_classdev *led_cdev, + unsigned long flags); + /* + * Get from the LED driver the current mode that the LED is set in hw + * control mode and put them in flags. + * Trigger can use this to get the initial state of a LED already set in + * hardware blink control. + * + * Return 0 on success, a negative error number on failing parsing the + * initial mode. Error from this function is NOT FATAL as the device + * may be in a not supported initial state by the attached LED trigger. + */ + int (*hw_control_get)(struct led_classdev *led_cdev, + unsigned long *flags); + /* + * Get the device this LED blinks in response to. + * e.g. for a PHY LED, it is the network device. If the LED is + * not yet associated to a device, return NULL. + */ + struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); #endif #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED @@ -272,12 +325,27 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev, * software blinking if there is no hardware blinking or if * the LED refuses the passed values. * + * This function may sleep! + * * Note that if software blinking is active, simply calling * led_cdev->brightness_set() will not stop the blinking, * use led_set_brightness() instead. */ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off); + +/** + * led_blink_set_nosleep - set blinking, guaranteed to not sleep + * @led_cdev: the LED to start blinking + * @delay_on: the time it should be on (in ms) + * @delay_off: the time it should ble off (in ms) + * + * This function makes the LED blink and is guaranteed to not sleep. Otherwise + * this is the same as led_blink_set(), see led_blink_set() for details. + */ +void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on, + unsigned long delay_off); + /** * led_blink_set_oneshot - do a oneshot software blink * @led_cdev: the LED to start blinking @@ -291,6 +359,8 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, * * If invert is set, led blinks for delay_off first, then for * delay_on and leave the led on after the on-off cycle. + * + * This function is guaranteed not to sleep. */ void led_blink_set_oneshot(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off, @@ -433,11 +503,11 @@ void led_trigger_register_simple(const char *name, struct led_trigger **trigger); void led_trigger_unregister_simple(struct led_trigger *trigger); void led_trigger_event(struct led_trigger *trigger, enum led_brightness event); -void led_trigger_blink(struct led_trigger *trigger, unsigned long *delay_on, - unsigned long *delay_off); +void led_trigger_blink(struct led_trigger *trigger, unsigned long delay_on, + unsigned long delay_off); void led_trigger_blink_oneshot(struct led_trigger *trigger, - unsigned long *delay_on, - unsigned long *delay_off, + unsigned long delay_on, + unsigned long delay_off, int invert); void led_trigger_set_default(struct led_classdev *led_cdev); int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger); @@ -487,11 +557,11 @@ static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} static inline void led_trigger_event(struct led_trigger *trigger, enum led_brightness event) {} static inline void led_trigger_blink(struct led_trigger *trigger, - unsigned long *delay_on, - unsigned long *delay_off) {} + unsigned long delay_on, + unsigned long delay_off) {} static inline void led_trigger_blink_oneshot(struct led_trigger *trigger, - unsigned long *delay_on, - unsigned long *delay_off, + unsigned long delay_on, + unsigned long delay_off, int invert) {} static inline void led_trigger_set_default(struct led_classdev *led_cdev) {} static inline int led_trigger_set(struct led_classdev *led_cdev, @@ -509,6 +579,21 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) #endif /* CONFIG_LEDS_TRIGGERS */ +/* Trigger specific enum */ +enum led_trigger_netdev_modes { + TRIGGER_NETDEV_LINK = 0, + TRIGGER_NETDEV_LINK_10, + TRIGGER_NETDEV_LINK_100, + TRIGGER_NETDEV_LINK_1000, + TRIGGER_NETDEV_HALF_DUPLEX, + TRIGGER_NETDEV_FULL_DUPLEX, + TRIGGER_NETDEV_TX, + TRIGGER_NETDEV_RX, + + /* Keep last */ + __TRIGGER_NETDEV_MAX, +}; + /* Trigger specific functions */ #ifdef CONFIG_LEDS_TRIGGER_DISK void ledtrig_disk_activity(bool write); diff --git a/include/linux/libata.h b/include/linux/libata.h index 311cd93377c7..820f7a3a2749 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -94,17 +94,19 @@ enum { ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ ATA_DFLAG_NCQ_SEND_RECV = (1 << 11), /* device supports NCQ SEND and RECV */ ATA_DFLAG_NCQ_PRIO = (1 << 12), /* device supports NCQ priority */ - ATA_DFLAG_CFG_MASK = (1 << 13) - 1, - - ATA_DFLAG_PIO = (1 << 13), /* device limited to PIO mode */ - ATA_DFLAG_NCQ_OFF = (1 << 14), /* device limited to non-NCQ mode */ - ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ - ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ - ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ - ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ - ATA_DFLAG_INIT_MASK = (1 << 19) - 1, - - ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 19), /* Priority cmds sent to dev */ + ATA_DFLAG_CDL = (1 << 13), /* supports cmd duration limits */ + ATA_DFLAG_CFG_MASK = (1 << 14) - 1, + + ATA_DFLAG_PIO = (1 << 14), /* device limited to PIO mode */ + ATA_DFLAG_NCQ_OFF = (1 << 15), /* device limited to non-NCQ mode */ + ATA_DFLAG_SLEEPING = (1 << 16), /* device is sleeping */ + ATA_DFLAG_DUBIOUS_XFER = (1 << 17), /* data transfer not verified */ + ATA_DFLAG_NO_UNLOAD = (1 << 18), /* device doesn't support unload */ + ATA_DFLAG_UNLOCK_HPA = (1 << 19), /* unlock HPA */ + ATA_DFLAG_INIT_MASK = (1 << 20) - 1, + + ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 20), /* Priority cmds sent to dev */ + ATA_DFLAG_CDL_ENABLED = (1 << 21), /* cmd duration limits is enabled */ ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACHED = (1 << 25), ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ @@ -115,7 +117,8 @@ enum { ATA_DFLAG_FEATURES_MASK = (ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \ ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \ - ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA), + ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA | \ + ATA_DFLAG_CDL), ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -206,10 +209,12 @@ enum { ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ ATA_QCFLAG_QUIET = (1 << 6), /* don't report device error */ ATA_QCFLAG_RETRY = (1 << 7), /* retry after failure */ + ATA_QCFLAG_HAS_CDL = (1 << 8), /* qc has CDL a descriptor set */ ATA_QCFLAG_EH = (1 << 16), /* cmd aborted and owned by EH */ ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */ ATA_QCFLAG_EH_SCHEDULED = (1 << 18), /* EH scheduled (obsolete) */ + ATA_QCFLAG_EH_SUCCESS_CMD = (1 << 19), /* EH should fetch sense for this successful cmd */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */ @@ -308,8 +313,10 @@ enum { ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_ENABLE_LINK = (1 << 3), ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ + ATA_EH_GET_SUCCESS_SENSE = (1 << 6), /* Get sense data for successful cmd */ - ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK, + ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK | + ATA_EH_GET_SUCCESS_SENSE, ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | ATA_EH_ENABLE_LINK, @@ -709,6 +716,9 @@ struct ata_device { /* Concurrent positioning ranges */ struct ata_cpr_log *cpr_log; + /* Command Duration Limits log support */ + u8 cdl[ATA_LOG_CDL_SIZE]; + /* error history */ int spdn_cnt; /* ering is CLEAR_END, read comment above CLEAR_END */ @@ -836,7 +846,7 @@ struct ata_port { struct mutex scsi_scan_mutex; struct delayed_work hotplug_task; - struct work_struct scsi_rescan_task; + struct delayed_work scsi_rescan_task; unsigned int hsm_task_state; @@ -860,6 +870,7 @@ struct ata_port { struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ #endif /* owned by EH */ + u8 *ncq_sense_buf; u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; }; @@ -1144,8 +1155,8 @@ extern int ata_scsi_slave_config(struct scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth); -extern int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev, - struct scsi_device *sdev, int queue_depth); +extern int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, + int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); @@ -1178,6 +1189,7 @@ extern int sata_link_hardreset(struct ata_link *link, bool *online, int (*check_ready)(struct ata_link *)); extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); +extern int ata_eh_read_sense_success_ncq_log(struct ata_link *link); extern void ata_eh_analyze_ncq_error(struct ata_link *link); #else static inline const unsigned long * @@ -1215,6 +1227,10 @@ static inline int sata_link_resume(struct ata_link *link, { return -EOPNOTSUPP; } +static inline int ata_eh_read_sense_success_ncq_log(struct ata_link *link) +{ + return -EOPNOTSUPP; +} static inline void ata_eh_analyze_ncq_error(struct ata_link *link) { } #endif extern int sata_link_debounce(struct ata_link *link, @@ -1276,7 +1292,7 @@ extern int ata_pci_device_resume(struct pci_dev *pdev); struct platform_device; -extern int ata_platform_remove_one(struct platform_device *pdev); +extern void ata_platform_remove_one(struct platform_device *pdev); /* * ACPI - drivers/ata/libata-acpi.c diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 53f7e4d0f4b7..9ca9ce4e6e64 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h @@ -8,44 +8,59 @@ */ #include <linux/bitops.h> +#include <linux/interrupt.h> #include <linux/mutex.h> #include <linux/types.h> #include <linux/wait.h> -#define PS2_CMD_SETSCALE11 0x00e6 -#define PS2_CMD_SETRES 0x10e8 -#define PS2_CMD_GETID 0x02f2 -#define PS2_CMD_RESET_BAT 0x02ff +struct ps2dev; -#define PS2_RET_BAT 0xaa -#define PS2_RET_ID 0x00 -#define PS2_RET_ACK 0xfa -#define PS2_RET_NAK 0xfe -#define PS2_RET_ERR 0xfc +/** + * enum ps2_disposition - indicates how received byte should be handled + * @PS2_PROCESS: pass to the main protocol handler, process normally + * @PS2_IGNORE: skip the byte + * @PS2_ERROR: do not process the byte, abort command in progress + */ +enum ps2_disposition { + PS2_PROCESS, + PS2_IGNORE, + PS2_ERROR, +}; -#define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ -#define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ -#define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ -#define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ -#define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ -#define PS2_FLAG_ACK_CMD BIT(5) /* Waiting to ACK the command (first) byte */ +typedef enum ps2_disposition (*ps2_pre_receive_handler_t)(struct ps2dev *, u8, + unsigned int); +typedef void (*ps2_receive_handler_t)(struct ps2dev *, u8); +/** + * struct ps2dev - represents a device using PS/2 protocol + * @serio: a serio port used by the PS/2 device + * @cmd_mutex: a mutex ensuring that only one command is executing at a time + * @wait: a waitqueue used to signal completion from the serio interrupt handler + * @flags: various internal flags indicating stages of PS/2 command execution + * @cmdbuf: buffer holding command response + * @cmdcnt: outstanding number of bytes of the command response + * @nak: a byte transmitted by the device when it refuses command + * @pre_receive_handler: checks communication errors and returns disposition + * (&enum ps2_disposition) of the received data byte + * @receive_handler: main handler of particular PS/2 protocol, such as keyboard + * or mouse protocol + */ struct ps2dev { struct serio *serio; - - /* Ensures that only one command is executing at a time */ struct mutex cmd_mutex; - - /* Used to signal completion from interrupt handler */ wait_queue_head_t wait; - unsigned long flags; u8 cmdbuf[8]; u8 cmdcnt; u8 nak; + + ps2_pre_receive_handler_t pre_receive_handler; + ps2_receive_handler_t receive_handler; }; -void ps2_init(struct ps2dev *ps2dev, struct serio *serio); +void ps2_init(struct ps2dev *ps2dev, struct serio *serio, + ps2_pre_receive_handler_t pre_receive_handler, + ps2_receive_handler_t receive_handler); int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout); void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout); void ps2_begin_command(struct ps2dev *ps2dev); @@ -53,9 +68,8 @@ void ps2_end_command(struct ps2dev *ps2dev); int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); int ps2_sliced_command(struct ps2dev *ps2dev, u8 command); -bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data); -bool ps2_handle_response(struct ps2dev *ps2dev, u8 data); -void ps2_cmd_aborted(struct ps2dev *ps2dev); bool ps2_is_keyboard_id(u8 id); +irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags); + #endif /* _LIBPS2_H */ diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index 3bc9f7410e21..c53c81242e72 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -20,6 +20,7 @@ /* Dummy declarations */ struct svc_rqst; struct rpc_task; +struct rpc_clnt; /* * This is the set of functions for lockd->nfsd communication @@ -56,6 +57,7 @@ struct nlmclnt_initdata { extern struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init); extern void nlmclnt_done(struct nlm_host *host); +extern struct rpc_clnt *nlmclnt_rpc_clnt(struct nlm_host *host); /* * NLM client operations provide a means to modify RPC processing of NLM diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index b32256e9e944..310f85903c91 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -344,6 +344,16 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); #define lockdep_repin_lock(l,c) lock_repin_lock(&(l)->dep_map, (c)) #define lockdep_unpin_lock(l,c) lock_unpin_lock(&(l)->dep_map, (c)) +/* + * Must use lock_map_aquire_try() with override maps to avoid + * lockdep thinking they participate in the block chain. + */ +#define DEFINE_WAIT_OVERRIDE_MAP(_name, _wait_type) \ + struct lockdep_map _name = { \ + .name = #_name "-wait-type-override", \ + .wait_type_inner = _wait_type, \ + .lock_type = LD_LOCK_WAIT_OVERRIDE, } + #else /* !CONFIG_LOCKDEP */ static inline void lockdep_init_task(struct task_struct *task) @@ -432,8 +442,19 @@ extern int lockdep_is_held(const void *); #define lockdep_repin_lock(l, c) do { (void)(l); (void)(c); } while (0) #define lockdep_unpin_lock(l, c) do { (void)(l); (void)(c); } while (0) +#define DEFINE_WAIT_OVERRIDE_MAP(_name, _wait_type) \ + struct lockdep_map __maybe_unused _name = {} + #endif /* !LOCKDEP */ +#ifdef CONFIG_PROVE_LOCKING +void lockdep_set_lock_cmp_fn(struct lockdep_map *, lock_cmp_fn, lock_print_fn); + +#define lock_set_cmp_fn(lock, ...) lockdep_set_lock_cmp_fn(&(lock)->dep_map, __VA_ARGS__) +#else +#define lock_set_cmp_fn(lock, ...) do { } while (0) +#endif + enum xhlock_context_t { XHLOCK_HARD, XHLOCK_SOFT, @@ -556,6 +577,7 @@ do { \ #define rwsem_release(l, i) lock_release(l, i) #define lock_map_acquire(l) lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_) +#define lock_map_acquire_try(l) lock_acquire_exclusive(l, 0, 1, NULL, _THIS_IP_) #define lock_map_acquire_read(l) lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_) #define lock_map_acquire_tryread(l) lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_) #define lock_map_release(l) lock_release(l, _THIS_IP_) diff --git a/include/linux/lockdep_types.h b/include/linux/lockdep_types.h index d22430840b53..2ebc323d345a 100644 --- a/include/linux/lockdep_types.h +++ b/include/linux/lockdep_types.h @@ -33,6 +33,7 @@ enum lockdep_wait_type { enum lockdep_lock_type { LD_LOCK_NORMAL = 0, /* normal, catch all */ LD_LOCK_PERCPU, /* percpu */ + LD_LOCK_WAIT_OVERRIDE, /* annotation */ LD_LOCK_MAX, }; @@ -84,6 +85,11 @@ struct lock_trace; #define LOCKSTAT_POINTS 4 +struct lockdep_map; +typedef int (*lock_cmp_fn)(const struct lockdep_map *a, + const struct lockdep_map *b); +typedef void (*lock_print_fn)(const struct lockdep_map *map); + /* * The lock-class itself. The order of the structure members matters. * reinit_class() zeroes the key member and all subsequent members. @@ -109,6 +115,9 @@ struct lock_class { struct list_head locks_after, locks_before; const struct lockdep_subclass_key *key; + lock_cmp_fn cmp_fn; + lock_print_fn print_fn; + unsigned int subclass; unsigned int dep_gen_id; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 6bb55e61e8e8..7308a1a7599b 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -343,6 +343,7 @@ LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc, struct sock *sk, struct sock *newsk) LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc, struct sk_buff *skb) +LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk) #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_INFINIBAND diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index 1fadb5f5978b..295548cca8b3 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -455,7 +455,9 @@ void *mas_erase(struct ma_state *mas); int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp); void mas_store_prealloc(struct ma_state *mas, void *entry); void *mas_find(struct ma_state *mas, unsigned long max); +void *mas_find_range(struct ma_state *mas, unsigned long max); void *mas_find_rev(struct ma_state *mas, unsigned long min); +void *mas_find_range_rev(struct ma_state *mas, unsigned long max); int mas_preallocate(struct ma_state *mas, gfp_t gfp); bool mas_is_err(struct ma_state *mas); @@ -466,10 +468,18 @@ void mas_destroy(struct ma_state *mas); int mas_expected_entries(struct ma_state *mas, unsigned long nr_entries); void *mas_prev(struct ma_state *mas, unsigned long min); +void *mas_prev_range(struct ma_state *mas, unsigned long max); void *mas_next(struct ma_state *mas, unsigned long max); +void *mas_next_range(struct ma_state *mas, unsigned long max); int mas_empty_area(struct ma_state *mas, unsigned long min, unsigned long max, unsigned long size); +/* + * This finds an empty area from the highest address to the lowest. + * AKA "Topdown" version, + */ +int mas_empty_area_rev(struct ma_state *mas, unsigned long min, + unsigned long max, unsigned long size); static inline void mas_init(struct ma_state *mas, struct maple_tree *tree, unsigned long addr) @@ -482,23 +492,17 @@ static inline void mas_init(struct ma_state *mas, struct maple_tree *tree, } /* Checks if a mas has not found anything */ -static inline bool mas_is_none(struct ma_state *mas) +static inline bool mas_is_none(const struct ma_state *mas) { return mas->node == MAS_NONE; } /* Checks if a mas has been paused */ -static inline bool mas_is_paused(struct ma_state *mas) +static inline bool mas_is_paused(const struct ma_state *mas) { return mas->node == MAS_PAUSE; } -/* - * This finds an empty area from the highest address to the lowest. - * AKA "Topdown" version, - */ -int mas_empty_area_rev(struct ma_state *mas, unsigned long min, - unsigned long max, unsigned long size); /** * mas_reset() - Reset a Maple Tree operation state. * @mas: Maple Tree operation state. @@ -528,7 +532,6 @@ static inline void mas_reset(struct ma_state *mas) #define mas_for_each(__mas, __entry, __max) \ while (((__entry) = mas_find((__mas), (__max))) != NULL) - /** * mas_set_range() - Set up Maple Tree operation state for a different index. * @mas: Maple Tree operation state. @@ -616,7 +619,7 @@ static inline void mt_clear_in_rcu(struct maple_tree *mt) return; if (mt_external_lock(mt)) { - BUG_ON(!mt_lock_is_held(mt)); + WARN_ON(!mt_lock_is_held(mt)); mt->ma_flags &= ~MT_FLAGS_USE_RCU; } else { mtree_lock(mt); @@ -635,7 +638,7 @@ static inline void mt_set_in_rcu(struct maple_tree *mt) return; if (mt_external_lock(mt)) { - BUG_ON(!mt_lock_is_held(mt)); + WARN_ON(!mt_lock_is_held(mt)); mt->ma_flags |= MT_FLAGS_USE_RCU; } else { mtree_lock(mt); @@ -670,10 +673,17 @@ void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max); #ifdef CONFIG_DEBUG_MAPLE_TREE +enum mt_dump_format { + mt_dump_dec, + mt_dump_hex, +}; + extern atomic_t maple_tree_tests_run; extern atomic_t maple_tree_tests_passed; -void mt_dump(const struct maple_tree *mt); +void mt_dump(const struct maple_tree *mt, enum mt_dump_format format); +void mas_dump(const struct ma_state *mas); +void mas_wr_dump(const struct ma_wr_state *wr_mas); void mt_validate(struct maple_tree *mt); void mt_cache_shrink(void); #define MT_BUG_ON(__tree, __x) do { \ @@ -681,7 +691,23 @@ void mt_cache_shrink(void); if (__x) { \ pr_info("BUG at %s:%d (%u)\n", \ __func__, __LINE__, __x); \ - mt_dump(__tree); \ + mt_dump(__tree, mt_dump_hex); \ + pr_info("Pass: %u Run:%u\n", \ + atomic_read(&maple_tree_tests_passed), \ + atomic_read(&maple_tree_tests_run)); \ + dump_stack(); \ + } else { \ + atomic_inc(&maple_tree_tests_passed); \ + } \ +} while (0) + +#define MAS_BUG_ON(__mas, __x) do { \ + atomic_inc(&maple_tree_tests_run); \ + if (__x) { \ + pr_info("BUG at %s:%d (%u)\n", \ + __func__, __LINE__, __x); \ + mas_dump(__mas); \ + mt_dump((__mas)->tree, mt_dump_hex); \ pr_info("Pass: %u Run:%u\n", \ atomic_read(&maple_tree_tests_passed), \ atomic_read(&maple_tree_tests_run)); \ @@ -690,8 +716,84 @@ void mt_cache_shrink(void); atomic_inc(&maple_tree_tests_passed); \ } \ } while (0) + +#define MAS_WR_BUG_ON(__wrmas, __x) do { \ + atomic_inc(&maple_tree_tests_run); \ + if (__x) { \ + pr_info("BUG at %s:%d (%u)\n", \ + __func__, __LINE__, __x); \ + mas_wr_dump(__wrmas); \ + mas_dump((__wrmas)->mas); \ + mt_dump((__wrmas)->mas->tree, mt_dump_hex); \ + pr_info("Pass: %u Run:%u\n", \ + atomic_read(&maple_tree_tests_passed), \ + atomic_read(&maple_tree_tests_run)); \ + dump_stack(); \ + } else { \ + atomic_inc(&maple_tree_tests_passed); \ + } \ +} while (0) + +#define MT_WARN_ON(__tree, __x) ({ \ + int ret = !!(__x); \ + atomic_inc(&maple_tree_tests_run); \ + if (ret) { \ + pr_info("WARN at %s:%d (%u)\n", \ + __func__, __LINE__, __x); \ + mt_dump(__tree, mt_dump_hex); \ + pr_info("Pass: %u Run:%u\n", \ + atomic_read(&maple_tree_tests_passed), \ + atomic_read(&maple_tree_tests_run)); \ + dump_stack(); \ + } else { \ + atomic_inc(&maple_tree_tests_passed); \ + } \ + unlikely(ret); \ +}) + +#define MAS_WARN_ON(__mas, __x) ({ \ + int ret = !!(__x); \ + atomic_inc(&maple_tree_tests_run); \ + if (ret) { \ + pr_info("WARN at %s:%d (%u)\n", \ + __func__, __LINE__, __x); \ + mas_dump(__mas); \ + mt_dump((__mas)->tree, mt_dump_hex); \ + pr_info("Pass: %u Run:%u\n", \ + atomic_read(&maple_tree_tests_passed), \ + atomic_read(&maple_tree_tests_run)); \ + dump_stack(); \ + } else { \ + atomic_inc(&maple_tree_tests_passed); \ + } \ + unlikely(ret); \ +}) + +#define MAS_WR_WARN_ON(__wrmas, __x) ({ \ + int ret = !!(__x); \ + atomic_inc(&maple_tree_tests_run); \ + if (ret) { \ + pr_info("WARN at %s:%d (%u)\n", \ + __func__, __LINE__, __x); \ + mas_wr_dump(__wrmas); \ + mas_dump((__wrmas)->mas); \ + mt_dump((__wrmas)->mas->tree, mt_dump_hex); \ + pr_info("Pass: %u Run:%u\n", \ + atomic_read(&maple_tree_tests_passed), \ + atomic_read(&maple_tree_tests_run)); \ + dump_stack(); \ + } else { \ + atomic_inc(&maple_tree_tests_passed); \ + } \ + unlikely(ret); \ +}) #else -#define MT_BUG_ON(__tree, __x) BUG_ON(__x) +#define MT_BUG_ON(__tree, __x) BUG_ON(__x) +#define MAS_BUG_ON(__mas, __x) BUG_ON(__x) +#define MAS_WR_BUG_ON(__mas, __x) BUG_ON(__x) +#define MT_WARN_ON(__tree, __x) WARN_ON(__x) +#define MAS_WARN_ON(__mas, __x) WARN_ON(__x) +#define MAS_WR_WARN_ON(__mas, __x) WARN_ON(__x) #endif /* CONFIG_DEBUG_MAPLE_TREE */ #endif /*_LINUX_MAPLE_TREE_H */ diff --git a/include/linux/math.h b/include/linux/math.h index 439b8f0b9ebd..2d388650c556 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -118,17 +118,17 @@ __STRUCT_FRACT(s32) __STRUCT_FRACT(u32) #undef __STRUCT_FRACT -/* - * Multiplies an integer by a fraction, while avoiding unnecessary - * overflow or loss of precision. - */ -#define mult_frac(x, numer, denom)( \ -{ \ - typeof(x) quot = (x) / (denom); \ - typeof(x) rem = (x) % (denom); \ - (quot * (numer)) + ((rem * (numer)) / (denom)); \ -} \ -) +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ +#define mult_frac(x, n, d) \ +({ \ + typeof(x) x_ = (x); \ + typeof(n) n_ = (n); \ + typeof(d) d_ = (d); \ + \ + typeof(x_) q = x_ / d_; \ + typeof(x_) r = x_ % d_; \ + q * n_ + r * n_ / d_; \ +}) #define sector_div(a, b) do_div(a, b) diff --git a/include/linux/math64.h b/include/linux/math64.h index 8b9191a2849e..bf74478926d4 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -168,7 +168,7 @@ static __always_inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift) #endif /* mul_u64_u32_shr */ #ifndef mul_u64_u64_shr -static inline u64 mul_u64_u64_shr(u64 a, u64 mul, unsigned int shift) +static __always_inline u64 mul_u64_u64_shr(u64 a, u64 mul, unsigned int shift) { return (u64)(((unsigned __int128)a * mul) >> shift); } diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 27013d6bf24a..c1b7008826e5 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -106,6 +106,16 @@ int mdio_driver_register(struct mdio_driver *drv); void mdio_driver_unregister(struct mdio_driver *drv); int mdio_device_bus_match(struct device *dev, struct device_driver *drv); +static inline void mdio_device_get(struct mdio_device *mdiodev) +{ + get_device(&mdiodev->dev); +} + +static inline void mdio_device_put(struct mdio_device *mdiodev) +{ + mdio_device_free(mdiodev); +} + static inline bool mdio_phy_id_is_c45(int phy_id) { return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK); @@ -486,6 +496,45 @@ static inline u32 linkmode_adv_to_mii_10base_t1_t(unsigned long *adv) return result; } +/** + * mii_c73_mod_linkmode - convert a Clause 73 advertisement to linkmodes + * @adv: linkmode advertisement setting + * @lpa: array of three u16s containing the advertisement + * + * Convert an IEEE 802.3 Clause 73 advertisement to ethtool link modes. + */ +static inline void mii_c73_mod_linkmode(unsigned long *adv, u16 *lpa) +{ + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, + adv, lpa[0] & MDIO_AN_C73_0_PAUSE); + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + adv, lpa[0] & MDIO_AN_C73_0_ASM_DIR); + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_1000BASE_KX); + linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_10GBASE_KX4); + linkmode_mod_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_40GBASE_KR4); + linkmode_mod_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_40GBASE_CR4); + /* 100GBASE_CR10 and 100GBASE_KP4 not implemented */ + linkmode_mod_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_100GBASE_KR4); + linkmode_mod_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_100GBASE_CR4); + /* 25GBASE_R_S not implemented */ + /* The 25GBASE_R bit can be used for 25Gbase KR or CR modes */ + linkmode_mod_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_25GBASE_R); + linkmode_mod_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_25GBASE_R); + linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + adv, lpa[1] & MDIO_AN_C73_1_10GBASE_KR); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + adv, lpa[2] & MDIO_AN_C73_2_2500BASE_KX); + /* 5GBASE_KR not implemented */ +} + int __mdiobus_read(struct mii_bus *bus, int addr, u32 regnum); int __mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); int __mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum, diff --git a/include/linux/mdio/mdio-regmap.h b/include/linux/mdio/mdio-regmap.h new file mode 100644 index 000000000000..679d9069846b --- /dev/null +++ b/include/linux/mdio/mdio-regmap.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS + * within the MMIO-mapped area + * + * Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com> + */ +#ifndef MDIO_REGMAP_H +#define MDIO_REGMAP_H + +#include <linux/phy.h> + +struct device; +struct regmap; + +struct mdio_regmap_config { + struct device *parent; + struct regmap *regmap; + char name[MII_BUS_ID_SIZE]; + u8 valid_addr; + bool autoscan; +}; + +struct mii_bus *devm_mdio_regmap_register(struct device *dev, + const struct mdio_regmap_config *config); + +#endif diff --git a/include/linux/memblock.h b/include/linux/memblock.h index f82ee3fac1cd..f71ff9f0ec81 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -128,7 +128,6 @@ int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); void memblock_free_all(void); void memblock_free(void *ptr, size_t size); -void reset_node_managed_pages(pg_data_t *pgdat); void reset_all_zones_managed_pages(void); /* Low level functions */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 222d7370134c..5818af8eca5a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -419,7 +419,7 @@ static inline struct obj_cgroup *__folio_objcg(struct folio *folio) * * - the folio lock * - LRU isolation - * - lock_page_memcg() + * - folio_memcg_lock() * - exclusive reference * - mem_cgroup_trylock_pages() * @@ -820,8 +820,8 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *, struct mem_cgroup *, struct mem_cgroup_reclaim_cookie *); void mem_cgroup_iter_break(struct mem_cgroup *, struct mem_cgroup *); -int mem_cgroup_scan_tasks(struct mem_cgroup *, - int (*)(struct task_struct *, void *), void *); +void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, + int (*)(struct task_struct *, void *), void *arg); static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg) { @@ -949,8 +949,6 @@ void mem_cgroup_print_oom_group(struct mem_cgroup *memcg); void folio_memcg_lock(struct folio *folio); void folio_memcg_unlock(struct folio *folio); -void lock_page_memcg(struct page *page); -void unlock_page_memcg(struct page *page); void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val); @@ -1038,7 +1036,6 @@ static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec, } void mem_cgroup_flush_stats(void); -void mem_cgroup_flush_stats_atomic(void); void mem_cgroup_flush_stats_ratelimited(void); void __mod_memcg_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, @@ -1367,10 +1364,9 @@ static inline void mem_cgroup_iter_break(struct mem_cgroup *root, { } -static inline int mem_cgroup_scan_tasks(struct mem_cgroup *memcg, +static inline void mem_cgroup_scan_tasks(struct mem_cgroup *memcg, int (*fn)(struct task_struct *, void *), void *arg) { - return 0; } static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg) @@ -1439,14 +1435,6 @@ mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) { } -static inline void lock_page_memcg(struct page *page) -{ -} - -static inline void unlock_page_memcg(struct page *page) -{ -} - static inline void folio_memcg_lock(struct folio *folio) { } @@ -1537,10 +1525,6 @@ static inline void mem_cgroup_flush_stats(void) { } -static inline void mem_cgroup_flush_stats_atomic(void) -{ -} - static inline void mem_cgroup_flush_stats_ratelimited(void) { } diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 9fcbf5706595..013c69753c91 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -326,9 +326,6 @@ static inline int remove_memory(u64 start, u64 size) static inline void __remove_memory(u64 start, u64 size) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ -extern void set_zone_contiguous(struct zone *zone); -extern void clear_zone_contiguous(struct zone *zone); - #ifdef CONFIG_MEMORY_HOTPLUG extern void __ref free_area_init_core_hotplug(struct pglist_data *pgdat); extern int __add_memory(int nid, u64 start, u64 size, mhp_t mhp_flags); @@ -347,9 +344,8 @@ extern void remove_pfn_range_from_zone(struct zone *zone, extern int sparse_add_section(int nid, unsigned long pfn, unsigned long nr_pages, struct vmem_altmap *altmap, struct dev_pagemap *pgmap); -extern void sparse_remove_section(struct mem_section *ms, - unsigned long pfn, unsigned long nr_pages, - unsigned long map_offset, struct vmem_altmap *altmap); +extern void sparse_remove_section(unsigned long pfn, unsigned long nr_pages, + struct vmem_altmap *altmap); extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum); extern struct zone *zone_for_pfn_range(int online_type, int nid, diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index beb3f44f85c5..f1755163dd9f 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -12,11 +12,13 @@ enum axp20x_variants { AXP152_ID = 0, + AXP192_ID, AXP202_ID, AXP209_ID, AXP221_ID, AXP223_ID, AXP288_ID, + AXP313A_ID, AXP803_ID, AXP806_ID, AXP809_ID, @@ -25,6 +27,7 @@ enum axp20x_variants { NR_AXP20X_VARIANTS, }; +#define AXP192_DATACACHE(m) (0x06 + (m)) #define AXP20X_DATACACHE(m) (0x04 + (m)) /* Power supply */ @@ -46,6 +49,13 @@ enum axp20x_variants { #define AXP152_DCDC_FREQ 0x37 #define AXP152_DCDC_MODE 0x80 +#define AXP192_USB_OTG_STATUS 0x04 +#define AXP192_PWR_OUT_CTRL 0x12 +#define AXP192_DCDC2_V_OUT 0x23 +#define AXP192_DCDC1_V_OUT 0x26 +#define AXP192_DCDC3_V_OUT 0x27 +#define AXP192_LDO2_3_V_OUT 0x28 + #define AXP20X_PWR_INPUT_STATUS 0x00 #define AXP20X_PWR_OP_MODE 0x01 #define AXP20X_USB_OTG_STATUS 0x02 @@ -92,6 +102,17 @@ enum axp20x_variants { #define AXP22X_ALDO3_V_OUT 0x2a #define AXP22X_CHRG_CTRL3 0x35 +#define AXP313A_ON_INDICATE 0x00 +#define AXP313A_OUTPUT_CONTROL 0x10 +#define AXP313A_DCDC1_CONRTOL 0x13 +#define AXP313A_DCDC2_CONRTOL 0x14 +#define AXP313A_DCDC3_CONRTOL 0x15 +#define AXP313A_ALDO1_CONRTOL 0x16 +#define AXP313A_DLDO1_CONRTOL 0x17 +#define AXP313A_SHUTDOWN_CTRL 0x1a +#define AXP313A_IRQ_EN 0x20 +#define AXP313A_IRQ_STATE 0x21 + #define AXP806_STARTUP_SRC 0x00 #define AXP806_CHIP_ID 0x03 #define AXP806_PWR_OUT_CTRL1 0x10 @@ -173,6 +194,17 @@ enum axp20x_variants { #define AXP152_IRQ2_STATE 0x49 #define AXP152_IRQ3_STATE 0x4a +#define AXP192_IRQ1_EN 0x40 +#define AXP192_IRQ2_EN 0x41 +#define AXP192_IRQ3_EN 0x42 +#define AXP192_IRQ4_EN 0x43 +#define AXP192_IRQ1_STATE 0x44 +#define AXP192_IRQ2_STATE 0x45 +#define AXP192_IRQ3_STATE 0x46 +#define AXP192_IRQ4_STATE 0x47 +#define AXP192_IRQ5_EN 0x4a +#define AXP192_IRQ5_STATE 0x4d + #define AXP20X_IRQ1_EN 0x40 #define AXP20X_IRQ2_EN 0x41 #define AXP20X_IRQ3_EN 0x42 @@ -192,6 +224,11 @@ enum axp20x_variants { #define AXP15060_IRQ2_STATE 0x49 /* ADC */ +#define AXP192_GPIO2_V_ADC_H 0x68 +#define AXP192_GPIO2_V_ADC_L 0x69 +#define AXP192_GPIO3_V_ADC_H 0x6a +#define AXP192_GPIO3_V_ADC_L 0x6b + #define AXP20X_ACIN_V_ADC_H 0x56 #define AXP20X_ACIN_V_ADC_L 0x57 #define AXP20X_ACIN_I_ADC_H 0x58 @@ -221,6 +258,8 @@ enum axp20x_variants { #define AXP20X_IPSOUT_V_HIGH_L 0x7f /* Power supply */ +#define AXP192_GPIO30_IN_RANGE 0x85 + #define AXP20X_DCDC_MODE 0x80 #define AXP20X_ADC_EN1 0x82 #define AXP20X_ADC_EN2 0x83 @@ -249,6 +288,16 @@ enum axp20x_variants { #define AXP152_PWM1_FREQ_Y 0x9c #define AXP152_PWM1_DUTY_CYCLE 0x9d +#define AXP192_GPIO0_CTRL 0x90 +#define AXP192_LDO_IO0_V_OUT 0x91 +#define AXP192_GPIO1_CTRL 0x92 +#define AXP192_GPIO2_CTRL 0x93 +#define AXP192_GPIO2_0_STATE 0x94 +#define AXP192_GPIO4_3_CTRL 0x95 +#define AXP192_GPIO4_3_STATE 0x96 +#define AXP192_GPIO2_0_PULL 0x97 +#define AXP192_N_RSTO_CTRL 0x9e + #define AXP20X_GPIO0_CTRL 0x90 #define AXP20X_LDO5_V_OUT 0x91 #define AXP20X_GPIO1_CTRL 0x92 @@ -329,6 +378,17 @@ enum axp20x_variants { /* Regulators IDs */ enum { + AXP192_DCDC1 = 0, + AXP192_DCDC2, + AXP192_DCDC3, + AXP192_LDO1, + AXP192_LDO2, + AXP192_LDO3, + AXP192_LDO_IO0, + AXP192_REG_ID_MAX +}; + +enum { AXP20X_LDO1 = 0, AXP20X_LDO2, AXP20X_LDO3, @@ -364,6 +424,16 @@ enum { }; enum { + AXP313A_DCDC1 = 0, + AXP313A_DCDC2, + AXP313A_DCDC3, + AXP313A_ALDO1, + AXP313A_DLDO1, + AXP313A_RTC_LDO, + AXP313A_REG_ID_MAX, +}; + +enum { AXP806_DCDCA = 0, AXP806_DCDCB, AXP806_DCDCC, @@ -509,6 +579,42 @@ enum { AXP152_IRQ_GPIO0_INPUT, }; +enum axp192_irqs { + AXP192_IRQ_ACIN_OVER_V = 1, + AXP192_IRQ_ACIN_PLUGIN, + AXP192_IRQ_ACIN_REMOVAL, + AXP192_IRQ_VBUS_OVER_V, + AXP192_IRQ_VBUS_PLUGIN, + AXP192_IRQ_VBUS_REMOVAL, + AXP192_IRQ_VBUS_V_LOW, + AXP192_IRQ_BATT_PLUGIN, + AXP192_IRQ_BATT_REMOVAL, + AXP192_IRQ_BATT_ENT_ACT_MODE, + AXP192_IRQ_BATT_EXIT_ACT_MODE, + AXP192_IRQ_CHARG, + AXP192_IRQ_CHARG_DONE, + AXP192_IRQ_BATT_TEMP_HIGH, + AXP192_IRQ_BATT_TEMP_LOW, + AXP192_IRQ_DIE_TEMP_HIGH, + AXP192_IRQ_CHARG_I_LOW, + AXP192_IRQ_DCDC1_V_LONG, + AXP192_IRQ_DCDC2_V_LONG, + AXP192_IRQ_DCDC3_V_LONG, + AXP192_IRQ_PEK_SHORT = 22, + AXP192_IRQ_PEK_LONG, + AXP192_IRQ_N_OE_PWR_ON, + AXP192_IRQ_N_OE_PWR_OFF, + AXP192_IRQ_VBUS_VALID, + AXP192_IRQ_VBUS_NOT_VALID, + AXP192_IRQ_VBUS_SESS_VALID, + AXP192_IRQ_VBUS_SESS_END, + AXP192_IRQ_LOW_PWR_LVL = 31, + AXP192_IRQ_TIMER, + AXP192_IRQ_GPIO2_INPUT = 37, + AXP192_IRQ_GPIO1_INPUT, + AXP192_IRQ_GPIO0_INPUT, +}; + enum { AXP20X_IRQ_ACIN_OVER_V = 1, AXP20X_IRQ_ACIN_PLUGIN, @@ -616,6 +722,16 @@ enum axp288_irqs { AXP288_IRQ_BC_USB_CHNG, }; +enum axp313a_irqs { + AXP313A_IRQ_DIE_TEMP_HIGH, + AXP313A_IRQ_DCDC2_V_LOW = 2, + AXP313A_IRQ_DCDC3_V_LOW, + AXP313A_IRQ_PEK_LONG, + AXP313A_IRQ_PEK_SHORT, + AXP313A_IRQ_PEK_FAL_EDGE, + AXP313A_IRQ_PEK_RIS_EDGE, +}; + enum axp803_irqs { AXP803_IRQ_ACIN_OVER_V = 1, AXP803_IRQ_ACIN_PLUGIN, diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h index 1812ebfa11a8..ee66c9751003 100644 --- a/include/linux/mfd/intel-m10-bmc.h +++ b/include/linux/mfd/intel-m10-bmc.h @@ -11,6 +11,7 @@ #include <linux/bits.h> #include <linux/dev_printk.h> #include <linux/regmap.h> +#include <linux/rwsem.h> #define M10BMC_N3000_LEGACY_BUILD_VER 0x300468 #define M10BMC_N3000_SYS_BASE 0x300800 @@ -39,6 +40,11 @@ #define M10BMC_N3000_VER_PCB_INFO_MSK GENMASK(31, 24) #define M10BMC_N3000_VER_LEGACY_INVALID 0xffffffff +/* Telemetry registers */ +#define M10BMC_N3000_TELEM_START 0x100 +#define M10BMC_N3000_TELEM_END 0x250 +#define M10BMC_D5005_TELEM_END 0x300 + /* Secure update doorbell register, in system register region */ #define M10BMC_N3000_DOORBELL 0x400 @@ -205,11 +211,15 @@ struct m10bmc_csr_map { * struct intel_m10bmc_platform_info - Intel MAX 10 BMC platform specific information * @cells: MFD cells * @n_cells: MFD cells ARRAY_SIZE() + * @handshake_sys_reg_ranges: array of register ranges for fw handshake regs + * @handshake_sys_reg_nranges: number of register ranges for fw handshake regs * @csr_map: the mappings for register definition of MAX10 BMC */ struct intel_m10bmc_platform_info { struct mfd_cell *cells; int n_cells; + const struct regmap_range *handshake_sys_reg_ranges; + unsigned int handshake_sys_reg_nranges; const struct m10bmc_csr_map *csr_map; }; @@ -232,18 +242,30 @@ struct intel_m10bmc_flash_bulk_ops { void (*unlock_write)(struct intel_m10bmc *m10bmc); }; +enum m10bmc_fw_state { + M10BMC_FW_STATE_NORMAL, + M10BMC_FW_STATE_SEC_UPDATE_PREPARE, + M10BMC_FW_STATE_SEC_UPDATE_WRITE, + M10BMC_FW_STATE_SEC_UPDATE_PROGRAM, +}; + /** * struct intel_m10bmc - Intel MAX 10 BMC parent driver data structure * @dev: this device * @regmap: the regmap used to access registers by m10bmc itself * @info: the platform information for MAX10 BMC * @flash_bulk_ops: optional device specific operations for flash R/W + * @bmcfw_lock: read/write semaphore to BMC firmware running state + * @bmcfw_state: BMC firmware running state. Available only when + * handshake_sys_reg_nranges > 0. */ struct intel_m10bmc { struct device *dev; struct regmap *regmap; const struct intel_m10bmc_platform_info *info; const struct intel_m10bmc_flash_bulk_ops *flash_bulk_ops; + struct rw_semaphore bmcfw_lock; /* Protects bmcfw_state */ + enum m10bmc_fw_state bmcfw_state; }; /* @@ -251,6 +273,7 @@ struct intel_m10bmc { * * m10bmc_raw_read - read m10bmc register per addr * m10bmc_sys_read - read m10bmc system register per offset + * m10bmc_sys_update_bits - update m10bmc system register per offset */ static inline int m10bmc_raw_read(struct intel_m10bmc *m10bmc, unsigned int addr, @@ -266,21 +289,15 @@ m10bmc_raw_read(struct intel_m10bmc *m10bmc, unsigned int addr, return ret; } +int m10bmc_sys_read(struct intel_m10bmc *m10bmc, unsigned int offset, unsigned int *val); +int m10bmc_sys_update_bits(struct intel_m10bmc *m10bmc, unsigned int offset, + unsigned int msk, unsigned int val); + /* - * The base of the system registers could be configured by HW developers, and - * in HW SPEC, the base is not added to the addresses of the system registers. - * - * This function helps to simplify the accessing of the system registers. And if - * the base is reconfigured in HW, SW developers could simply change the - * csr_map's base accordingly. + * Track the state of the firmware, as it is not available for register + * handshakes during secure updates on some MAX 10 cards. */ -static inline int m10bmc_sys_read(struct intel_m10bmc *m10bmc, unsigned int offset, - unsigned int *val) -{ - const struct m10bmc_csr_map *csr_map = m10bmc->info->csr_map; - - return m10bmc_raw_read(m10bmc, csr_map->base + offset, val); -} +void m10bmc_fw_state_set(struct intel_m10bmc *m10bmc, enum m10bmc_fw_state new_state); /* * MAX10 BMC Core support diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max5970.h index a850b2e02e6a..762a7d40c843 100644 --- a/include/linux/mfd/max597x.h +++ b/include/linux/mfd/max5970.h @@ -7,25 +7,25 @@ * Author: Patrick Rudolph <patrick.rudolph@9elements.com> */ -#ifndef _MFD_MAX597X_H -#define _MFD_MAX597X_H +#ifndef _MFD_MAX5970_H +#define _MFD_MAX5970_H #include <linux/regmap.h> #define MAX5970_NUM_SWITCHES 2 #define MAX5978_NUM_SWITCHES 1 -#define MAX597X_NUM_LEDS 4 +#define MAX5970_NUM_LEDS 4 -struct max597x_data { +struct max5970_data { int num_switches; u32 irng[MAX5970_NUM_SWITCHES]; u32 mon_rng[MAX5970_NUM_SWITCHES]; u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES]; }; -enum max597x_chip_type { - MAX597x_TYPE_MAX5978 = 1, - MAX597x_TYPE_MAX5970, +enum max5970_chip_type { + TYPE_MAX5978 = 1, + TYPE_MAX5970, }; #define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4) @@ -93,4 +93,4 @@ enum max597x_chip_type { #define MAX_REGISTERS 0x49 #define ADC_MASK 0x3FF -#endif /* _MFD_MAX597X_H */ +#endif /* _MFD_MAX5970_H */ diff --git a/include/linux/mfd/max77541.h b/include/linux/mfd/max77541.h new file mode 100644 index 000000000000..fe5c0a3dc637 --- /dev/null +++ b/include/linux/mfd/max77541.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __MFD_MAX77541_H +#define __MFD_MAX77541_H + +#include <linux/bits.h> +#include <linux/types.h> + +/* REGISTERS */ +#define MAX77541_REG_INT_SRC 0x00 +#define MAX77541_REG_INT_SRC_M 0x01 + +#define MAX77541_BIT_INT_SRC_TOPSYS BIT(0) +#define MAX77541_BIT_INT_SRC_BUCK BIT(1) + +#define MAX77541_REG_TOPSYS_INT 0x02 +#define MAX77541_REG_TOPSYS_INT_M 0x03 + +#define MAX77541_BIT_TOPSYS_INT_TJ_120C BIT(0) +#define MAX77541_BIT_TOPSYS_INT_TJ_140C BIT(1) +#define MAX77541_BIT_TOPSYS_INT_TSHDN BIT(2) +#define MAX77541_BIT_TOPSYS_INT_UVLO BIT(3) +#define MAX77541_BIT_TOPSYS_INT_ALT_SWO BIT(4) +#define MAX77541_BIT_TOPSYS_INT_EXT_FREQ_DET BIT(5) + +/* REGULATORS */ +#define MAX77541_REG_BUCK_INT 0x20 +#define MAX77541_REG_BUCK_INT_M 0x21 + +#define MAX77541_BIT_BUCK_INT_M1_POK_FLT BIT(0) +#define MAX77541_BIT_BUCK_INT_M2_POK_FLT BIT(1) +#define MAX77541_BIT_BUCK_INT_M1_SCFLT BIT(4) +#define MAX77541_BIT_BUCK_INT_M2_SCFLT BIT(5) + +#define MAX77541_REG_EN_CTRL 0x0B + +#define MAX77541_BIT_M1_EN BIT(0) +#define MAX77541_BIT_M2_EN BIT(1) + +#define MAX77541_REG_M1_VOUT 0x23 +#define MAX77541_REG_M2_VOUT 0x33 + +#define MAX77541_BITS_MX_VOUT GENMASK(7, 0) + +#define MAX77541_REG_M1_CFG1 0x25 +#define MAX77541_REG_M2_CFG1 0x35 + +#define MAX77541_BITS_MX_CFG1_RNG GENMASK(7, 6) + +/* ADC */ +#define MAX77541_REG_ADC_INT 0x70 +#define MAX77541_REG_ADC_INT_M 0x71 + +#define MAX77541_BIT_ADC_INT_CH1_I BIT(0) +#define MAX77541_BIT_ADC_INT_CH2_I BIT(1) +#define MAX77541_BIT_ADC_INT_CH3_I BIT(2) +#define MAX77541_BIT_ADC_INT_CH6_I BIT(5) + +#define MAX77541_REG_ADC_DATA_CH1 0x72 +#define MAX77541_REG_ADC_DATA_CH2 0x73 +#define MAX77541_REG_ADC_DATA_CH3 0x74 +#define MAX77541_REG_ADC_DATA_CH6 0x77 + +/* INTERRUPT MASKS*/ +#define MAX77541_REG_INT_SRC_MASK 0x00 +#define MAX77541_REG_TOPSYS_INT_MASK 0x00 +#define MAX77541_REG_BUCK_INT_MASK 0x00 + +#define MAX77541_MAX_REGULATORS 2 + +enum max7754x_ids { + MAX77540 = 1, + MAX77541, +}; + +struct regmap; +struct regmap_irq_chip_data; +struct i2c_client; + +struct max77541 { + struct i2c_client *i2c; + struct regmap *regmap; + enum max7754x_ids id; + + struct regmap_irq_chip_data *irq_data; + struct regmap_irq_chip_data *irq_buck; + struct regmap_irq_chip_data *irq_topsys; + struct regmap_irq_chip_data *irq_adc; +}; + +#endif /* __MFD_MAX77541_H */ diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 9af1f3105f80..78e167a92483 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -289,6 +289,414 @@ enum rk805_reg { #define RK805_INT_ALARM_EN (1 << 3) #define RK805_INT_TIMER_EN (1 << 2) +/* RK806 */ +#define RK806_POWER_EN0 0x0 +#define RK806_POWER_EN1 0x1 +#define RK806_POWER_EN2 0x2 +#define RK806_POWER_EN3 0x3 +#define RK806_POWER_EN4 0x4 +#define RK806_POWER_EN5 0x5 +#define RK806_POWER_SLP_EN0 0x6 +#define RK806_POWER_SLP_EN1 0x7 +#define RK806_POWER_SLP_EN2 0x8 +#define RK806_POWER_DISCHRG_EN0 0x9 +#define RK806_POWER_DISCHRG_EN1 0xA +#define RK806_POWER_DISCHRG_EN2 0xB +#define RK806_BUCK_FB_CONFIG 0xC +#define RK806_SLP_LP_CONFIG 0xD +#define RK806_POWER_FPWM_EN0 0xE +#define RK806_POWER_FPWM_EN1 0xF +#define RK806_BUCK1_CONFIG 0x10 +#define RK806_BUCK2_CONFIG 0x11 +#define RK806_BUCK3_CONFIG 0x12 +#define RK806_BUCK4_CONFIG 0x13 +#define RK806_BUCK5_CONFIG 0x14 +#define RK806_BUCK6_CONFIG 0x15 +#define RK806_BUCK7_CONFIG 0x16 +#define RK806_BUCK8_CONFIG 0x17 +#define RK806_BUCK9_CONFIG 0x18 +#define RK806_BUCK10_CONFIG 0x19 +#define RK806_BUCK1_ON_VSEL 0x1A +#define RK806_BUCK2_ON_VSEL 0x1B +#define RK806_BUCK3_ON_VSEL 0x1C +#define RK806_BUCK4_ON_VSEL 0x1D +#define RK806_BUCK5_ON_VSEL 0x1E +#define RK806_BUCK6_ON_VSEL 0x1F +#define RK806_BUCK7_ON_VSEL 0x20 +#define RK806_BUCK8_ON_VSEL 0x21 +#define RK806_BUCK9_ON_VSEL 0x22 +#define RK806_BUCK10_ON_VSEL 0x23 +#define RK806_BUCK1_SLP_VSEL 0x24 +#define RK806_BUCK2_SLP_VSEL 0x25 +#define RK806_BUCK3_SLP_VSEL 0x26 +#define RK806_BUCK4_SLP_VSEL 0x27 +#define RK806_BUCK5_SLP_VSEL 0x28 +#define RK806_BUCK6_SLP_VSEL 0x29 +#define RK806_BUCK7_SLP_VSEL 0x2A +#define RK806_BUCK8_SLP_VSEL 0x2B +#define RK806_BUCK9_SLP_VSEL 0x2D +#define RK806_BUCK10_SLP_VSEL 0x2E +#define RK806_BUCK_DEBUG1 0x30 +#define RK806_BUCK_DEBUG2 0x31 +#define RK806_BUCK_DEBUG3 0x32 +#define RK806_BUCK_DEBUG4 0x33 +#define RK806_BUCK_DEBUG5 0x34 +#define RK806_BUCK_DEBUG6 0x35 +#define RK806_BUCK_DEBUG7 0x36 +#define RK806_BUCK_DEBUG8 0x37 +#define RK806_BUCK_DEBUG9 0x38 +#define RK806_BUCK_DEBUG10 0x39 +#define RK806_BUCK_DEBUG11 0x3A +#define RK806_BUCK_DEBUG12 0x3B +#define RK806_BUCK_DEBUG13 0x3C +#define RK806_BUCK_DEBUG14 0x3D +#define RK806_BUCK_DEBUG15 0x3E +#define RK806_BUCK_DEBUG16 0x3F +#define RK806_BUCK_DEBUG17 0x40 +#define RK806_BUCK_DEBUG18 0x41 +#define RK806_NLDO_IMAX 0x42 +#define RK806_NLDO1_ON_VSEL 0x43 +#define RK806_NLDO2_ON_VSEL 0x44 +#define RK806_NLDO3_ON_VSEL 0x45 +#define RK806_NLDO4_ON_VSEL 0x46 +#define RK806_NLDO5_ON_VSEL 0x47 +#define RK806_NLDO1_SLP_VSEL 0x48 +#define RK806_NLDO2_SLP_VSEL 0x49 +#define RK806_NLDO3_SLP_VSEL 0x4A +#define RK806_NLDO4_SLP_VSEL 0x4B +#define RK806_NLDO5_SLP_VSEL 0x4C +#define RK806_PLDO_IMAX 0x4D +#define RK806_PLDO1_ON_VSEL 0x4E +#define RK806_PLDO2_ON_VSEL 0x4F +#define RK806_PLDO3_ON_VSEL 0x50 +#define RK806_PLDO4_ON_VSEL 0x51 +#define RK806_PLDO5_ON_VSEL 0x52 +#define RK806_PLDO6_ON_VSEL 0x53 +#define RK806_PLDO1_SLP_VSEL 0x54 +#define RK806_PLDO2_SLP_VSEL 0x55 +#define RK806_PLDO3_SLP_VSEL 0x56 +#define RK806_PLDO4_SLP_VSEL 0x57 +#define RK806_PLDO5_SLP_VSEL 0x58 +#define RK806_PLDO6_SLP_VSEL 0x59 +#define RK806_CHIP_NAME 0x5A +#define RK806_CHIP_VER 0x5B +#define RK806_OTP_VER 0x5C +#define RK806_SYS_STS 0x5D +#define RK806_SYS_CFG0 0x5E +#define RK806_SYS_CFG1 0x5F +#define RK806_SYS_OPTION 0x61 +#define RK806_SLEEP_CONFIG0 0x62 +#define RK806_SLEEP_CONFIG1 0x63 +#define RK806_SLEEP_CTR_SEL0 0x64 +#define RK806_SLEEP_CTR_SEL1 0x65 +#define RK806_SLEEP_CTR_SEL2 0x66 +#define RK806_SLEEP_CTR_SEL3 0x67 +#define RK806_SLEEP_CTR_SEL4 0x68 +#define RK806_SLEEP_CTR_SEL5 0x69 +#define RK806_DVS_CTRL_SEL0 0x6A +#define RK806_DVS_CTRL_SEL1 0x6B +#define RK806_DVS_CTRL_SEL2 0x6C +#define RK806_DVS_CTRL_SEL3 0x6D +#define RK806_DVS_CTRL_SEL4 0x6E +#define RK806_DVS_CTRL_SEL5 0x6F +#define RK806_DVS_START_CTRL 0x70 +#define RK806_SLEEP_GPIO 0x71 +#define RK806_SYS_CFG3 0x72 +#define RK806_ON_SOURCE 0x74 +#define RK806_OFF_SOURCE 0x75 +#define RK806_PWRON_KEY 0x76 +#define RK806_INT_STS0 0x77 +#define RK806_INT_MSK0 0x78 +#define RK806_INT_STS1 0x79 +#define RK806_INT_MSK1 0x7A +#define RK806_GPIO_INT_CONFIG 0x7B +#define RK806_DATA_REG0 0x7C +#define RK806_DATA_REG1 0x7D +#define RK806_DATA_REG2 0x7E +#define RK806_DATA_REG3 0x7F +#define RK806_DATA_REG4 0x80 +#define RK806_DATA_REG5 0x81 +#define RK806_DATA_REG6 0x82 +#define RK806_DATA_REG7 0x83 +#define RK806_DATA_REG8 0x84 +#define RK806_DATA_REG9 0x85 +#define RK806_DATA_REG10 0x86 +#define RK806_DATA_REG11 0x87 +#define RK806_DATA_REG12 0x88 +#define RK806_DATA_REG13 0x89 +#define RK806_DATA_REG14 0x8A +#define RK806_DATA_REG15 0x8B +#define RK806_TM_REG 0x8C +#define RK806_OTP_EN_REG 0x8D +#define RK806_FUNC_OTP_EN_REG 0x8E +#define RK806_TEST_REG1 0x8F +#define RK806_TEST_REG2 0x90 +#define RK806_TEST_REG3 0x91 +#define RK806_TEST_REG4 0x92 +#define RK806_TEST_REG5 0x93 +#define RK806_BUCK_VSEL_OTP_REG0 0x94 +#define RK806_BUCK_VSEL_OTP_REG1 0x95 +#define RK806_BUCK_VSEL_OTP_REG2 0x96 +#define RK806_BUCK_VSEL_OTP_REG3 0x97 +#define RK806_BUCK_VSEL_OTP_REG4 0x98 +#define RK806_BUCK_VSEL_OTP_REG5 0x99 +#define RK806_BUCK_VSEL_OTP_REG6 0x9A +#define RK806_BUCK_VSEL_OTP_REG7 0x9B +#define RK806_BUCK_VSEL_OTP_REG8 0x9C +#define RK806_BUCK_VSEL_OTP_REG9 0x9D +#define RK806_NLDO1_VSEL_OTP_REG0 0x9E +#define RK806_NLDO1_VSEL_OTP_REG1 0x9F +#define RK806_NLDO1_VSEL_OTP_REG2 0xA0 +#define RK806_NLDO1_VSEL_OTP_REG3 0xA1 +#define RK806_NLDO1_VSEL_OTP_REG4 0xA2 +#define RK806_PLDO_VSEL_OTP_REG0 0xA3 +#define RK806_PLDO_VSEL_OTP_REG1 0xA4 +#define RK806_PLDO_VSEL_OTP_REG2 0xA5 +#define RK806_PLDO_VSEL_OTP_REG3 0xA6 +#define RK806_PLDO_VSEL_OTP_REG4 0xA7 +#define RK806_PLDO_VSEL_OTP_REG5 0xA8 +#define RK806_BUCK_EN_OTP_REG1 0xA9 +#define RK806_NLDO_EN_OTP_REG1 0xAA +#define RK806_PLDO_EN_OTP_REG1 0xAB +#define RK806_BUCK_FB_RES_OTP_REG1 0xAC +#define RK806_OTP_RESEV_REG0 0xAD +#define RK806_OTP_RESEV_REG1 0xAE +#define RK806_OTP_RESEV_REG2 0xAF +#define RK806_OTP_RESEV_REG3 0xB0 +#define RK806_OTP_RESEV_REG4 0xB1 +#define RK806_BUCK_SEQ_REG0 0xB2 +#define RK806_BUCK_SEQ_REG1 0xB3 +#define RK806_BUCK_SEQ_REG2 0xB4 +#define RK806_BUCK_SEQ_REG3 0xB5 +#define RK806_BUCK_SEQ_REG4 0xB6 +#define RK806_BUCK_SEQ_REG5 0xB7 +#define RK806_BUCK_SEQ_REG6 0xB8 +#define RK806_BUCK_SEQ_REG7 0xB9 +#define RK806_BUCK_SEQ_REG8 0xBA +#define RK806_BUCK_SEQ_REG9 0xBB +#define RK806_BUCK_SEQ_REG10 0xBC +#define RK806_BUCK_SEQ_REG11 0xBD +#define RK806_BUCK_SEQ_REG12 0xBE +#define RK806_BUCK_SEQ_REG13 0xBF +#define RK806_BUCK_SEQ_REG14 0xC0 +#define RK806_BUCK_SEQ_REG15 0xC1 +#define RK806_BUCK_SEQ_REG16 0xC2 +#define RK806_BUCK_SEQ_REG17 0xC3 +#define RK806_HK_TRIM_REG1 0xC4 +#define RK806_HK_TRIM_REG2 0xC5 +#define RK806_BUCK_REF_TRIM_REG1 0xC6 +#define RK806_BUCK_REF_TRIM_REG2 0xC7 +#define RK806_BUCK_REF_TRIM_REG3 0xC8 +#define RK806_BUCK_REF_TRIM_REG4 0xC9 +#define RK806_BUCK_REF_TRIM_REG5 0xCA +#define RK806_BUCK_OSC_TRIM_REG1 0xCB +#define RK806_BUCK_OSC_TRIM_REG2 0xCC +#define RK806_BUCK_OSC_TRIM_REG3 0xCD +#define RK806_BUCK_OSC_TRIM_REG4 0xCE +#define RK806_BUCK_OSC_TRIM_REG5 0xCF +#define RK806_BUCK_TRIM_ZCDIOS_REG1 0xD0 +#define RK806_BUCK_TRIM_ZCDIOS_REG2 0xD1 +#define RK806_NLDO_TRIM_REG1 0xD2 +#define RK806_NLDO_TRIM_REG2 0xD3 +#define RK806_NLDO_TRIM_REG3 0xD4 +#define RK806_PLDO_TRIM_REG1 0xD5 +#define RK806_PLDO_TRIM_REG2 0xD6 +#define RK806_PLDO_TRIM_REG3 0xD7 +#define RK806_TRIM_ICOMP_REG1 0xD8 +#define RK806_TRIM_ICOMP_REG2 0xD9 +#define RK806_EFUSE_CONTROL_REGH 0xDA +#define RK806_FUSE_PROG_REG 0xDB +#define RK806_MAIN_FSM_STS_REG 0xDD +#define RK806_FSM_REG 0xDE +#define RK806_TOP_RESEV_OFFR 0xEC +#define RK806_TOP_RESEV_POR 0xED +#define RK806_BUCK_VRSN_REG1 0xEE +#define RK806_BUCK_VRSN_REG2 0xEF +#define RK806_NLDO_RLOAD_SEL_REG1 0xF0 +#define RK806_PLDO_RLOAD_SEL_REG1 0xF1 +#define RK806_PLDO_RLOAD_SEL_REG2 0xF2 +#define RK806_BUCK_CMIN_MX_REG1 0xF3 +#define RK806_BUCK_CMIN_MX_REG2 0xF4 +#define RK806_BUCK_FREQ_SET_REG1 0xF5 +#define RK806_BUCK_FREQ_SET_REG2 0xF6 +#define RK806_BUCK_RS_MEABS_REG1 0xF7 +#define RK806_BUCK_RS_MEABS_REG2 0xF8 +#define RK806_BUCK_RS_ZDLEB_REG1 0xF9 +#define RK806_BUCK_RS_ZDLEB_REG2 0xFA +#define RK806_BUCK_RSERVE_REG1 0xFB +#define RK806_BUCK_RSERVE_REG2 0xFC +#define RK806_BUCK_RSERVE_REG3 0xFD +#define RK806_BUCK_RSERVE_REG4 0xFE +#define RK806_BUCK_RSERVE_REG5 0xFF + +/* INT_STS Register field definitions */ +#define RK806_INT_STS_PWRON_FALL BIT(0) +#define RK806_INT_STS_PWRON_RISE BIT(1) +#define RK806_INT_STS_PWRON BIT(2) +#define RK806_INT_STS_PWRON_LP BIT(3) +#define RK806_INT_STS_HOTDIE BIT(4) +#define RK806_INT_STS_VDC_RISE BIT(5) +#define RK806_INT_STS_VDC_FALL BIT(6) +#define RK806_INT_STS_VB_LO BIT(7) +#define RK806_INT_STS_REV0 BIT(0) +#define RK806_INT_STS_REV1 BIT(1) +#define RK806_INT_STS_REV2 BIT(2) +#define RK806_INT_STS_CRC_ERROR BIT(3) +#define RK806_INT_STS_SLP3_GPIO BIT(4) +#define RK806_INT_STS_SLP2_GPIO BIT(5) +#define RK806_INT_STS_SLP1_GPIO BIT(6) +#define RK806_INT_STS_WDT BIT(7) + +/* SPI command */ +#define RK806_CMD_READ 0 +#define RK806_CMD_WRITE BIT(7) +#define RK806_CMD_CRC_EN BIT(6) +#define RK806_CMD_CRC_DIS 0 +#define RK806_CMD_LEN_MSK 0x0f +#define RK806_REG_H 0x00 + +#define VERSION_AB 0x01 + +enum rk806_reg_id { + RK806_ID_DCDC1 = 0, + RK806_ID_DCDC2, + RK806_ID_DCDC3, + RK806_ID_DCDC4, + RK806_ID_DCDC5, + RK806_ID_DCDC6, + RK806_ID_DCDC7, + RK806_ID_DCDC8, + RK806_ID_DCDC9, + RK806_ID_DCDC10, + + RK806_ID_NLDO1, + RK806_ID_NLDO2, + RK806_ID_NLDO3, + RK806_ID_NLDO4, + RK806_ID_NLDO5, + + RK806_ID_PLDO1, + RK806_ID_PLDO2, + RK806_ID_PLDO3, + RK806_ID_PLDO4, + RK806_ID_PLDO5, + RK806_ID_PLDO6, + RK806_ID_END, +}; + +/* Define the RK806 IRQ numbers */ +enum rk806_irqs { + /* INT_STS0 registers */ + RK806_IRQ_PWRON_FALL, + RK806_IRQ_PWRON_RISE, + RK806_IRQ_PWRON, + RK806_IRQ_PWRON_LP, + RK806_IRQ_HOTDIE, + RK806_IRQ_VDC_RISE, + RK806_IRQ_VDC_FALL, + RK806_IRQ_VB_LO, + + /* INT_STS0 registers */ + RK806_IRQ_REV0, + RK806_IRQ_REV1, + RK806_IRQ_REV2, + RK806_IRQ_CRC_ERROR, + RK806_IRQ_SLP3_GPIO, + RK806_IRQ_SLP2_GPIO, + RK806_IRQ_SLP1_GPIO, + RK806_IRQ_WDT, +}; + +/* VCC1 Low Voltage Threshold */ +enum rk806_lv_sel { + VB_LO_SEL_2800, + VB_LO_SEL_2900, + VB_LO_SEL_3000, + VB_LO_SEL_3100, + VB_LO_SEL_3200, + VB_LO_SEL_3300, + VB_LO_SEL_3400, + VB_LO_SEL_3500, +}; + +/* System Shutdown Voltage Select */ +enum rk806_uv_sel { + VB_UV_SEL_2700, + VB_UV_SEL_2800, + VB_UV_SEL_2900, + VB_UV_SEL_3000, + VB_UV_SEL_3100, + VB_UV_SEL_3200, + VB_UV_SEL_3300, + VB_UV_SEL_3400, +}; + +/* Pin Function */ +enum rk806_pwrctrl_fun { + PWRCTRL_NULL_FUN, + PWRCTRL_SLP_FUN, + PWRCTRL_POWOFF_FUN, + PWRCTRL_RST_FUN, + PWRCTRL_DVS_FUN, + PWRCTRL_GPIO_FUN, +}; + +/* Pin Polarity */ +enum rk806_pin_level { + POL_LOW, + POL_HIGH, +}; + +enum rk806_vsel_ctr_sel { + CTR_BY_NO_EFFECT, + CTR_BY_PWRCTRL1, + CTR_BY_PWRCTRL2, + CTR_BY_PWRCTRL3, +}; + +enum rk806_dvs_ctr_sel { + CTR_SEL_NO_EFFECT, + CTR_SEL_DVS_START1, + CTR_SEL_DVS_START2, + CTR_SEL_DVS_START3, +}; + +enum rk806_pin_dr_sel { + RK806_PIN_INPUT, + RK806_PIN_OUTPUT, +}; + +#define RK806_INT_POL_MSK BIT(1) +#define RK806_INT_POL_H BIT(1) +#define RK806_INT_POL_L 0 + +#define RK806_SLAVE_RESTART_FUN_MSK BIT(1) +#define RK806_SLAVE_RESTART_FUN_EN BIT(1) +#define RK806_SLAVE_RESTART_FUN_OFF 0 + +#define RK806_SYS_ENB2_2M_MSK BIT(1) +#define RK806_SYS_ENB2_2M_EN BIT(1) +#define RK806_SYS_ENB2_2M_OFF 0 + +enum rk806_int_fun { + RK806_INT_ONLY, + RK806_INT_ADN_WKUP, +}; + +enum rk806_dvs_mode { + RK806_DVS_NOT_SUPPORT, + RK806_DVS_START1, + RK806_DVS_START2, + RK806_DVS_START3, + RK806_DVS_PWRCTRL1, + RK806_DVS_PWRCTRL2, + RK806_DVS_PWRCTRL3, + RK806_DVS_START_PWRCTR1, + RK806_DVS_START_PWRCTR2, + RK806_DVS_START_PWRCTR3, + RK806_DVS_END, +}; + /* RK808 IRQ Definitions */ #define RK808_IRQ_VOUT_LO 0 #define RK808_IRQ_VB_LO 1 @@ -780,6 +1188,7 @@ enum { enum { RK805_ID = 0x8050, + RK806_ID = 0x8060, RK808_ID = 0x0000, RK809_ID = 0x8090, RK817_ID = 0x8170, @@ -787,11 +1196,17 @@ enum { }; struct rk808 { - struct i2c_client *i2c; + struct device *dev; struct regmap_irq_chip_data *irq_data; struct regmap *regmap; long variant; const struct regmap_config *regmap_cfg; const struct regmap_irq_chip *regmap_irq_chip; }; + +void rk8xx_shutdown(struct device *dev); +int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap); +int rk8xx_suspend(struct device *dev); +int rk8xx_resume(struct device *dev); + #endif /* __LINUX_REGULATOR_RK808_H */ diff --git a/include/linux/mfd/rt5033-private.h b/include/linux/mfd/rt5033-private.h index 6bb432f6a96c..0221f806d139 100644 --- a/include/linux/mfd/rt5033-private.h +++ b/include/linux/mfd/rt5033-private.h @@ -55,21 +55,28 @@ enum rt5033_reg { }; /* RT5033 Charger state register */ -#define RT5033_CHG_STAT_MASK 0x20 +#define RT5033_CHG_STAT_TYPE_MASK 0x60 +#define RT5033_CHG_STAT_TYPE_PRE 0x20 +#define RT5033_CHG_STAT_TYPE_FAST 0x60 +#define RT5033_CHG_STAT_MASK 0x30 #define RT5033_CHG_STAT_DISCHARGING 0x00 #define RT5033_CHG_STAT_FULL 0x10 #define RT5033_CHG_STAT_CHARGING 0x20 #define RT5033_CHG_STAT_NOT_CHARGING 0x30 -#define RT5033_CHG_STAT_TYPE_MASK 0x60 -#define RT5033_CHG_STAT_TYPE_PRE 0x20 -#define RT5033_CHG_STAT_TYPE_FAST 0x60 /* RT5033 CHGCTRL1 register */ #define RT5033_CHGCTRL1_IAICR_MASK 0xe0 +#define RT5033_CHGCTRL1_TE_EN_MASK 0x08 +#define RT5033_CHGCTRL1_HZ_MASK 0x02 #define RT5033_CHGCTRL1_MODE_MASK 0x01 /* RT5033 CHGCTRL2 register */ #define RT5033_CHGCTRL2_CV_MASK 0xfc +#define RT5033_CHGCTRL2_CV_SHIFT 0x02 + +/* RT5033 DEVICE_ID register */ +#define RT5033_VENDOR_ID_MASK 0xf0 +#define RT5033_CHIP_REV_MASK 0x0f /* RT5033 CHGCTRL3 register */ #define RT5033_CHGCTRL3_CFO_EN_MASK 0x40 @@ -77,18 +84,18 @@ enum rt5033_reg { #define RT5033_CHGCTRL3_TIMER_EN_MASK 0x01 /* RT5033 CHGCTRL4 register */ -#define RT5033_CHGCTRL4_EOC_MASK 0x07 +#define RT5033_CHGCTRL4_MIVR_MASK 0xe0 #define RT5033_CHGCTRL4_IPREC_MASK 0x18 +#define RT5033_CHGCTRL4_IPREC_SHIFT 0x03 +#define RT5033_CHGCTRL4_EOC_MASK 0x07 /* RT5033 CHGCTRL5 register */ -#define RT5033_CHGCTRL5_VPREC_MASK 0x0f #define RT5033_CHGCTRL5_ICHG_MASK 0xf0 #define RT5033_CHGCTRL5_ICHG_SHIFT 0x04 -#define RT5033_CHG_MAX_CURRENT 0x0d +#define RT5033_CHGCTRL5_VPREC_MASK 0x0f /* RT5033 RT CTRL1 register */ #define RT5033_RT_CTRL1_UUG_MASK 0x02 -#define RT5033_RT_HZ_MASK 0x01 /* RT5033 control register */ #define RT5033_CTRL_FCCM_BUCK_MASK BIT(0) @@ -115,28 +122,37 @@ enum rt5033_reg { * register), AICR mode limits the input current. For example, the AIRC 100 * mode limits the input current to 100 mA. */ +#define RT5033_AICR_DISABLE 0x00 #define RT5033_AICR_100_MODE 0x20 #define RT5033_AICR_500_MODE 0x40 #define RT5033_AICR_700_MODE 0x60 #define RT5033_AICR_900_MODE 0x80 +#define RT5033_AICR_1000_MODE 0xa0 #define RT5033_AICR_1500_MODE 0xc0 #define RT5033_AICR_2000_MODE 0xe0 -#define RT5033_AICR_MODE_MASK 0xe0 -/* RT5033 use internal timer need to set time */ -#define RT5033_FAST_CHARGE_TIMER4 0x00 -#define RT5033_FAST_CHARGE_TIMER6 0x01 -#define RT5033_FAST_CHARGE_TIMER8 0x02 -#define RT5033_FAST_CHARGE_TIMER9 0x03 -#define RT5033_FAST_CHARGE_TIMER12 0x04 -#define RT5033_FAST_CHARGE_TIMER14 0x05 -#define RT5033_FAST_CHARGE_TIMER16 0x06 +/* RT5033 charger minimum input voltage regulation */ +#define RT5033_CHARGER_MIVR_DISABLE 0x00 +#define RT5033_CHARGER_MIVR_4200MV 0x20 +#define RT5033_CHARGER_MIVR_4300MV 0x40 +#define RT5033_CHARGER_MIVR_4400MV 0x60 +#define RT5033_CHARGER_MIVR_4500MV 0x80 +#define RT5033_CHARGER_MIVR_4600MV 0xa0 +#define RT5033_CHARGER_MIVR_4700MV 0xc0 +#define RT5033_CHARGER_MIVR_4800MV 0xe0 +/* RT5033 use internal timer need to set time */ +#define RT5033_FAST_CHARGE_TIMER4 0x00 /* 4 hrs */ +#define RT5033_FAST_CHARGE_TIMER6 0x08 /* 6 hrs */ +#define RT5033_FAST_CHARGE_TIMER8 0x10 /* 8 hrs */ +#define RT5033_FAST_CHARGE_TIMER10 0x18 /* 10 hrs */ +#define RT5033_FAST_CHARGE_TIMER12 0x20 /* 12 hrs */ +#define RT5033_FAST_CHARGE_TIMER14 0x28 /* 14 hrs */ +#define RT5033_FAST_CHARGE_TIMER16 0x30 /* 16 hrs */ + +#define RT5033_INT_TIMER_DISABLE 0x00 #define RT5033_INT_TIMER_ENABLE 0x01 -/* RT5033 charger termination enable mask */ -#define RT5033_TE_ENABLE_MASK 0x08 - /* * RT5033 charger opa mode. RT5033 has two opa modes for OTG: charger mode * and boost mode. @@ -145,25 +161,30 @@ enum rt5033_reg { #define RT5033_BOOST_MODE 0x01 /* RT5033 charger termination enable */ +#define RT5033_TE_DISABLE 0x00 #define RT5033_TE_ENABLE 0x08 /* RT5033 charger CFO enable */ +#define RT5033_CFO_DISABLE 0x00 #define RT5033_CFO_ENABLE 0x40 /* RT5033 charger constant charge voltage (as in CHGCTRL2 register), uV */ #define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN 3650000U #define RT5033_CHARGER_CONST_VOLTAGE_STEP_NUM 25000U #define RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX 4400000U +#define RT5033_CV_MAX_VOLTAGE 0x1e /* RT5033 charger pre-charge current limits (as in CHGCTRL4 register), uA */ #define RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN 350000U #define RT5033_CHARGER_PRE_CURRENT_STEP_NUM 100000U #define RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX 650000U +#define RT5033_CHG_MAX_PRE_CURRENT 0x03 /* RT5033 charger fast-charge current (as in CHGCTRL5 register), uA */ #define RT5033_CHARGER_FAST_CURRENT_MIN 700000U #define RT5033_CHARGER_FAST_CURRENT_STEP_NUM 100000U #define RT5033_CHARGER_FAST_CURRENT_MAX 2000000U +#define RT5033_CHG_MAX_CURRENT 0x0d /* * RT5033 charger const-charge end of charger current ( @@ -187,11 +208,12 @@ enum rt5033_reg { * RT5033 charger UUG. It enables MOS auto control by H/W charger * circuit. */ +#define RT5033_CHARGER_UUG_DISABLE 0x00 #define RT5033_CHARGER_UUG_ENABLE 0x02 /* RT5033 charger high impedance mode */ #define RT5033_CHARGER_HZ_DISABLE 0x00 -#define RT5033_CHARGER_HZ_ENABLE 0x01 +#define RT5033_CHARGER_HZ_ENABLE 0x02 /* RT5033 regulator BUCK output voltage uV */ #define RT5033_REGULATOR_BUCK_VOLTAGE_MIN 1000000U diff --git a/include/linux/mfd/rt5033.h b/include/linux/mfd/rt5033.h index 8f306ac15a27..bb3d18945d21 100644 --- a/include/linux/mfd/rt5033.h +++ b/include/linux/mfd/rt5033.h @@ -12,7 +12,6 @@ #include <linux/regulator/consumer.h> #include <linux/i2c.h> #include <linux/regmap.h> -#include <linux/power_supply.h> /* RT5033 regulator IDs */ enum rt5033_regulators { @@ -32,27 +31,4 @@ struct rt5033_dev { bool wakeup; }; -struct rt5033_battery { - struct i2c_client *client; - struct rt5033_dev *rt5033; - struct regmap *regmap; - struct power_supply *psy; -}; - -/* RT5033 charger platform data */ -struct rt5033_charger_data { - unsigned int pre_uamp; - unsigned int pre_uvolt; - unsigned int const_uvolt; - unsigned int eoc_uamp; - unsigned int fast_uamp; -}; - -struct rt5033_charger { - struct device *dev; - struct rt5033_dev *rt5033; - struct power_supply psy; - struct rt5033_charger_data *chg; -}; - #endif /* __RT5033_H__ */ diff --git a/include/linux/mfd/stpmic1.h b/include/linux/mfd/stpmic1.h index fa3f99f7e9a1..dc00bac24f5a 100644 --- a/include/linux/mfd/stpmic1.h +++ b/include/linux/mfd/stpmic1.h @@ -15,7 +15,7 @@ #define RREQ_STATE_SR 0x5 #define VERSION_SR 0x6 -#define SWOFF_PWRCTRL_CR 0x10 +#define MAIN_CR 0x10 #define PADS_PULL_CR 0x11 #define BUCKS_PD_CR 0x12 #define LDO14_PD_CR 0x13 @@ -148,14 +148,14 @@ #define LDO_BYPASS_MASK BIT(7) /* Main PMIC Control Register - * SWOFF_PWRCTRL_CR + * MAIN_CR * Address : 0x10 */ -#define ICC_EVENT_ENABLED BIT(4) +#define OCP_OFF_DBG BIT(4) #define PWRCTRL_POLARITY_HIGH BIT(3) -#define PWRCTRL_PIN_VALID BIT(2) -#define RESTART_REQUEST_ENABLED BIT(1) -#define SOFTWARE_SWITCH_OFF_ENABLED BIT(0) +#define PWRCTRL_ENABLE BIT(2) +#define RESTART_REQUEST_ENABLE BIT(1) +#define SOFTWARE_SWITCH_OFF BIT(0) /* Main PMIC PADS Control Register * PADS_PULL_CR diff --git a/include/linux/mfd/tps65010.h b/include/linux/mfd/tps65010.h index a1fb9bc5311d..5edf1aef1118 100644 --- a/include/linux/mfd/tps65010.h +++ b/include/linux/mfd/tps65010.h @@ -28,6 +28,8 @@ #ifndef __LINUX_I2C_TPS65010_H #define __LINUX_I2C_TPS65010_H +struct gpio_chip; + /* * ---------------------------------------------------------------------------- * Registers, all 8 bits @@ -176,12 +178,10 @@ struct i2c_client; /** * struct tps65010_board - packages GPIO and LED lines - * @base: the GPIO number to assign to GPIO-1 * @outmask: bit (N-1) is set to allow GPIO-N to be used as an * (open drain) output * @setup: optional callback issued once the GPIOs are valid * @teardown: optional callback issued before the GPIOs are invalidated - * @context: optional parameter passed to setup() and teardown() * * Board data may be used to package the GPIO (and LED) lines for use * in by the generic GPIO and LED frameworks. The first four GPIOs @@ -193,12 +193,9 @@ struct i2c_client; * devices in their initial states using these GPIOs. */ struct tps65010_board { - int base; unsigned outmask; - - int (*setup)(struct i2c_client *client, void *context); - int (*teardown)(struct i2c_client *client, void *context); - void *context; + int (*setup)(struct i2c_client *client, struct gpio_chip *gc); + void (*teardown)(struct i2c_client *client, struct gpio_chip *gc); }; #endif /* __LINUX_I2C_TPS65010_H */ diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h new file mode 100644 index 000000000000..3f7c5e23cd4c --- /dev/null +++ b/include/linux/mfd/tps6594.h @@ -0,0 +1,1020 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Functions to access TPS6594 Power Management IC + * + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ + */ + +#ifndef __LINUX_MFD_TPS6594_H +#define __LINUX_MFD_TPS6594_H + +#include <linux/device.h> +#include <linux/regmap.h> + +struct regmap_irq_chip_data; + +/* Chip id list */ +enum pmic_id { + TPS6594, + TPS6593, + LP8764, +}; + +/* Macro to get page index from register address */ +#define TPS6594_REG_TO_PAGE(reg) ((reg) >> 8) + +/* Registers for page 0 of TPS6594 */ +#define TPS6594_REG_DEV_REV 0x01 + +#define TPS6594_REG_NVM_CODE_1 0x02 +#define TPS6594_REG_NVM_CODE_2 0x03 + +#define TPS6594_REG_BUCKX_CTRL(buck_inst) (0x04 + ((buck_inst) << 1)) +#define TPS6594_REG_BUCKX_CONF(buck_inst) (0x05 + ((buck_inst) << 1)) +#define TPS6594_REG_BUCKX_VOUT_1(buck_inst) (0x0e + ((buck_inst) << 1)) +#define TPS6594_REG_BUCKX_VOUT_2(buck_inst) (0x0f + ((buck_inst) << 1)) +#define TPS6594_REG_BUCKX_PG_WINDOW(buck_inst) (0x18 + (buck_inst)) + +#define TPS6594_REG_LDOX_CTRL(ldo_inst) (0x1d + (ldo_inst)) +#define TPS6594_REG_LDORTC_CTRL 0x22 +#define TPS6594_REG_LDOX_VOUT(ldo_inst) (0x23 + (ldo_inst)) +#define TPS6594_REG_LDOX_PG_WINDOW(ldo_inst) (0x27 + (ldo_inst)) + +#define TPS6594_REG_VCCA_VMON_CTRL 0x2b +#define TPS6594_REG_VCCA_PG_WINDOW 0x2c +#define TPS6594_REG_VMON1_PG_WINDOW 0x2d +#define TPS6594_REG_VMON1_PG_LEVEL 0x2e +#define TPS6594_REG_VMON2_PG_WINDOW 0x2f +#define TPS6594_REG_VMON2_PG_LEVEL 0x30 + +#define TPS6594_REG_GPIOX_CONF(gpio_inst) (0x31 + (gpio_inst)) +#define TPS6594_REG_NPWRON_CONF 0x3c +#define TPS6594_REG_GPIO_OUT_1 0x3d +#define TPS6594_REG_GPIO_OUT_2 0x3e +#define TPS6594_REG_GPIO_IN_1 0x3f +#define TPS6594_REG_GPIO_IN_2 0x40 +#define TPS6594_REG_GPIOX_OUT(gpio_inst) (TPS6594_REG_GPIO_OUT_1 + (gpio_inst) / 8) +#define TPS6594_REG_GPIOX_IN(gpio_inst) (TPS6594_REG_GPIO_IN_1 + (gpio_inst) / 8) + +#define TPS6594_REG_GPIO_IN_1 0x3f +#define TPS6594_REG_GPIO_IN_2 0x40 + +#define TPS6594_REG_RAIL_SEL_1 0x41 +#define TPS6594_REG_RAIL_SEL_2 0x42 +#define TPS6594_REG_RAIL_SEL_3 0x43 + +#define TPS6594_REG_FSM_TRIG_SEL_1 0x44 +#define TPS6594_REG_FSM_TRIG_SEL_2 0x45 +#define TPS6594_REG_FSM_TRIG_MASK_1 0x46 +#define TPS6594_REG_FSM_TRIG_MASK_2 0x47 +#define TPS6594_REG_FSM_TRIG_MASK_3 0x48 + +#define TPS6594_REG_MASK_BUCK1_2 0x49 +#define TPS6594_REG_MASK_BUCK3_4 0x4a +#define TPS6594_REG_MASK_BUCK5 0x4b +#define TPS6594_REG_MASK_LDO1_2 0x4c +#define TPS6594_REG_MASK_LDO3_4 0x4d +#define TPS6594_REG_MASK_VMON 0x4e +#define TPS6594_REG_MASK_GPIO1_8_FALL 0x4f +#define TPS6594_REG_MASK_GPIO1_8_RISE 0x50 +#define TPS6594_REG_MASK_GPIO9_11 0x51 +#define TPS6594_REG_MASK_STARTUP 0x52 +#define TPS6594_REG_MASK_MISC 0x53 +#define TPS6594_REG_MASK_MODERATE_ERR 0x54 +#define TPS6594_REG_MASK_FSM_ERR 0x56 +#define TPS6594_REG_MASK_COMM_ERR 0x57 +#define TPS6594_REG_MASK_READBACK_ERR 0x58 +#define TPS6594_REG_MASK_ESM 0x59 + +#define TPS6594_REG_INT_TOP 0x5a +#define TPS6594_REG_INT_BUCK 0x5b +#define TPS6594_REG_INT_BUCK1_2 0x5c +#define TPS6594_REG_INT_BUCK3_4 0x5d +#define TPS6594_REG_INT_BUCK5 0x5e +#define TPS6594_REG_INT_LDO_VMON 0x5f +#define TPS6594_REG_INT_LDO1_2 0x60 +#define TPS6594_REG_INT_LDO3_4 0x61 +#define TPS6594_REG_INT_VMON 0x62 +#define TPS6594_REG_INT_GPIO 0x63 +#define TPS6594_REG_INT_GPIO1_8 0x64 +#define TPS6594_REG_INT_STARTUP 0x65 +#define TPS6594_REG_INT_MISC 0x66 +#define TPS6594_REG_INT_MODERATE_ERR 0x67 +#define TPS6594_REG_INT_SEVERE_ERR 0x68 +#define TPS6594_REG_INT_FSM_ERR 0x69 +#define TPS6594_REG_INT_COMM_ERR 0x6a +#define TPS6594_REG_INT_READBACK_ERR 0x6b +#define TPS6594_REG_INT_ESM 0x6c + +#define TPS6594_REG_STAT_BUCK1_2 0x6d +#define TPS6594_REG_STAT_BUCK3_4 0x6e +#define TPS6594_REG_STAT_BUCK5 0x6f +#define TPS6594_REG_STAT_LDO1_2 0x70 +#define TPS6594_REG_STAT_LDO3_4 0x71 +#define TPS6594_REG_STAT_VMON 0x72 +#define TPS6594_REG_STAT_STARTUP 0x73 +#define TPS6594_REG_STAT_MISC 0x74 +#define TPS6594_REG_STAT_MODERATE_ERR 0x75 +#define TPS6594_REG_STAT_SEVERE_ERR 0x76 +#define TPS6594_REG_STAT_READBACK_ERR 0x77 + +#define TPS6594_REG_PGOOD_SEL_1 0x78 +#define TPS6594_REG_PGOOD_SEL_2 0x79 +#define TPS6594_REG_PGOOD_SEL_3 0x7a +#define TPS6594_REG_PGOOD_SEL_4 0x7b + +#define TPS6594_REG_PLL_CTRL 0x7c + +#define TPS6594_REG_CONFIG_1 0x7d +#define TPS6594_REG_CONFIG_2 0x7e + +#define TPS6594_REG_ENABLE_DRV_REG 0x80 + +#define TPS6594_REG_MISC_CTRL 0x81 + +#define TPS6594_REG_ENABLE_DRV_STAT 0x82 + +#define TPS6594_REG_RECOV_CNT_REG_1 0x83 +#define TPS6594_REG_RECOV_CNT_REG_2 0x84 + +#define TPS6594_REG_FSM_I2C_TRIGGERS 0x85 +#define TPS6594_REG_FSM_NSLEEP_TRIGGERS 0x86 + +#define TPS6594_REG_BUCK_RESET_REG 0x87 + +#define TPS6594_REG_SPREAD_SPECTRUM_1 0x88 + +#define TPS6594_REG_FREQ_SEL 0x8a + +#define TPS6594_REG_FSM_STEP_SIZE 0x8b + +#define TPS6594_REG_LDO_RV_TIMEOUT_REG_1 0x8c +#define TPS6594_REG_LDO_RV_TIMEOUT_REG_2 0x8d + +#define TPS6594_REG_USER_SPARE_REGS 0x8e + +#define TPS6594_REG_ESM_MCU_START_REG 0x8f +#define TPS6594_REG_ESM_MCU_DELAY1_REG 0x90 +#define TPS6594_REG_ESM_MCU_DELAY2_REG 0x91 +#define TPS6594_REG_ESM_MCU_MODE_CFG 0x92 +#define TPS6594_REG_ESM_MCU_HMAX_REG 0x93 +#define TPS6594_REG_ESM_MCU_HMIN_REG 0x94 +#define TPS6594_REG_ESM_MCU_LMAX_REG 0x95 +#define TPS6594_REG_ESM_MCU_LMIN_REG 0x96 +#define TPS6594_REG_ESM_MCU_ERR_CNT_REG 0x97 +#define TPS6594_REG_ESM_SOC_START_REG 0x98 +#define TPS6594_REG_ESM_SOC_DELAY1_REG 0x99 +#define TPS6594_REG_ESM_SOC_DELAY2_REG 0x9a +#define TPS6594_REG_ESM_SOC_MODE_CFG 0x9b +#define TPS6594_REG_ESM_SOC_HMAX_REG 0x9c +#define TPS6594_REG_ESM_SOC_HMIN_REG 0x9d +#define TPS6594_REG_ESM_SOC_LMAX_REG 0x9e +#define TPS6594_REG_ESM_SOC_LMIN_REG 0x9f +#define TPS6594_REG_ESM_SOC_ERR_CNT_REG 0xa0 + +#define TPS6594_REG_REGISTER_LOCK 0xa1 + +#define TPS6594_REG_MANUFACTURING_VER 0xa6 + +#define TPS6594_REG_CUSTOMER_NVM_ID_REG 0xa7 + +#define TPS6594_REG_VMON_CONF_REG 0xa8 + +#define TPS6594_REG_SOFT_REBOOT_REG 0xab + +#define TPS6594_REG_RTC_SECONDS 0xb5 +#define TPS6594_REG_RTC_MINUTES 0xb6 +#define TPS6594_REG_RTC_HOURS 0xb7 +#define TPS6594_REG_RTC_DAYS 0xb8 +#define TPS6594_REG_RTC_MONTHS 0xb9 +#define TPS6594_REG_RTC_YEARS 0xba +#define TPS6594_REG_RTC_WEEKS 0xbb + +#define TPS6594_REG_ALARM_SECONDS 0xbc +#define TPS6594_REG_ALARM_MINUTES 0xbd +#define TPS6594_REG_ALARM_HOURS 0xbe +#define TPS6594_REG_ALARM_DAYS 0xbf +#define TPS6594_REG_ALARM_MONTHS 0xc0 +#define TPS6594_REG_ALARM_YEARS 0xc1 + +#define TPS6594_REG_RTC_CTRL_1 0xc2 +#define TPS6594_REG_RTC_CTRL_2 0xc3 +#define TPS6594_REG_RTC_STATUS 0xc4 +#define TPS6594_REG_RTC_INTERRUPTS 0xc5 +#define TPS6594_REG_RTC_COMP_LSB 0xc6 +#define TPS6594_REG_RTC_COMP_MSB 0xc7 +#define TPS6594_REG_RTC_RESET_STATUS 0xc8 + +#define TPS6594_REG_SCRATCH_PAD_REG_1 0xc9 +#define TPS6594_REG_SCRATCH_PAD_REG_2 0xca +#define TPS6594_REG_SCRATCH_PAD_REG_3 0xcb +#define TPS6594_REG_SCRATCH_PAD_REG_4 0xcc + +#define TPS6594_REG_PFSM_DELAY_REG_1 0xcd +#define TPS6594_REG_PFSM_DELAY_REG_2 0xce +#define TPS6594_REG_PFSM_DELAY_REG_3 0xcf +#define TPS6594_REG_PFSM_DELAY_REG_4 0xd0 + +/* Registers for page 1 of TPS6594 */ +#define TPS6594_REG_SERIAL_IF_CONFIG 0x11a +#define TPS6594_REG_I2C1_ID 0x122 +#define TPS6594_REG_I2C2_ID 0x123 + +/* Registers for page 4 of TPS6594 */ +#define TPS6594_REG_WD_ANSWER_REG 0x401 +#define TPS6594_REG_WD_QUESTION_ANSW_CNT 0x402 +#define TPS6594_REG_WD_WIN1_CFG 0x403 +#define TPS6594_REG_WD_WIN2_CFG 0x404 +#define TPS6594_REG_WD_LONGWIN_CFG 0x405 +#define TPS6594_REG_WD_MODE_REG 0x406 +#define TPS6594_REG_WD_QA_CFG 0x407 +#define TPS6594_REG_WD_ERR_STATUS 0x408 +#define TPS6594_REG_WD_THR_CFG 0x409 +#define TPS6594_REG_DWD_FAIL_CNT_REG 0x40a + +/* BUCKX_CTRL register field definition */ +#define TPS6594_BIT_BUCK_EN BIT(0) +#define TPS6594_BIT_BUCK_FPWM BIT(1) +#define TPS6594_BIT_BUCK_FPWM_MP BIT(2) +#define TPS6594_BIT_BUCK_VSEL BIT(3) +#define TPS6594_BIT_BUCK_VMON_EN BIT(4) +#define TPS6594_BIT_BUCK_PLDN BIT(5) +#define TPS6594_BIT_BUCK_RV_SEL BIT(7) + +/* BUCKX_CONF register field definition */ +#define TPS6594_MASK_BUCK_SLEW_RATE GENMASK(2, 0) +#define TPS6594_MASK_BUCK_ILIM GENMASK(5, 3) + +/* BUCKX_PG_WINDOW register field definition */ +#define TPS6594_MASK_BUCK_OV_THR GENMASK(2, 0) +#define TPS6594_MASK_BUCK_UV_THR GENMASK(5, 3) + +/* BUCKX VSET */ +#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0) + +/* LDOX_CTRL register field definition */ +#define TPS6594_BIT_LDO_EN BIT(0) +#define TPS6594_BIT_LDO_SLOW_RAMP BIT(1) +#define TPS6594_BIT_LDO_VMON_EN BIT(4) +#define TPS6594_MASK_LDO_PLDN GENMASK(6, 5) +#define TPS6594_BIT_LDO_RV_SEL BIT(7) + +/* LDORTC_CTRL register field definition */ +#define TPS6594_BIT_LDORTC_DIS BIT(0) + +/* LDOX_VOUT register field definition */ +#define TPS6594_MASK_LDO123_VSET GENMASK(6, 1) +#define TPS6594_MASK_LDO4_VSET GENMASK(6, 0) +#define TPS6594_BIT_LDO_BYPASS BIT(7) + +/* LDOX_PG_WINDOW register field definition */ +#define TPS6594_MASK_LDO_OV_THR GENMASK(2, 0) +#define TPS6594_MASK_LDO_UV_THR GENMASK(5, 3) + +/* VCCA_VMON_CTRL register field definition */ +#define TPS6594_BIT_VMON_EN BIT(0) +#define TPS6594_BIT_VMON1_EN BIT(1) +#define TPS6594_BIT_VMON1_RV_SEL BIT(2) +#define TPS6594_BIT_VMON2_EN BIT(3) +#define TPS6594_BIT_VMON2_RV_SEL BIT(4) +#define TPS6594_BIT_VMON_DEGLITCH_SEL BIT(5) + +/* VCCA_PG_WINDOW register field definition */ +#define TPS6594_MASK_VCCA_OV_THR GENMASK(2, 0) +#define TPS6594_MASK_VCCA_UV_THR GENMASK(5, 3) +#define TPS6594_BIT_VCCA_PG_SET BIT(6) + +/* VMONX_PG_WINDOW register field definition */ +#define TPS6594_MASK_VMONX_OV_THR GENMASK(2, 0) +#define TPS6594_MASK_VMONX_UV_THR GENMASK(5, 3) +#define TPS6594_BIT_VMONX_RANGE BIT(6) + +/* GPIOX_CONF register field definition */ +#define TPS6594_BIT_GPIO_DIR BIT(0) +#define TPS6594_BIT_GPIO_OD BIT(1) +#define TPS6594_BIT_GPIO_PU_SEL BIT(2) +#define TPS6594_BIT_GPIO_PU_PD_EN BIT(3) +#define TPS6594_BIT_GPIO_DEGLITCH_EN BIT(4) +#define TPS6594_MASK_GPIO_SEL GENMASK(7, 5) + +/* NPWRON_CONF register field definition */ +#define TPS6594_BIT_NRSTOUT_OD BIT(0) +#define TPS6594_BIT_ENABLE_PU_SEL BIT(2) +#define TPS6594_BIT_ENABLE_PU_PD_EN BIT(3) +#define TPS6594_BIT_ENABLE_DEGLITCH_EN BIT(4) +#define TPS6594_BIT_ENABLE_POL BIT(5) +#define TPS6594_MASK_NPWRON_SEL GENMASK(7, 6) + +/* GPIO_OUT_X register field definition */ +#define TPS6594_BIT_GPIOX_OUT(gpio_inst) BIT((gpio_inst) % 8) + +/* GPIO_IN_X register field definition */ +#define TPS6594_BIT_GPIOX_IN(gpio_inst) BIT((gpio_inst) % 8) +#define TPS6594_BIT_NPWRON_IN BIT(3) + +/* RAIL_SEL_1 register field definition */ +#define TPS6594_MASK_BUCK1_GRP_SEL GENMASK(1, 0) +#define TPS6594_MASK_BUCK2_GRP_SEL GENMASK(3, 2) +#define TPS6594_MASK_BUCK3_GRP_SEL GENMASK(5, 4) +#define TPS6594_MASK_BUCK4_GRP_SEL GENMASK(7, 6) + +/* RAIL_SEL_2 register field definition */ +#define TPS6594_MASK_BUCK5_GRP_SEL GENMASK(1, 0) +#define TPS6594_MASK_LDO1_GRP_SEL GENMASK(3, 2) +#define TPS6594_MASK_LDO2_GRP_SEL GENMASK(5, 4) +#define TPS6594_MASK_LDO3_GRP_SEL GENMASK(7, 6) + +/* RAIL_SEL_3 register field definition */ +#define TPS6594_MASK_LDO4_GRP_SEL GENMASK(1, 0) +#define TPS6594_MASK_VCCA_GRP_SEL GENMASK(3, 2) +#define TPS6594_MASK_VMON1_GRP_SEL GENMASK(5, 4) +#define TPS6594_MASK_VMON2_GRP_SEL GENMASK(7, 6) + +/* FSM_TRIG_SEL_1 register field definition */ +#define TPS6594_MASK_MCU_RAIL_TRIG GENMASK(1, 0) +#define TPS6594_MASK_SOC_RAIL_TRIG GENMASK(3, 2) +#define TPS6594_MASK_OTHER_RAIL_TRIG GENMASK(5, 4) +#define TPS6594_MASK_SEVERE_ERR_TRIG GENMASK(7, 6) + +/* FSM_TRIG_SEL_2 register field definition */ +#define TPS6594_MASK_MODERATE_ERR_TRIG GENMASK(1, 0) + +/* FSM_TRIG_MASK_X register field definition */ +#define TPS6594_BIT_GPIOX_FSM_MASK(gpio_inst) BIT(((gpio_inst) << 1) % 8) +#define TPS6594_BIT_GPIOX_FSM_MASK_POL(gpio_inst) BIT(((gpio_inst) << 1) % 8 + 1) + +/* MASK_BUCKX register field definition */ +#define TPS6594_BIT_BUCKX_OV_MASK(buck_inst) BIT(((buck_inst) << 2) % 8) +#define TPS6594_BIT_BUCKX_UV_MASK(buck_inst) BIT(((buck_inst) << 2) % 8 + 1) +#define TPS6594_BIT_BUCKX_ILIM_MASK(buck_inst) BIT(((buck_inst) << 2) % 8 + 3) + +/* MASK_LDOX register field definition */ +#define TPS6594_BIT_LDOX_OV_MASK(ldo_inst) BIT(((ldo_inst) << 2) % 8) +#define TPS6594_BIT_LDOX_UV_MASK(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 1) +#define TPS6594_BIT_LDOX_ILIM_MASK(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 3) + +/* MASK_VMON register field definition */ +#define TPS6594_BIT_VCCA_OV_MASK BIT(0) +#define TPS6594_BIT_VCCA_UV_MASK BIT(1) +#define TPS6594_BIT_VMON1_OV_MASK BIT(2) +#define TPS6594_BIT_VMON1_UV_MASK BIT(3) +#define TPS6594_BIT_VMON2_OV_MASK BIT(5) +#define TPS6594_BIT_VMON2_UV_MASK BIT(6) + +/* MASK_GPIOX register field definition */ +#define TPS6594_BIT_GPIOX_FALL_MASK(gpio_inst) BIT((gpio_inst) < 8 ? \ + (gpio_inst) : (gpio_inst) % 8) +#define TPS6594_BIT_GPIOX_RISE_MASK(gpio_inst) BIT((gpio_inst) < 8 ? \ + (gpio_inst) : (gpio_inst) % 8 + 3) + +/* MASK_STARTUP register field definition */ +#define TPS6594_BIT_NPWRON_START_MASK BIT(0) +#define TPS6594_BIT_ENABLE_MASK BIT(1) +#define TPS6594_BIT_FSD_MASK BIT(4) +#define TPS6594_BIT_SOFT_REBOOT_MASK BIT(5) + +/* MASK_MISC register field definition */ +#define TPS6594_BIT_BIST_PASS_MASK BIT(0) +#define TPS6594_BIT_EXT_CLK_MASK BIT(1) +#define TPS6594_BIT_TWARN_MASK BIT(3) + +/* MASK_MODERATE_ERR register field definition */ +#define TPS6594_BIT_BIST_FAIL_MASK BIT(1) +#define TPS6594_BIT_REG_CRC_ERR_MASK BIT(2) +#define TPS6594_BIT_SPMI_ERR_MASK BIT(4) +#define TPS6594_BIT_NPWRON_LONG_MASK BIT(5) +#define TPS6594_BIT_NINT_READBACK_MASK BIT(6) +#define TPS6594_BIT_NRSTOUT_READBACK_MASK BIT(7) + +/* MASK_FSM_ERR register field definition */ +#define TPS6594_BIT_IMM_SHUTDOWN_MASK BIT(0) +#define TPS6594_BIT_ORD_SHUTDOWN_MASK BIT(1) +#define TPS6594_BIT_MCU_PWR_ERR_MASK BIT(2) +#define TPS6594_BIT_SOC_PWR_ERR_MASK BIT(3) + +/* MASK_COMM_ERR register field definition */ +#define TPS6594_BIT_COMM_FRM_ERR_MASK BIT(0) +#define TPS6594_BIT_COMM_CRC_ERR_MASK BIT(1) +#define TPS6594_BIT_COMM_ADR_ERR_MASK BIT(3) +#define TPS6594_BIT_I2C2_CRC_ERR_MASK BIT(5) +#define TPS6594_BIT_I2C2_ADR_ERR_MASK BIT(7) + +/* MASK_READBACK_ERR register field definition */ +#define TPS6594_BIT_EN_DRV_READBACK_MASK BIT(0) +#define TPS6594_BIT_NRSTOUT_SOC_READBACK_MASK BIT(3) + +/* MASK_ESM register field definition */ +#define TPS6594_BIT_ESM_SOC_PIN_MASK BIT(0) +#define TPS6594_BIT_ESM_SOC_FAIL_MASK BIT(1) +#define TPS6594_BIT_ESM_SOC_RST_MASK BIT(2) +#define TPS6594_BIT_ESM_MCU_PIN_MASK BIT(3) +#define TPS6594_BIT_ESM_MCU_FAIL_MASK BIT(4) +#define TPS6594_BIT_ESM_MCU_RST_MASK BIT(5) + +/* INT_TOP register field definition */ +#define TPS6594_BIT_BUCK_INT BIT(0) +#define TPS6594_BIT_LDO_VMON_INT BIT(1) +#define TPS6594_BIT_GPIO_INT BIT(2) +#define TPS6594_BIT_STARTUP_INT BIT(3) +#define TPS6594_BIT_MISC_INT BIT(4) +#define TPS6594_BIT_MODERATE_ERR_INT BIT(5) +#define TPS6594_BIT_SEVERE_ERR_INT BIT(6) +#define TPS6594_BIT_FSM_ERR_INT BIT(7) + +/* INT_BUCK register field definition */ +#define TPS6594_BIT_BUCK1_2_INT BIT(0) +#define TPS6594_BIT_BUCK3_4_INT BIT(1) +#define TPS6594_BIT_BUCK5_INT BIT(2) + +/* INT_BUCKX register field definition */ +#define TPS6594_BIT_BUCKX_OV_INT(buck_inst) BIT(((buck_inst) << 2) % 8) +#define TPS6594_BIT_BUCKX_UV_INT(buck_inst) BIT(((buck_inst) << 2) % 8 + 1) +#define TPS6594_BIT_BUCKX_SC_INT(buck_inst) BIT(((buck_inst) << 2) % 8 + 2) +#define TPS6594_BIT_BUCKX_ILIM_INT(buck_inst) BIT(((buck_inst) << 2) % 8 + 3) + +/* INT_LDO_VMON register field definition */ +#define TPS6594_BIT_LDO1_2_INT BIT(0) +#define TPS6594_BIT_LDO3_4_INT BIT(1) +#define TPS6594_BIT_VCCA_INT BIT(4) + +/* INT_LDOX register field definition */ +#define TPS6594_BIT_LDOX_OV_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8) +#define TPS6594_BIT_LDOX_UV_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 1) +#define TPS6594_BIT_LDOX_SC_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 2) +#define TPS6594_BIT_LDOX_ILIM_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 3) + +/* INT_VMON register field definition */ +#define TPS6594_BIT_VCCA_OV_INT BIT(0) +#define TPS6594_BIT_VCCA_UV_INT BIT(1) +#define TPS6594_BIT_VMON1_OV_INT BIT(2) +#define TPS6594_BIT_VMON1_UV_INT BIT(3) +#define TPS6594_BIT_VMON1_RV_INT BIT(4) +#define TPS6594_BIT_VMON2_OV_INT BIT(5) +#define TPS6594_BIT_VMON2_UV_INT BIT(6) +#define TPS6594_BIT_VMON2_RV_INT BIT(7) + +/* INT_GPIO register field definition */ +#define TPS6594_BIT_GPIO9_INT BIT(0) +#define TPS6594_BIT_GPIO10_INT BIT(1) +#define TPS6594_BIT_GPIO11_INT BIT(2) +#define TPS6594_BIT_GPIO1_8_INT BIT(3) + +/* INT_GPIOX register field definition */ +#define TPS6594_BIT_GPIOX_INT(gpio_inst) BIT(gpio_inst) + +/* INT_STARTUP register field definition */ +#define TPS6594_BIT_NPWRON_START_INT BIT(0) +#define TPS6594_BIT_ENABLE_INT BIT(1) +#define TPS6594_BIT_RTC_INT BIT(2) +#define TPS6594_BIT_FSD_INT BIT(4) +#define TPS6594_BIT_SOFT_REBOOT_INT BIT(5) + +/* INT_MISC register field definition */ +#define TPS6594_BIT_BIST_PASS_INT BIT(0) +#define TPS6594_BIT_EXT_CLK_INT BIT(1) +#define TPS6594_BIT_TWARN_INT BIT(3) + +/* INT_MODERATE_ERR register field definition */ +#define TPS6594_BIT_TSD_ORD_INT BIT(0) +#define TPS6594_BIT_BIST_FAIL_INT BIT(1) +#define TPS6594_BIT_REG_CRC_ERR_INT BIT(2) +#define TPS6594_BIT_RECOV_CNT_INT BIT(3) +#define TPS6594_BIT_SPMI_ERR_INT BIT(4) +#define TPS6594_BIT_NPWRON_LONG_INT BIT(5) +#define TPS6594_BIT_NINT_READBACK_INT BIT(6) +#define TPS6594_BIT_NRSTOUT_READBACK_INT BIT(7) + +/* INT_SEVERE_ERR register field definition */ +#define TPS6594_BIT_TSD_IMM_INT BIT(0) +#define TPS6594_BIT_VCCA_OVP_INT BIT(1) +#define TPS6594_BIT_PFSM_ERR_INT BIT(2) + +/* INT_FSM_ERR register field definition */ +#define TPS6594_BIT_IMM_SHUTDOWN_INT BIT(0) +#define TPS6594_BIT_ORD_SHUTDOWN_INT BIT(1) +#define TPS6594_BIT_MCU_PWR_ERR_INT BIT(2) +#define TPS6594_BIT_SOC_PWR_ERR_INT BIT(3) +#define TPS6594_BIT_COMM_ERR_INT BIT(4) +#define TPS6594_BIT_READBACK_ERR_INT BIT(5) +#define TPS6594_BIT_ESM_INT BIT(6) +#define TPS6594_BIT_WD_INT BIT(7) + +/* INT_COMM_ERR register field definition */ +#define TPS6594_BIT_COMM_FRM_ERR_INT BIT(0) +#define TPS6594_BIT_COMM_CRC_ERR_INT BIT(1) +#define TPS6594_BIT_COMM_ADR_ERR_INT BIT(3) +#define TPS6594_BIT_I2C2_CRC_ERR_INT BIT(5) +#define TPS6594_BIT_I2C2_ADR_ERR_INT BIT(7) + +/* INT_READBACK_ERR register field definition */ +#define TPS6594_BIT_EN_DRV_READBACK_INT BIT(0) +#define TPS6594_BIT_NRSTOUT_SOC_READBACK_INT BIT(3) + +/* INT_ESM register field definition */ +#define TPS6594_BIT_ESM_SOC_PIN_INT BIT(0) +#define TPS6594_BIT_ESM_SOC_FAIL_INT BIT(1) +#define TPS6594_BIT_ESM_SOC_RST_INT BIT(2) +#define TPS6594_BIT_ESM_MCU_PIN_INT BIT(3) +#define TPS6594_BIT_ESM_MCU_FAIL_INT BIT(4) +#define TPS6594_BIT_ESM_MCU_RST_INT BIT(5) + +/* STAT_BUCKX register field definition */ +#define TPS6594_BIT_BUCKX_OV_STAT(buck_inst) BIT(((buck_inst) << 2) % 8) +#define TPS6594_BIT_BUCKX_UV_STAT(buck_inst) BIT(((buck_inst) << 2) % 8 + 1) +#define TPS6594_BIT_BUCKX_ILIM_STAT(buck_inst) BIT(((buck_inst) << 2) % 8 + 3) + +/* STAT_LDOX register field definition */ +#define TPS6594_BIT_LDOX_OV_STAT(ldo_inst) BIT(((ldo_inst) << 2) % 8) +#define TPS6594_BIT_LDOX_UV_STAT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 1) +#define TPS6594_BIT_LDOX_ILIM_STAT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 3) + +/* STAT_VMON register field definition */ +#define TPS6594_BIT_VCCA_OV_STAT BIT(0) +#define TPS6594_BIT_VCCA_UV_STAT BIT(1) +#define TPS6594_BIT_VMON1_OV_STAT BIT(2) +#define TPS6594_BIT_VMON1_UV_STAT BIT(3) +#define TPS6594_BIT_VMON2_OV_STAT BIT(5) +#define TPS6594_BIT_VMON2_UV_STAT BIT(6) + +/* STAT_STARTUP register field definition */ +#define TPS6594_BIT_ENABLE_STAT BIT(1) + +/* STAT_MISC register field definition */ +#define TPS6594_BIT_EXT_CLK_STAT BIT(1) +#define TPS6594_BIT_TWARN_STAT BIT(3) + +/* STAT_MODERATE_ERR register field definition */ +#define TPS6594_BIT_TSD_ORD_STAT BIT(0) + +/* STAT_SEVERE_ERR register field definition */ +#define TPS6594_BIT_TSD_IMM_STAT BIT(0) +#define TPS6594_BIT_VCCA_OVP_STAT BIT(1) + +/* STAT_READBACK_ERR register field definition */ +#define TPS6594_BIT_EN_DRV_READBACK_STAT BIT(0) +#define TPS6594_BIT_NINT_READBACK_STAT BIT(1) +#define TPS6594_BIT_NRSTOUT_READBACK_STAT BIT(2) +#define TPS6594_BIT_NRSTOUT_SOC_READBACK_STAT BIT(3) + +/* PGOOD_SEL_1 register field definition */ +#define TPS6594_MASK_PGOOD_SEL_BUCK1 GENMASK(1, 0) +#define TPS6594_MASK_PGOOD_SEL_BUCK2 GENMASK(3, 2) +#define TPS6594_MASK_PGOOD_SEL_BUCK3 GENMASK(5, 4) +#define TPS6594_MASK_PGOOD_SEL_BUCK4 GENMASK(7, 6) + +/* PGOOD_SEL_2 register field definition */ +#define TPS6594_MASK_PGOOD_SEL_BUCK5 GENMASK(1, 0) + +/* PGOOD_SEL_3 register field definition */ +#define TPS6594_MASK_PGOOD_SEL_LDO1 GENMASK(1, 0) +#define TPS6594_MASK_PGOOD_SEL_LDO2 GENMASK(3, 2) +#define TPS6594_MASK_PGOOD_SEL_LDO3 GENMASK(5, 4) +#define TPS6594_MASK_PGOOD_SEL_LDO4 GENMASK(7, 6) + +/* PGOOD_SEL_4 register field definition */ +#define TPS6594_BIT_PGOOD_SEL_VCCA BIT(0) +#define TPS6594_BIT_PGOOD_SEL_VMON1 BIT(1) +#define TPS6594_BIT_PGOOD_SEL_VMON2 BIT(2) +#define TPS6594_BIT_PGOOD_SEL_TDIE_WARN BIT(3) +#define TPS6594_BIT_PGOOD_SEL_NRSTOUT BIT(4) +#define TPS6594_BIT_PGOOD_SEL_NRSTOUT_SOC BIT(5) +#define TPS6594_BIT_PGOOD_POL BIT(6) +#define TPS6594_BIT_PGOOD_WINDOW BIT(7) + +/* PLL_CTRL register field definition */ +#define TPS6594_MASK_EXT_CLK_FREQ GENMASK(1, 0) + +/* CONFIG_1 register field definition */ +#define TPS6594_BIT_TWARN_LEVEL BIT(0) +#define TPS6594_BIT_TSD_ORD_LEVEL BIT(1) +#define TPS6594_BIT_I2C1_HS BIT(3) +#define TPS6594_BIT_I2C2_HS BIT(4) +#define TPS6594_BIT_EN_ILIM_FSM_CTRL BIT(5) +#define TPS6594_BIT_NSLEEP1_MASK BIT(6) +#define TPS6594_BIT_NSLEEP2_MASK BIT(7) + +/* CONFIG_2 register field definition */ +#define TPS6594_BIT_BB_CHARGER_EN BIT(0) +#define TPS6594_BIT_BB_ICHR BIT(1) +#define TPS6594_MASK_BB_VEOC GENMASK(3, 2) +#define TPS6594_BB_EOC_RDY BIT(7) + +/* ENABLE_DRV_REG register field definition */ +#define TPS6594_BIT_ENABLE_DRV BIT(0) + +/* MISC_CTRL register field definition */ +#define TPS6594_BIT_NRSTOUT BIT(0) +#define TPS6594_BIT_NRSTOUT_SOC BIT(1) +#define TPS6594_BIT_LPM_EN BIT(2) +#define TPS6594_BIT_CLKMON_EN BIT(3) +#define TPS6594_BIT_AMUXOUT_EN BIT(4) +#define TPS6594_BIT_SEL_EXT_CLK BIT(5) +#define TPS6594_MASK_SYNCCLKOUT_FREQ_SEL GENMASK(7, 6) + +/* ENABLE_DRV_STAT register field definition */ +#define TPS6594_BIT_EN_DRV_IN BIT(0) +#define TPS6594_BIT_NRSTOUT_IN BIT(1) +#define TPS6594_BIT_NRSTOUT_SOC_IN BIT(2) +#define TPS6594_BIT_FORCE_EN_DRV_LOW BIT(3) +#define TPS6594_BIT_SPMI_LPM_EN BIT(4) + +/* RECOV_CNT_REG_1 register field definition */ +#define TPS6594_MASK_RECOV_CNT GENMASK(3, 0) + +/* RECOV_CNT_REG_2 register field definition */ +#define TPS6594_MASK_RECOV_CNT_THR GENMASK(3, 0) +#define TPS6594_BIT_RECOV_CNT_CLR BIT(4) + +/* FSM_I2C_TRIGGERS register field definition */ +#define TPS6594_BIT_TRIGGER_I2C(bit) BIT(bit) + +/* FSM_NSLEEP_TRIGGERS register field definition */ +#define TPS6594_BIT_NSLEEP1B BIT(0) +#define TPS6594_BIT_NSLEEP2B BIT(1) + +/* BUCK_RESET_REG register field definition */ +#define TPS6594_BIT_BUCKX_RESET(buck_inst) BIT(buck_inst) + +/* SPREAD_SPECTRUM_1 register field definition */ +#define TPS6594_MASK_SS_DEPTH GENMASK(1, 0) +#define TPS6594_BIT_SS_EN BIT(2) + +/* FREQ_SEL register field definition */ +#define TPS6594_BIT_BUCKX_FREQ_SEL(buck_inst) BIT(buck_inst) + +/* FSM_STEP_SIZE register field definition */ +#define TPS6594_MASK_PFSM_DELAY_STEP GENMASK(4, 0) + +/* LDO_RV_TIMEOUT_REG_1 register field definition */ +#define TPS6594_MASK_LDO1_RV_TIMEOUT GENMASK(3, 0) +#define TPS6594_MASK_LDO2_RV_TIMEOUT GENMASK(7, 4) + +/* LDO_RV_TIMEOUT_REG_2 register field definition */ +#define TPS6594_MASK_LDO3_RV_TIMEOUT GENMASK(3, 0) +#define TPS6594_MASK_LDO4_RV_TIMEOUT GENMASK(7, 4) + +/* USER_SPARE_REGS register field definition */ +#define TPS6594_BIT_USER_SPARE(bit) BIT(bit) + +/* ESM_MCU_START_REG register field definition */ +#define TPS6594_BIT_ESM_MCU_START BIT(0) + +/* ESM_MCU_MODE_CFG register field definition */ +#define TPS6594_MASK_ESM_MCU_ERR_CNT_TH GENMASK(3, 0) +#define TPS6594_BIT_ESM_MCU_ENDRV BIT(5) +#define TPS6594_BIT_ESM_MCU_EN BIT(6) +#define TPS6594_BIT_ESM_MCU_MODE BIT(7) + +/* ESM_MCU_ERR_CNT_REG register field definition */ +#define TPS6594_MASK_ESM_MCU_ERR_CNT GENMASK(4, 0) + +/* ESM_SOC_START_REG register field definition */ +#define TPS6594_BIT_ESM_SOC_START BIT(0) + +/* ESM_SOC_MODE_CFG register field definition */ +#define TPS6594_MASK_ESM_SOC_ERR_CNT_TH GENMASK(3, 0) +#define TPS6594_BIT_ESM_SOC_ENDRV BIT(5) +#define TPS6594_BIT_ESM_SOC_EN BIT(6) +#define TPS6594_BIT_ESM_SOC_MODE BIT(7) + +/* ESM_SOC_ERR_CNT_REG register field definition */ +#define TPS6594_MASK_ESM_SOC_ERR_CNT GENMASK(4, 0) + +/* REGISTER_LOCK register field definition */ +#define TPS6594_BIT_REGISTER_LOCK_STATUS BIT(0) + +/* VMON_CONF register field definition */ +#define TPS6594_MASK_VMON1_SLEW_RATE GENMASK(2, 0) +#define TPS6594_MASK_VMON2_SLEW_RATE GENMASK(5, 3) + +/* SOFT_REBOOT_REG register field definition */ +#define TPS6594_BIT_SOFT_REBOOT BIT(0) + +/* RTC_SECONDS & ALARM_SECONDS register field definition */ +#define TPS6594_MASK_SECOND_0 GENMASK(3, 0) +#define TPS6594_MASK_SECOND_1 GENMASK(6, 4) + +/* RTC_MINUTES & ALARM_MINUTES register field definition */ +#define TPS6594_MASK_MINUTE_0 GENMASK(3, 0) +#define TPS6594_MASK_MINUTE_1 GENMASK(6, 4) + +/* RTC_HOURS & ALARM_HOURS register field definition */ +#define TPS6594_MASK_HOUR_0 GENMASK(3, 0) +#define TPS6594_MASK_HOUR_1 GENMASK(5, 4) +#define TPS6594_BIT_PM_NAM BIT(7) + +/* RTC_DAYS & ALARM_DAYS register field definition */ +#define TPS6594_MASK_DAY_0 GENMASK(3, 0) +#define TPS6594_MASK_DAY_1 GENMASK(5, 4) + +/* RTC_MONTHS & ALARM_MONTHS register field definition */ +#define TPS6594_MASK_MONTH_0 GENMASK(3, 0) +#define TPS6594_BIT_MONTH_1 BIT(4) + +/* RTC_YEARS & ALARM_YEARS register field definition */ +#define TPS6594_MASK_YEAR_0 GENMASK(3, 0) +#define TPS6594_MASK_YEAR_1 GENMASK(7, 4) + +/* RTC_WEEKS register field definition */ +#define TPS6594_MASK_WEEK GENMASK(2, 0) + +/* RTC_CTRL_1 register field definition */ +#define TPS6594_BIT_STOP_RTC BIT(0) +#define TPS6594_BIT_ROUND_30S BIT(1) +#define TPS6594_BIT_AUTO_COMP BIT(2) +#define TPS6594_BIT_MODE_12_24 BIT(3) +#define TPS6594_BIT_SET_32_COUNTER BIT(5) +#define TPS6594_BIT_GET_TIME BIT(6) +#define TPS6594_BIT_RTC_V_OPT BIT(7) + +/* RTC_CTRL_2 register field definition */ +#define TPS6594_BIT_XTAL_EN BIT(0) +#define TPS6594_MASK_XTAL_SEL GENMASK(2, 1) +#define TPS6594_BIT_LP_STANDBY_SEL BIT(3) +#define TPS6594_BIT_FAST_BIST BIT(4) +#define TPS6594_MASK_STARTUP_DEST GENMASK(6, 5) +#define TPS6594_BIT_FIRST_STARTUP_DONE BIT(7) + +/* RTC_STATUS register field definition */ +#define TPS6594_BIT_RUN BIT(1) +#define TPS6594_BIT_TIMER BIT(5) +#define TPS6594_BIT_ALARM BIT(6) +#define TPS6594_BIT_POWER_UP BIT(7) + +/* RTC_INTERRUPTS register field definition */ +#define TPS6594_MASK_EVERY GENMASK(1, 0) +#define TPS6594_BIT_IT_TIMER BIT(2) +#define TPS6594_BIT_IT_ALARM BIT(3) + +/* RTC_RESET_STATUS register field definition */ +#define TPS6594_BIT_RESET_STATUS_RTC BIT(0) + +/* SERIAL_IF_CONFIG register field definition */ +#define TPS6594_BIT_I2C_SPI_SEL BIT(0) +#define TPS6594_BIT_I2C1_SPI_CRC_EN BIT(1) +#define TPS6594_BIT_I2C2_CRC_EN BIT(2) +#define TPS6594_MASK_T_CRC GENMASK(7, 3) + +/* WD_QUESTION_ANSW_CNT register field definition */ +#define TPS6594_MASK_WD_QUESTION GENMASK(3, 0) +#define TPS6594_MASK_WD_ANSW_CNT GENMASK(5, 4) + +/* WD_MODE_REG register field definition */ +#define TPS6594_BIT_WD_RETURN_LONGWIN BIT(0) +#define TPS6594_BIT_WD_MODE_SELECT BIT(1) +#define TPS6594_BIT_WD_PWRHOLD BIT(2) + +/* WD_QA_CFG register field definition */ +#define TPS6594_MASK_WD_QUESTION_SEED GENMASK(3, 0) +#define TPS6594_MASK_WD_QA_LFSR GENMASK(5, 4) +#define TPS6594_MASK_WD_QA_FDBK GENMASK(7, 6) + +/* WD_ERR_STATUS register field definition */ +#define TPS6594_BIT_WD_LONGWIN_TIMEOUT_INT BIT(0) +#define TPS6594_BIT_WD_TIMEOUT BIT(1) +#define TPS6594_BIT_WD_TRIG_EARLY BIT(2) +#define TPS6594_BIT_WD_ANSW_EARLY BIT(3) +#define TPS6594_BIT_WD_SEQ_ERR BIT(4) +#define TPS6594_BIT_WD_ANSW_ERR BIT(5) +#define TPS6594_BIT_WD_FAIL_INT BIT(6) +#define TPS6594_BIT_WD_RST_INT BIT(7) + +/* WD_THR_CFG register field definition */ +#define TPS6594_MASK_WD_RST_TH GENMASK(2, 0) +#define TPS6594_MASK_WD_FAIL_TH GENMASK(5, 3) +#define TPS6594_BIT_WD_EN BIT(6) +#define TPS6594_BIT_WD_RST_EN BIT(7) + +/* WD_FAIL_CNT_REG register field definition */ +#define TPS6594_MASK_WD_FAIL_CNT GENMASK(3, 0) +#define TPS6594_BIT_WD_FIRST_OK BIT(5) +#define TPS6594_BIT_WD_BAD_EVENT BIT(6) + +/* CRC8 polynomial for I2C & SPI protocols */ +#define TPS6594_CRC8_POLYNOMIAL 0x07 + +/* IRQs */ +enum tps6594_irqs { + /* INT_BUCK1_2 register */ + TPS6594_IRQ_BUCK1_OV, + TPS6594_IRQ_BUCK1_UV, + TPS6594_IRQ_BUCK1_SC, + TPS6594_IRQ_BUCK1_ILIM, + TPS6594_IRQ_BUCK2_OV, + TPS6594_IRQ_BUCK2_UV, + TPS6594_IRQ_BUCK2_SC, + TPS6594_IRQ_BUCK2_ILIM, + /* INT_BUCK3_4 register */ + TPS6594_IRQ_BUCK3_OV, + TPS6594_IRQ_BUCK3_UV, + TPS6594_IRQ_BUCK3_SC, + TPS6594_IRQ_BUCK3_ILIM, + TPS6594_IRQ_BUCK4_OV, + TPS6594_IRQ_BUCK4_UV, + TPS6594_IRQ_BUCK4_SC, + TPS6594_IRQ_BUCK4_ILIM, + /* INT_BUCK5 register */ + TPS6594_IRQ_BUCK5_OV, + TPS6594_IRQ_BUCK5_UV, + TPS6594_IRQ_BUCK5_SC, + TPS6594_IRQ_BUCK5_ILIM, + /* INT_LDO1_2 register */ + TPS6594_IRQ_LDO1_OV, + TPS6594_IRQ_LDO1_UV, + TPS6594_IRQ_LDO1_SC, + TPS6594_IRQ_LDO1_ILIM, + TPS6594_IRQ_LDO2_OV, + TPS6594_IRQ_LDO2_UV, + TPS6594_IRQ_LDO2_SC, + TPS6594_IRQ_LDO2_ILIM, + /* INT_LDO3_4 register */ + TPS6594_IRQ_LDO3_OV, + TPS6594_IRQ_LDO3_UV, + TPS6594_IRQ_LDO3_SC, + TPS6594_IRQ_LDO3_ILIM, + TPS6594_IRQ_LDO4_OV, + TPS6594_IRQ_LDO4_UV, + TPS6594_IRQ_LDO4_SC, + TPS6594_IRQ_LDO4_ILIM, + /* INT_VMON register */ + TPS6594_IRQ_VCCA_OV, + TPS6594_IRQ_VCCA_UV, + TPS6594_IRQ_VMON1_OV, + TPS6594_IRQ_VMON1_UV, + TPS6594_IRQ_VMON1_RV, + TPS6594_IRQ_VMON2_OV, + TPS6594_IRQ_VMON2_UV, + TPS6594_IRQ_VMON2_RV, + /* INT_GPIO register */ + TPS6594_IRQ_GPIO9, + TPS6594_IRQ_GPIO10, + TPS6594_IRQ_GPIO11, + /* INT_GPIO1_8 register */ + TPS6594_IRQ_GPIO1, + TPS6594_IRQ_GPIO2, + TPS6594_IRQ_GPIO3, + TPS6594_IRQ_GPIO4, + TPS6594_IRQ_GPIO5, + TPS6594_IRQ_GPIO6, + TPS6594_IRQ_GPIO7, + TPS6594_IRQ_GPIO8, + /* INT_STARTUP register */ + TPS6594_IRQ_NPWRON_START, + TPS6594_IRQ_ENABLE, + TPS6594_IRQ_FSD, + TPS6594_IRQ_SOFT_REBOOT, + /* INT_MISC register */ + TPS6594_IRQ_BIST_PASS, + TPS6594_IRQ_EXT_CLK, + TPS6594_IRQ_TWARN, + /* INT_MODERATE_ERR register */ + TPS6594_IRQ_TSD_ORD, + TPS6594_IRQ_BIST_FAIL, + TPS6594_IRQ_REG_CRC_ERR, + TPS6594_IRQ_RECOV_CNT, + TPS6594_IRQ_SPMI_ERR, + TPS6594_IRQ_NPWRON_LONG, + TPS6594_IRQ_NINT_READBACK, + TPS6594_IRQ_NRSTOUT_READBACK, + /* INT_SEVERE_ERR register */ + TPS6594_IRQ_TSD_IMM, + TPS6594_IRQ_VCCA_OVP, + TPS6594_IRQ_PFSM_ERR, + /* INT_FSM_ERR register */ + TPS6594_IRQ_IMM_SHUTDOWN, + TPS6594_IRQ_ORD_SHUTDOWN, + TPS6594_IRQ_MCU_PWR_ERR, + TPS6594_IRQ_SOC_PWR_ERR, + /* INT_COMM_ERR register */ + TPS6594_IRQ_COMM_FRM_ERR, + TPS6594_IRQ_COMM_CRC_ERR, + TPS6594_IRQ_COMM_ADR_ERR, + TPS6594_IRQ_I2C2_CRC_ERR, + TPS6594_IRQ_I2C2_ADR_ERR, + /* INT_READBACK_ERR register */ + TPS6594_IRQ_EN_DRV_READBACK, + TPS6594_IRQ_NRSTOUT_SOC_READBACK, + /* INT_ESM register */ + TPS6594_IRQ_ESM_SOC_PIN, + TPS6594_IRQ_ESM_SOC_FAIL, + TPS6594_IRQ_ESM_SOC_RST, + /* RTC_STATUS register */ + TPS6594_IRQ_TIMER, + TPS6594_IRQ_ALARM, + TPS6594_IRQ_POWER_UP, +}; + +#define TPS6594_IRQ_NAME_BUCK1_OV "buck1_ov" +#define TPS6594_IRQ_NAME_BUCK1_UV "buck1_uv" +#define TPS6594_IRQ_NAME_BUCK1_SC "buck1_sc" +#define TPS6594_IRQ_NAME_BUCK1_ILIM "buck1_ilim" +#define TPS6594_IRQ_NAME_BUCK2_OV "buck2_ov" +#define TPS6594_IRQ_NAME_BUCK2_UV "buck2_uv" +#define TPS6594_IRQ_NAME_BUCK2_SC "buck2_sc" +#define TPS6594_IRQ_NAME_BUCK2_ILIM "buck2_ilim" +#define TPS6594_IRQ_NAME_BUCK3_OV "buck3_ov" +#define TPS6594_IRQ_NAME_BUCK3_UV "buck3_uv" +#define TPS6594_IRQ_NAME_BUCK3_SC "buck3_sc" +#define TPS6594_IRQ_NAME_BUCK3_ILIM "buck3_ilim" +#define TPS6594_IRQ_NAME_BUCK4_OV "buck4_ov" +#define TPS6594_IRQ_NAME_BUCK4_UV "buck4_uv" +#define TPS6594_IRQ_NAME_BUCK4_SC "buck4_sc" +#define TPS6594_IRQ_NAME_BUCK4_ILIM "buck4_ilim" +#define TPS6594_IRQ_NAME_BUCK5_OV "buck5_ov" +#define TPS6594_IRQ_NAME_BUCK5_UV "buck5_uv" +#define TPS6594_IRQ_NAME_BUCK5_SC "buck5_sc" +#define TPS6594_IRQ_NAME_BUCK5_ILIM "buck5_ilim" +#define TPS6594_IRQ_NAME_LDO1_OV "ldo1_ov" +#define TPS6594_IRQ_NAME_LDO1_UV "ldo1_uv" +#define TPS6594_IRQ_NAME_LDO1_SC "ldo1_sc" +#define TPS6594_IRQ_NAME_LDO1_ILIM "ldo1_ilim" +#define TPS6594_IRQ_NAME_LDO2_OV "ldo2_ov" +#define TPS6594_IRQ_NAME_LDO2_UV "ldo2_uv" +#define TPS6594_IRQ_NAME_LDO2_SC "ldo2_sc" +#define TPS6594_IRQ_NAME_LDO2_ILIM "ldo2_ilim" +#define TPS6594_IRQ_NAME_LDO3_OV "ldo3_ov" +#define TPS6594_IRQ_NAME_LDO3_UV "ldo3_uv" +#define TPS6594_IRQ_NAME_LDO3_SC "ldo3_sc" +#define TPS6594_IRQ_NAME_LDO3_ILIM "ldo3_ilim" +#define TPS6594_IRQ_NAME_LDO4_OV "ldo4_ov" +#define TPS6594_IRQ_NAME_LDO4_UV "ldo4_uv" +#define TPS6594_IRQ_NAME_LDO4_SC "ldo4_sc" +#define TPS6594_IRQ_NAME_LDO4_ILIM "ldo4_ilim" +#define TPS6594_IRQ_NAME_VCCA_OV "vcca_ov" +#define TPS6594_IRQ_NAME_VCCA_UV "vcca_uv" +#define TPS6594_IRQ_NAME_VMON1_OV "vmon1_ov" +#define TPS6594_IRQ_NAME_VMON1_UV "vmon1_uv" +#define TPS6594_IRQ_NAME_VMON1_RV "vmon1_rv" +#define TPS6594_IRQ_NAME_VMON2_OV "vmon2_ov" +#define TPS6594_IRQ_NAME_VMON2_UV "vmon2_uv" +#define TPS6594_IRQ_NAME_VMON2_RV "vmon2_rv" +#define TPS6594_IRQ_NAME_GPIO9 "gpio9" +#define TPS6594_IRQ_NAME_GPIO10 "gpio10" +#define TPS6594_IRQ_NAME_GPIO11 "gpio11" +#define TPS6594_IRQ_NAME_GPIO1 "gpio1" +#define TPS6594_IRQ_NAME_GPIO2 "gpio2" +#define TPS6594_IRQ_NAME_GPIO3 "gpio3" +#define TPS6594_IRQ_NAME_GPIO4 "gpio4" +#define TPS6594_IRQ_NAME_GPIO5 "gpio5" +#define TPS6594_IRQ_NAME_GPIO6 "gpio6" +#define TPS6594_IRQ_NAME_GPIO7 "gpio7" +#define TPS6594_IRQ_NAME_GPIO8 "gpio8" +#define TPS6594_IRQ_NAME_NPWRON_START "npwron_start" +#define TPS6594_IRQ_NAME_ENABLE "enable" +#define TPS6594_IRQ_NAME_FSD "fsd" +#define TPS6594_IRQ_NAME_SOFT_REBOOT "soft_reboot" +#define TPS6594_IRQ_NAME_BIST_PASS "bist_pass" +#define TPS6594_IRQ_NAME_EXT_CLK "ext_clk" +#define TPS6594_IRQ_NAME_TWARN "twarn" +#define TPS6594_IRQ_NAME_TSD_ORD "tsd_ord" +#define TPS6594_IRQ_NAME_BIST_FAIL "bist_fail" +#define TPS6594_IRQ_NAME_REG_CRC_ERR "reg_crc_err" +#define TPS6594_IRQ_NAME_RECOV_CNT "recov_cnt" +#define TPS6594_IRQ_NAME_SPMI_ERR "spmi_err" +#define TPS6594_IRQ_NAME_NPWRON_LONG "npwron_long" +#define TPS6594_IRQ_NAME_NINT_READBACK "nint_readback" +#define TPS6594_IRQ_NAME_NRSTOUT_READBACK "nrstout_readback" +#define TPS6594_IRQ_NAME_TSD_IMM "tsd_imm" +#define TPS6594_IRQ_NAME_VCCA_OVP "vcca_ovp" +#define TPS6594_IRQ_NAME_PFSM_ERR "pfsm_err" +#define TPS6594_IRQ_NAME_IMM_SHUTDOWN "imm_shutdown" +#define TPS6594_IRQ_NAME_ORD_SHUTDOWN "ord_shutdown" +#define TPS6594_IRQ_NAME_MCU_PWR_ERR "mcu_pwr_err" +#define TPS6594_IRQ_NAME_SOC_PWR_ERR "soc_pwr_err" +#define TPS6594_IRQ_NAME_COMM_FRM_ERR "comm_frm_err" +#define TPS6594_IRQ_NAME_COMM_CRC_ERR "comm_crc_err" +#define TPS6594_IRQ_NAME_COMM_ADR_ERR "comm_adr_err" +#define TPS6594_IRQ_NAME_EN_DRV_READBACK "en_drv_readback" +#define TPS6594_IRQ_NAME_NRSTOUT_SOC_READBACK "nrstout_soc_readback" +#define TPS6594_IRQ_NAME_ESM_SOC_PIN "esm_soc_pin" +#define TPS6594_IRQ_NAME_ESM_SOC_FAIL "esm_soc_fail" +#define TPS6594_IRQ_NAME_ESM_SOC_RST "esm_soc_rst" +#define TPS6594_IRQ_NAME_TIMER "timer" +#define TPS6594_IRQ_NAME_ALARM "alarm" +#define TPS6594_IRQ_NAME_POWERUP "powerup" + +/** + * struct tps6594 - device private data structure + * + * @dev: MFD parent device + * @chip_id: chip ID + * @reg: I2C slave address or SPI chip select number + * @use_crc: if true, use CRC for I2C and SPI interface protocols + * @regmap: regmap for accessing the device registers + * @irq: irq generated by the device + * @irq_data: regmap irq data used for the irq chip + */ +struct tps6594 { + struct device *dev; + unsigned long chip_id; + unsigned short reg; + bool use_crc; + struct regmap *regmap; + int irq; + struct regmap_irq_chip_data *irq_data; +}; + +bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg); +int tps6594_device_init(struct tps6594 *tps, bool enable_crc); + +#endif /* __LINUX_MFD_TPS6594_H */ diff --git a/include/linux/mfd/twl.h b/include/linux/mfd/twl.h index 6e3d99b7a0ee..c062d91a67d9 100644 --- a/include/linux/mfd/twl.h +++ b/include/linux/mfd/twl.h @@ -593,9 +593,6 @@ struct twl4030_gpio_platform_data { */ u32 pullups; u32 pulldowns; - - int (*setup)(struct device *dev, - unsigned gpio, unsigned ngpio); }; struct twl4030_madc_platform_data { diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 6241a1596a75..711dd9412561 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -7,8 +7,8 @@ #include <linux/migrate_mode.h> #include <linux/hugetlb.h> -typedef struct page *new_page_t(struct page *page, unsigned long private); -typedef void free_page_t(struct page *page, unsigned long private); +typedef struct folio *new_folio_t(struct folio *folio, unsigned long private); +typedef void free_folio_t(struct folio *folio, unsigned long private); struct migration_target_control; @@ -67,16 +67,16 @@ int migrate_folio_extra(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode, int extra_count); int migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode); -int migrate_pages(struct list_head *l, new_page_t new, free_page_t free, +int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free, unsigned long private, enum migrate_mode mode, int reason, unsigned int *ret_succeeded); -struct page *alloc_migration_target(struct page *page, unsigned long private); +struct folio *alloc_migration_target(struct folio *src, unsigned long private); bool isolate_movable_page(struct page *page, isolate_mode_t mode); int migrate_huge_page_move_mapping(struct address_space *mapping, struct folio *dst, struct folio *src); -void migration_entry_wait_on_locked(swp_entry_t entry, pte_t *ptep, - spinlock_t *ptl); +void migration_entry_wait_on_locked(swp_entry_t entry, spinlock_t *ptl) + __releases(ptl); void folio_migrate_flags(struct folio *newfolio, struct folio *folio); void folio_migrate_copy(struct folio *newfolio, struct folio *folio); int folio_migrate_mapping(struct address_space *mapping, @@ -85,11 +85,11 @@ int folio_migrate_mapping(struct address_space *mapping, #else static inline void putback_movable_pages(struct list_head *l) {} -static inline int migrate_pages(struct list_head *l, new_page_t new, - free_page_t free, unsigned long private, enum migrate_mode mode, - int reason, unsigned int *ret_succeeded) +static inline int migrate_pages(struct list_head *l, new_folio_t new, + free_folio_t free, unsigned long private, + enum migrate_mode mode, int reason, unsigned int *ret_succeeded) { return -ENOSYS; } -static inline struct page *alloc_migration_target(struct page *page, +static inline struct folio *alloc_migration_target(struct folio *src, unsigned long private) { return NULL; } static inline bool isolate_movable_page(struct page *page, isolate_mode_t mode) diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index c0af74efd3cb..80cc12a9a531 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -716,6 +716,7 @@ enum sync_rst_state_type { MLX5_SYNC_RST_STATE_RESET_REQUEST = 0x0, MLX5_SYNC_RST_STATE_RESET_NOW = 0x1, MLX5_SYNC_RST_STATE_RESET_ABORT = 0x2, + MLX5_SYNC_RST_STATE_RESET_UNLOAD = 0x3, }; struct mlx5_eqe_sync_fw_update { diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index a4c4f737f9c1..25d0528f9219 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -382,7 +382,6 @@ enum mlx5_res_type { MLX5_RES_SRQ = 3, MLX5_RES_XSRQ = 4, MLX5_RES_XRQ = 5, - MLX5_RES_DCT = MLX5_EVENT_QUEUE_TYPE_DCT, }; struct mlx5_core_rsc_common { @@ -443,15 +442,6 @@ struct mlx5_core_health { struct delayed_work update_fw_log_ts_work; }; -struct mlx5_qp_table { - struct notifier_block nb; - - /* protect radix tree - */ - spinlock_t lock; - struct radix_tree_root tree; -}; - enum { MLX5_PF_NOTIFY_DISABLE_VF, MLX5_PF_NOTIFY_ENABLE_VF, @@ -474,6 +464,7 @@ struct mlx5_core_sriov { struct mlx5_vf_context *vfs_ctx; int num_vfs; u16 max_vfs; + u16 max_ec_vfs; }; struct mlx5_fc_pool { @@ -580,6 +571,7 @@ enum mlx5_func_type { MLX5_VF, MLX5_SF, MLX5_HOST_PF, + MLX5_EC_VF, MLX5_FUNC_TYPE_NUM, }; @@ -1093,6 +1085,7 @@ void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev); int mlx5_core_create_psv(struct mlx5_core_dev *dev, u32 pdn, int npsvs, u32 *sig_index); int mlx5_core_destroy_psv(struct mlx5_core_dev *dev, int psv_num); +__be32 mlx5_core_get_terminate_scatter_list_mkey(struct mlx5_core_dev *dev); void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common); int mlx5_query_odp_caps(struct mlx5_core_dev *dev, struct mlx5_odp_caps *odp_caps); @@ -1173,7 +1166,13 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, u64 *values, int num_counters, size_t *offsets); -struct mlx5_core_dev *mlx5_lag_get_peer_mdev(struct mlx5_core_dev *dev); +struct mlx5_core_dev *mlx5_lag_get_next_peer_mdev(struct mlx5_core_dev *dev, int *i); + +#define mlx5_lag_for_each_peer_mdev(dev, peer, i) \ + for (i = 0, peer = mlx5_lag_get_next_peer_mdev(dev, &i); \ + peer; \ + peer = mlx5_lag_get_next_peer_mdev(dev, &i)) + u8 mlx5_lag_get_num_ports(struct mlx5_core_dev *dev); struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev); void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up); @@ -1237,6 +1236,23 @@ static inline u16 mlx5_core_max_vfs(const struct mlx5_core_dev *dev) return dev->priv.sriov.max_vfs; } +static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev) +{ + /* LACP owner conditions: + * 1) Function is physical. + * 2) LAG is supported by FW. + * 3) LAG is managed by driver (currently the only option). + */ + return MLX5_CAP_GEN(dev, vport_group_manager) && + (MLX5_CAP_GEN(dev, num_lag_ports) > 1) && + MLX5_CAP_GEN(dev, lag_master); +} + +static inline u16 mlx5_core_max_ec_vfs(const struct mlx5_core_dev *dev) +{ + return dev->priv.sriov.max_ec_vfs; +} + static inline int mlx5_get_gid_table_len(u16 param) { if (param > 4) { diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index dc5e2cb302a5..33344a71c3e3 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1705,12 +1705,14 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 rc[0x1]; u8 uar_4k[0x1]; - u8 reserved_at_241[0x9]; + u8 reserved_at_241[0x7]; + u8 fl_rc_qp_when_roce_disabled[0x1]; + u8 regexp_params[0x1]; u8 uar_sz[0x6]; u8 port_selection_cap[0x1]; - u8 reserved_at_248[0x1]; + u8 reserved_at_251[0x1]; u8 umem_uid_0[0x1]; - u8 reserved_at_250[0x5]; + u8 reserved_at_253[0x5]; u8 log_pg_sz[0x8]; u8 bf[0x1]; @@ -1753,7 +1755,10 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_328[0x2]; u8 relaxed_ordering_read[0x1]; u8 log_max_pd[0x5]; - u8 reserved_at_330[0x9]; + u8 reserved_at_330[0x6]; + u8 pci_sync_for_fw_update_with_driver_unload[0x1]; + u8 vnic_env_cnt_steering_fail[0x1]; + u8 vport_counter_local_loopback[0x1]; u8 q_counter_aggregation[0x1]; u8 q_counter_other_vport[0x1]; u8 log_max_xrcd[0x5]; @@ -1988,7 +1993,10 @@ struct mlx5_ifc_cmd_hca_cap_2_bits { u8 ts_cqe_metadata_size2wqe_counter[0x5]; u8 reserved_at_250[0x10]; - u8 reserved_at_260[0x5a0]; + u8 reserved_at_260[0x120]; + u8 reserved_at_380[0x10]; + u8 ec_vf_vport_base[0x10]; + u8 reserved_at_3a0[0x460]; }; enum mlx5_ifc_flow_destination_type { @@ -3110,7 +3118,9 @@ struct mlx5_ifc_dtor_reg_bits { struct mlx5_ifc_default_timeout_bits reclaim_vfs_pages_to; - u8 reserved_at_1c0[0x40]; + struct mlx5_ifc_default_timeout_bits reset_unload_to; + + u8 reserved_at_1c0[0x20]; }; enum { @@ -3671,7 +3681,13 @@ struct mlx5_ifc_vnic_diagnostic_statistics_bits { u8 eth_wqe_too_small[0x20]; - u8 reserved_at_220[0xdc0]; + u8 reserved_at_220[0xc0]; + + u8 generated_pkt_steering_fail[0x40]; + + u8 handled_pkt_steering_fail[0x40]; + + u8 reserved_at_360[0xc80]; }; struct mlx5_ifc_traffic_counter_bits { @@ -4795,7 +4811,8 @@ struct mlx5_ifc_set_hca_cap_in_bits { u8 op_mod[0x10]; u8 other_function[0x1]; - u8 reserved_at_41[0xf]; + u8 ec_vf_function[0x1]; + u8 reserved_at_42[0xe]; u8 function_id[0x10]; u8 reserved_at_60[0x20]; @@ -5173,7 +5190,9 @@ struct mlx5_ifc_query_vport_counter_out_bits { struct mlx5_ifc_traffic_counter_bits transmitted_eth_multicast; - u8 reserved_at_680[0xa00]; + struct mlx5_ifc_traffic_counter_bits local_loopback; + + u8 reserved_at_700[0x980]; }; enum { @@ -5946,7 +5965,8 @@ struct mlx5_ifc_query_hca_cap_in_bits { u8 op_mod[0x10]; u8 other_function[0x1]; - u8 reserved_at_41[0xf]; + u8 ec_vf_function[0x1]; + u8 reserved_at_42[0xe]; u8 function_id[0x10]; u8 reserved_at_60[0x20]; diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h index 7f31432f44c2..fbb9bf447889 100644 --- a/include/linux/mlx5/vport.h +++ b/include/linux/mlx5/vport.h @@ -132,6 +132,6 @@ int mlx5_nic_vport_affiliate_multiport(struct mlx5_core_dev *master_mdev, int mlx5_nic_vport_unaffiliate_multiport(struct mlx5_core_dev *port_mdev); u64 mlx5_query_nic_system_image_guid(struct mlx5_core_dev *mdev); -int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out, +int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 vport, void *out, u16 opmod); #endif /* __MLX5_VPORT_H__ */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 27ce77080c79..2dd73e4f3d8e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -377,7 +377,7 @@ extern unsigned int kobjsize(const void *objp); #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ /* Bits set in the VMA until the stack is in its final location */ -#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ) +#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY) #define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) @@ -399,8 +399,10 @@ extern unsigned int kobjsize(const void *objp); #ifdef CONFIG_STACK_GROWSUP #define VM_STACK VM_GROWSUP +#define VM_STACK_EARLY VM_GROWSDOWN #else #define VM_STACK VM_GROWSDOWN +#define VM_STACK_EARLY 0 #endif #define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT) @@ -725,7 +727,6 @@ struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm, #else /* CONFIG_PER_VMA_LOCK */ -static inline void vma_init_lock(struct vm_area_struct *vma) {} static inline bool vma_start_read(struct vm_area_struct *vma) { return false; } static inline void vma_end_read(struct vm_area_struct *vma) {} @@ -866,11 +867,24 @@ static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi) return mas_find(&vmi->mas, ULONG_MAX); } +static inline +struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi) +{ + return mas_next_range(&vmi->mas, ULONG_MAX); +} + + static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi) { return mas_prev(&vmi->mas, 0); } +static inline +struct vm_area_struct *vma_iter_prev_range(struct vma_iterator *vmi) +{ + return mas_prev_range(&vmi->mas, 0); +} + static inline unsigned long vma_iter_addr(struct vma_iterator *vmi) { return vmi->mas.index; @@ -1208,17 +1222,6 @@ enum compound_dtor_id { #endif NR_COMPOUND_DTORS, }; -extern compound_page_dtor * const compound_page_dtors[NR_COMPOUND_DTORS]; - -static inline void set_compound_page_dtor(struct page *page, - enum compound_dtor_id compound_dtor) -{ - struct folio *folio = (struct folio *)page; - - VM_BUG_ON_PAGE(compound_dtor >= NR_COMPOUND_DTORS, page); - VM_BUG_ON_PAGE(!PageHead(page), page); - folio->_folio_dtor = compound_dtor; -} static inline void folio_set_compound_dtor(struct folio *folio, enum compound_dtor_id compound_dtor) @@ -1229,16 +1232,6 @@ static inline void folio_set_compound_dtor(struct folio *folio, void destroy_large_folio(struct folio *folio); -static inline void set_compound_order(struct page *page, unsigned int order) -{ - struct folio *folio = (struct folio *)page; - - folio->_folio_order = order; -#ifdef CONFIG_64BIT - folio->_folio_nr_pages = 1U << order; -#endif -} - /* Returns the number of bytes in this potentially compound page. */ static inline unsigned long page_size(struct page *page) { @@ -1910,39 +1903,57 @@ static inline bool page_needs_cow_for_dma(struct vm_area_struct *vma, return page_maybe_dma_pinned(page); } -/* MIGRATE_CMA and ZONE_MOVABLE do not allow pin pages */ +/** + * is_zero_page - Query if a page is a zero page + * @page: The page to query + * + * This returns true if @page is one of the permanent zero pages. + */ +static inline bool is_zero_page(const struct page *page) +{ + return is_zero_pfn(page_to_pfn(page)); +} + +/** + * is_zero_folio - Query if a folio is a zero page + * @folio: The folio to query + * + * This returns true if @folio is one of the permanent zero pages. + */ +static inline bool is_zero_folio(const struct folio *folio) +{ + return is_zero_page(&folio->page); +} + +/* MIGRATE_CMA and ZONE_MOVABLE do not allow pin folios */ #ifdef CONFIG_MIGRATION -static inline bool is_longterm_pinnable_page(struct page *page) +static inline bool folio_is_longterm_pinnable(struct folio *folio) { #ifdef CONFIG_CMA - int mt = get_pageblock_migratetype(page); + int mt = folio_migratetype(folio); if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE) return false; #endif - /* The zero page may always be pinned */ - if (is_zero_pfn(page_to_pfn(page))) + /* The zero page can be "pinned" but gets special handling. */ + if (is_zero_folio(folio)) return true; /* Coherent device memory must always allow eviction. */ - if (is_device_coherent_page(page)) + if (folio_is_device_coherent(folio)) return false; - /* Otherwise, non-movable zone pages can be pinned. */ - return !is_zone_movable_page(page); + /* Otherwise, non-movable zone folios can be pinned. */ + return !folio_is_zone_movable(folio); + } #else -static inline bool is_longterm_pinnable_page(struct page *page) +static inline bool folio_is_longterm_pinnable(struct folio *folio) { return true; } #endif -static inline bool folio_is_longterm_pinnable(struct folio *folio) -{ - return is_longterm_pinnable_page(&folio->page); -} - static inline void set_page_zone(struct page *page, enum zone_type zone) { page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT); @@ -2314,6 +2325,9 @@ void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to); void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end); int generic_error_remove_page(struct address_space *mapping, struct page *page); +struct vm_area_struct *lock_mm_and_find_vma(struct mm_struct *mm, + unsigned long address, struct pt_regs *regs); + #ifdef CONFIG_MMU extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address, unsigned int flags, @@ -2353,6 +2367,9 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, unmap_mapping_range(mapping, holebegin, holelen, 0); } +static inline struct vm_area_struct *vma_lookup(struct mm_struct *mm, + unsigned long addr); + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, unsigned int gup_flags); extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, @@ -2361,19 +2378,42 @@ extern int __access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, unsigned int gup_flags); long get_user_pages_remote(struct mm_struct *mm, - unsigned long start, unsigned long nr_pages, - unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas, int *locked); + unsigned long start, unsigned long nr_pages, + unsigned int gup_flags, struct page **pages, + int *locked); long pin_user_pages_remote(struct mm_struct *mm, unsigned long start, unsigned long nr_pages, unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas, int *locked); + int *locked); + +static inline struct page *get_user_page_vma_remote(struct mm_struct *mm, + unsigned long addr, + int gup_flags, + struct vm_area_struct **vmap) +{ + struct page *page; + struct vm_area_struct *vma; + int got = get_user_pages_remote(mm, addr, 1, gup_flags, &page, NULL); + + if (got < 0) + return ERR_PTR(got); + if (got == 0) + return NULL; + + vma = vma_lookup(mm, addr); + if (WARN_ON_ONCE(!vma)) { + put_page(page); + return ERR_PTR(-EINVAL); + } + + *vmap = vma; + return page; +} + long get_user_pages(unsigned long start, unsigned long nr_pages, - unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas); + unsigned int gup_flags, struct page **pages); long pin_user_pages(unsigned long start, unsigned long nr_pages, - unsigned int gup_flags, struct page **pages, - struct vm_area_struct **vmas); + unsigned int gup_flags, struct page **pages); long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, struct page **pages, unsigned int gup_flags); long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, @@ -2383,6 +2423,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); int pin_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); +void folio_add_pin(struct folio *folio); int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, @@ -2422,6 +2463,7 @@ extern unsigned long move_page_tables(struct vm_area_struct *vma, #define MM_CP_UFFD_WP_ALL (MM_CP_UFFD_WP | \ MM_CP_UFFD_WP_RESOLVE) +bool vma_needs_dirty_tracking(struct vm_area_struct *vma); int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot); static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma) { @@ -2787,14 +2829,25 @@ static inline void pgtable_pte_page_dtor(struct page *page) dec_lruvec_page_state(page, NR_PAGETABLE); } -#define pte_offset_map_lock(mm, pmd, address, ptlp) \ -({ \ - spinlock_t *__ptl = pte_lockptr(mm, pmd); \ - pte_t *__pte = pte_offset_map(pmd, address); \ - *(ptlp) = __ptl; \ - spin_lock(__ptl); \ - __pte; \ -}) +pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp); +static inline pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr) +{ + return __pte_offset_map(pmd, addr, NULL); +} + +pte_t *__pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, spinlock_t **ptlp); +static inline pte_t *pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, spinlock_t **ptlp) +{ + pte_t *pte; + + __cond_lock(*ptlp, pte = __pte_offset_map_lock(mm, pmd, addr, ptlp)); + return pte; +} + +pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, spinlock_t **ptlp); #define pte_unmap_unlock(pte, ptl) do { \ spin_unlock(ptl); \ @@ -2915,7 +2968,8 @@ extern unsigned long free_reserved_area(void *start, void *end, extern void adjust_managed_page_count(struct page *page, long count); -extern void reserve_bootmem_region(phys_addr_t start, phys_addr_t end); +extern void reserve_bootmem_region(phys_addr_t start, + phys_addr_t end, int nid); /* Free the reserved page into the buddy system, so it gets managed. */ static inline void free_reserved_page(struct page *page) @@ -2994,12 +3048,6 @@ extern int __meminit early_pfn_to_nid(unsigned long pfn); #endif extern void set_dma_reserve(unsigned long new_dma_reserve); -extern void memmap_init_range(unsigned long, int, unsigned long, - unsigned long, unsigned long, enum meminit_context, - struct vmem_altmap *, int migratetype); -extern void setup_per_zone_wmarks(void); -extern void calculate_min_free_kbytes(void); -extern int __meminit init_per_zone_wmark_min(void); extern void mem_init(void); extern void __init mmap_init(void); @@ -3020,11 +3068,6 @@ void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...); extern void setup_per_cpu_pageset(void); -/* page_alloc.c */ -extern int min_free_kbytes; -extern int watermark_boost_factor; -extern int watermark_scale_factor; - /* nommu.c */ extern atomic_long_t mmap_pages_allocated; extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t); @@ -3136,7 +3179,7 @@ extern unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long pgoff, unsigned long *populate, struct list_head *uf); extern int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, unsigned long start, size_t len, struct list_head *uf, - bool downgrade); + bool unlock); extern int do_munmap(struct mm_struct *, unsigned long, size_t, struct list_head *uf); extern int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior); @@ -3144,7 +3187,7 @@ extern int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, #ifdef CONFIG_MMU extern int do_vma_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma, unsigned long start, unsigned long end, - struct list_head *uf, bool downgrade); + struct list_head *uf, bool unlock); extern int __mm_populate(unsigned long addr, unsigned long len, int ignore_errors); static inline void mm_populate(unsigned long addr, unsigned long len) @@ -3190,16 +3233,11 @@ extern vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf); extern unsigned long stack_guard_gap; /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */ -extern int expand_stack(struct vm_area_struct *vma, unsigned long address); +int expand_stack_locked(struct vm_area_struct *vma, unsigned long address); +struct vm_area_struct *expand_stack(struct mm_struct * mm, unsigned long addr); /* CONFIG_STACK_GROWSUP still needs to grow downwards at some places */ -extern int expand_downwards(struct vm_area_struct *vma, - unsigned long address); -#if VM_GROWSUP -extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); -#else - #define expand_upwards(vma, address) (0) -#endif +int expand_downwards(struct vm_area_struct *vma, unsigned long address); /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); @@ -3294,7 +3332,8 @@ unsigned long change_prot_numa(struct vm_area_struct *vma, unsigned long start, unsigned long end); #endif -struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); +struct vm_area_struct *find_extend_vma_locked(struct mm_struct *, + unsigned long addr); int remap_pfn_range(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t); int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr, @@ -3342,6 +3381,8 @@ static inline vm_fault_t vmf_error(int err) { if (err == -ENOMEM) return VM_FAULT_OOM; + else if (err == -EHWPOISON) + return VM_FAULT_HWPOISON; return VM_FAULT_SIGBUS; } @@ -3453,13 +3494,12 @@ static inline bool debug_pagealloc_enabled_static(void) return static_branch_unlikely(&_debug_pagealloc_enabled); } -#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); - +#ifdef CONFIG_DEBUG_PAGEALLOC static inline void debug_pagealloc_map_pages(struct page *page, int numpages) { if (debug_pagealloc_enabled_static()) @@ -3471,9 +3511,58 @@ static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) if (debug_pagealloc_enabled_static()) __kernel_map_pages(page, numpages, 0); } + +extern unsigned int _debug_guardpage_minorder; +DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled); + +static inline unsigned int debug_guardpage_minorder(void) +{ + return _debug_guardpage_minorder; +} + +static inline bool debug_guardpage_enabled(void) +{ + return static_branch_unlikely(&_debug_guardpage_enabled); +} + +static inline bool page_is_guard(struct page *page) +{ + if (!debug_guardpage_enabled()) + return false; + + return PageGuard(page); +} + +bool __set_page_guard(struct zone *zone, struct page *page, unsigned int order, + int migratetype); +static inline bool set_page_guard(struct zone *zone, struct page *page, + unsigned int order, int migratetype) +{ + if (!debug_guardpage_enabled()) + return false; + return __set_page_guard(zone, page, order, migratetype); +} + +void __clear_page_guard(struct zone *zone, struct page *page, unsigned int order, + int migratetype); +static inline void clear_page_guard(struct zone *zone, struct page *page, + unsigned int order, int migratetype) +{ + if (!debug_guardpage_enabled()) + return; + __clear_page_guard(zone, page, order, migratetype); +} + #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) {} +static inline unsigned int debug_guardpage_minorder(void) { return 0; } +static inline bool debug_guardpage_enabled(void) { return false; } +static inline bool page_is_guard(struct page *page) { return false; } +static inline bool set_page_guard(struct zone *zone, struct page *page, + unsigned int order, int migratetype) { return false; } +static inline void clear_page_guard(struct zone *zone, struct page *page, + unsigned int order, int migratetype) {} #endif /* CONFIG_DEBUG_PAGEALLOC */ #ifdef __HAVE_ARCH_GATE_AREA @@ -3586,6 +3675,10 @@ extern void shake_page(struct page *p); extern atomic_long_t num_poisoned_pages __read_mostly; extern int soft_offline_page(unsigned long pfn, int flags); #ifdef CONFIG_MEMORY_FAILURE +/* + * Sysfs entries for memory failure handling statistics. + */ +extern const struct attribute_group memory_failure_attr_group; extern void memory_failure_queue(unsigned long pfn, int flags); extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags, bool *migratable_cleared); @@ -3678,11 +3771,6 @@ enum mf_action_page_type { MF_MSG_UNKNOWN, }; -/* - * Sysfs entries for memory failure handling statistics. - */ -extern const struct attribute_group memory_failure_attr_group; - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS) extern void clear_huge_page(struct page *page, unsigned long addr_hint, @@ -3712,33 +3800,6 @@ static inline bool vma_is_special_huge(const struct vm_area_struct *vma) #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ -#ifdef CONFIG_DEBUG_PAGEALLOC -extern unsigned int _debug_guardpage_minorder; -DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled); - -static inline unsigned int debug_guardpage_minorder(void) -{ - return _debug_guardpage_minorder; -} - -static inline bool debug_guardpage_enabled(void) -{ - return static_branch_unlikely(&_debug_guardpage_enabled); -} - -static inline bool page_is_guard(struct page *page) -{ - if (!debug_guardpage_enabled()) - return false; - - return PageGuard(page); -} -#else -static inline unsigned int debug_guardpage_minorder(void) { return 0; } -static inline bool debug_guardpage_enabled(void) { return false; } -static inline bool page_is_guard(struct page *page) { return false; } -#endif /* CONFIG_DEBUG_PAGEALLOC */ - #if MAX_NUMNODES > 1 void __init setup_nr_node_ids(void); #else @@ -3816,4 +3877,23 @@ madvise_set_anon_name(struct mm_struct *mm, unsigned long start, } #endif +#ifdef CONFIG_UNACCEPTED_MEMORY + +bool range_contains_unaccepted_memory(phys_addr_t start, phys_addr_t end); +void accept_memory(phys_addr_t start, phys_addr_t end); + +#else + +static inline bool range_contains_unaccepted_memory(phys_addr_t start, + phys_addr_t end) +{ + return false; +} + +static inline void accept_memory(phys_addr_t start, phys_addr_t end) +{ +} + +#endif + #endif /* _LINUX_MM_H */ diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 0e1d239a882c..21d6c72bcc71 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -323,12 +323,6 @@ void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio) list_add(&folio->lru, &lruvec->lists[lru]); } -static __always_inline void add_page_to_lru_list(struct page *page, - struct lruvec *lruvec) -{ - lruvec_add_folio(lruvec, page_folio(page)); -} - static __always_inline void lruvec_add_folio_tail(struct lruvec *lruvec, struct folio *folio) { @@ -357,12 +351,6 @@ void lruvec_del_folio(struct lruvec *lruvec, struct folio *folio) -folio_nr_pages(folio)); } -static __always_inline void del_page_from_lru_list(struct page *page, - struct lruvec *lruvec) -{ - lruvec_del_folio(lruvec, page_folio(page)); -} - #ifdef CONFIG_ANON_VMA_NAME /* * mmap_lock should be read-locked when calling anon_vma_name(). Caller should @@ -555,7 +543,7 @@ pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr, bool arm_uffd_pte = false; /* The current status of the pte should be "cleared" before calling */ - WARN_ON_ONCE(!pte_none(*pte)); + WARN_ON_ONCE(!pte_none(ptep_get(pte))); /* * NOTE: userfaultfd_wp_unpopulated() doesn't need this whole diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 306a3d1a0fa6..de10fc797c8e 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -583,6 +583,21 @@ struct mm_cid { struct kioctx_table; struct mm_struct { struct { + /* + * Fields which are often written to are placed in a separate + * cache line. + */ + struct { + /** + * @mm_count: The number of references to &struct + * mm_struct (@mm_users count as 1). + * + * Use mmgrab()/mmdrop() to modify. When this drops to + * 0, the &struct mm_struct is freed. + */ + atomic_t mm_count; + } ____cacheline_aligned_in_smp; + struct maple_tree mm_mt; #ifdef CONFIG_MMU unsigned long (*get_unmapped_area) (struct file *filp, @@ -620,14 +635,6 @@ struct mm_struct { */ atomic_t mm_users; - /** - * @mm_count: The number of references to &struct mm_struct - * (@mm_users count as 1). - * - * Use mmgrab()/mmdrop() to modify. When this drops to 0, the - * &struct mm_struct is freed. - */ - atomic_t mm_count; #ifdef CONFIG_SCHED_MM_CID /** * @pcpu_cid: Per-cpu current cid. diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c726ea781255..daa2f40d9ce6 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -294,6 +294,7 @@ struct mmc_card { #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ #define MMC_QUIRK_BROKEN_SD_DISCARD (1<<14) /* Disable broken SD discard support */ +#define MMC_QUIRK_BROKEN_SD_CACHE (1<<15) /* Disable broken SD cache support */ bool reenable_cmdq; /* Re-enable Command Queue */ diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index c653accdc7fd..7fada7a714fe 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -121,7 +121,8 @@ #define SDIO_DEVICE_ID_REALTEK_RTW8822BS 0xb822 #define SDIO_DEVICE_ID_REALTEK_RTW8821CS 0xc821 #define SDIO_DEVICE_ID_REALTEK_RTW8822CS 0xc822 -#define SDIO_DEVICE_ID_REALTEK_RTW8723DS 0xd723 +#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_2ANT 0xd723 +#define SDIO_DEVICE_ID_REALTEK_RTW8723DS_1ANT 0xd724 #define SDIO_DEVICE_ID_REALTEK_RTW8821DS 0xd821 #define SDIO_VENDOR_ID_SIANO 0x039a diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index b8728d11c949..7c3e7b0b0e8f 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -8,10 +8,12 @@ struct page; struct vm_area_struct; struct mm_struct; +struct vma_iterator; void dump_page(struct page *page, const char *reason); void dump_vma(const struct vm_area_struct *vma); void dump_mm(const struct mm_struct *mm); +void vma_iter_dump_tree(const struct vma_iterator *vmi); #ifdef CONFIG_DEBUG_VM #define VM_BUG_ON(cond) BUG_ON(cond) @@ -74,6 +76,17 @@ void dump_mm(const struct mm_struct *mm); } \ unlikely(__ret_warn_once); \ }) +#define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ + static bool __section(".data.once") __warned; \ + int __ret_warn_once = !!(cond); \ + \ + if (unlikely(__ret_warn_once && !__warned)) { \ + dump_mm(mm); \ + __warned = true; \ + WARN_ON(1); \ + } \ + unlikely(__ret_warn_once); \ +}) #define VM_WARN_ON(cond) (void)WARN_ON(cond) #define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond) @@ -90,6 +103,7 @@ void dump_mm(const struct mm_struct *mm); #define VM_WARN_ON_ONCE_PAGE(cond, page) BUILD_BUG_ON_INVALID(cond) #define VM_WARN_ON_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) #define VM_WARN_ON_ONCE_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) +#define VM_WARN_ON_ONCE_MM(cond, mm) BUILD_BUG_ON_INVALID(cond) #define VM_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond) #define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond) #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a4889c9d4055..5e50b78d58ea 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -105,6 +105,9 @@ extern int page_group_by_mobility_disabled; #define get_pageblock_migratetype(page) \ get_pfnblock_flags_mask(page, page_to_pfn(page), MIGRATETYPE_MASK) +#define folio_migratetype(folio) \ + get_pfnblock_flags_mask(&folio->page, folio_pfn(folio), \ + MIGRATETYPE_MASK) struct free_area { struct list_head free_list[MIGRATE_TYPES]; unsigned long nr_free; @@ -143,6 +146,9 @@ enum zone_stat_item { NR_ZSPAGES, /* allocated in zsmalloc */ #endif NR_FREE_CMA_PAGES, +#ifdef CONFIG_UNACCEPTED_MEMORY + NR_UNACCEPTED, +#endif NR_VM_ZONE_STAT_ITEMS }; enum node_stat_item { @@ -290,9 +296,21 @@ static inline bool is_active_lru(enum lru_list lru) #define ANON_AND_FILE 2 enum lruvec_flags { - LRUVEC_CONGESTED, /* lruvec has many dirty pages - * backed by a congested BDI - */ + /* + * An lruvec has many dirty pages backed by a congested BDI: + * 1. LRUVEC_CGROUP_CONGESTED is set by cgroup-level reclaim. + * It can be cleared by cgroup reclaim or kswapd. + * 2. LRUVEC_NODE_CONGESTED is set by kswapd node-level reclaim. + * It can only be cleared by kswapd. + * + * Essentially, kswapd can unthrottle an lruvec throttled by cgroup + * reclaim, but not vice versa. This only applies to the root cgroup. + * The goal is to prevent cgroup reclaim on the root cgroup (e.g. + * memory.reclaim) to unthrottle an unbalanced node (that was throttled + * by kswapd). + */ + LRUVEC_CGROUP_CONGESTED, + LRUVEC_NODE_CONGESTED, }; #endif /* !__GENERATING_BOUNDS_H */ @@ -534,7 +552,7 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg); void lru_gen_online_memcg(struct mem_cgroup *memcg); void lru_gen_offline_memcg(struct mem_cgroup *memcg); void lru_gen_release_memcg(struct mem_cgroup *memcg); -void lru_gen_soft_reclaim(struct lruvec *lruvec); +void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid); #else /* !CONFIG_MEMCG */ @@ -585,7 +603,7 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg) { } -static inline void lru_gen_soft_reclaim(struct lruvec *lruvec) +static inline void lru_gen_soft_reclaim(struct mem_cgroup *memcg, int nid) { } @@ -910,6 +928,11 @@ struct zone { /* free areas of different sizes */ struct free_area free_area[MAX_ORDER + 1]; +#ifdef CONFIG_UNACCEPTED_MEMORY + /* Pages to be accepted. All pages on the list are MAX_ORDER */ + struct list_head unaccepted_pages; +#endif + /* zone flags, see below */ unsigned long flags; @@ -1116,6 +1139,11 @@ static inline bool is_zone_movable_page(const struct page *page) { return page_zonenum(page) == ZONE_MOVABLE; } + +static inline bool folio_is_zone_movable(const struct folio *folio) +{ + return folio_zonenum(folio) == ZONE_MOVABLE; +} #endif /* @@ -1512,27 +1540,6 @@ static inline bool has_managed_dma(void) } #endif -/* These two functions are used to setup the per zone pages min values */ -struct ctl_table; - -int min_free_kbytes_sysctl_handler(struct ctl_table *, int, void *, size_t *, - loff_t *); -int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, void *, - size_t *, loff_t *); -extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES]; -int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, void *, - size_t *, loff_t *); -int percpu_pagelist_high_fraction_sysctl_handler(struct ctl_table *, int, - void *, size_t *, loff_t *); -int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int, - void *, size_t *, loff_t *); -int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int, - void *, size_t *, loff_t *); -int numa_zonelist_order_handler(struct ctl_table *, int, - void *, size_t *, loff_t *); -extern int percpu_pagelist_high_fraction; -extern char numa_zonelist_order[]; -#define NUMA_ZONELIST_ORDER_LEN 16 #ifndef CONFIG_NUMA diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index ccaaeda792c0..b0678b093cb2 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -221,6 +221,19 @@ struct acpi_device_id { __u32 cls_msk; }; +/** + * ACPI_DEVICE_CLASS - macro used to describe an ACPI device with + * the PCI-defined class-code information + * + * @_cls : the class, subclass, prog-if triple for this device + * @_msk : the class mask for this device + * + * This macro is used to create a struct acpi_device_id that matches a + * specific PCI class. The .id and .driver_data fields will be left + * initialized with the default value. + */ +#define ACPI_DEVICE_CLASS(_cls, _msk) .cls = (_cls), .cls_msk = (_msk), + #define PNP_ID_LEN 8 #define PNP_MAX_DEVICES 8 @@ -912,6 +925,12 @@ struct ishtp_device_id { kernel_ulong_t driver_data; }; +#define CDX_ANY_ID (0xFFFF) + +enum { + CDX_ID_F_VFIO_DRIVER_OVERRIDE = 1, +}; + /** * struct cdx_device_id - CDX device identifier * @vendor: Vendor ID diff --git a/include/linux/module.h b/include/linux/module.h index 9e56763dff81..a98e188cf37b 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -968,15 +968,6 @@ static inline int lookup_module_symbol_name(unsigned long addr, char *symname) return -ERANGE; } -static inline int lookup_module_symbol_attrs(unsigned long addr, - unsigned long *size, - unsigned long *offset, - char *modname, - char *name) -{ - return -ERANGE; -} - static inline int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type, char *name, char *module_name, int *exported) diff --git a/include/linux/mount.h b/include/linux/mount.h index 1ea326c368f7..4f40b40306d0 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -107,7 +107,6 @@ extern struct vfsmount *vfs_submount(const struct dentry *mountpoint, extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list); extern void mark_mounts_for_expiry(struct list_head *mounts); -extern dev_t name_to_dev_t(const char *name); extern bool path_is_mountpoint(const struct path *path); extern bool our_mnt(struct vfsmount *mnt); @@ -124,4 +123,6 @@ extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, struct vfsmount *); extern void kern_unmount_array(struct vfsmount *mnt[], unsigned int num); +extern int cifs_root_data(char **dev, char **opts); + #endif /* _LINUX_MOUNT_H */ diff --git a/include/linux/mroute.h b/include/linux/mroute.h index 80b8400ab8b2..4c5003afee6c 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -18,10 +18,11 @@ static inline int ip_mroute_opt(int opt) int ip_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int); int ip_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t); -int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); +int ipmr_ioctl(struct sock *sk, int cmd, void *arg); int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); int ip_mr_init(void); bool ipmr_rule_default(const struct fib_rule *rule); +int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); #else static inline int ip_mroute_setsockopt(struct sock *sock, int optname, sockptr_t optval, unsigned int optlen) @@ -35,7 +36,7 @@ static inline int ip_mroute_getsockopt(struct sock *sk, int optname, return -ENOPROTOOPT; } -static inline int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) +static inline int ipmr_ioctl(struct sock *sk, int cmd, void *arg) { return -ENOIOCTLCMD; } @@ -54,6 +55,12 @@ static inline bool ipmr_rule_default(const struct fib_rule *rule) { return true; } + +static inline int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, + void __user *arg) +{ + return 1; +} #endif #define VIFF_STATIC 0x8000 diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h index 8f2b307fb124..63ef5191cc57 100644 --- a/include/linux/mroute6.h +++ b/include/linux/mroute6.h @@ -29,10 +29,10 @@ struct sock; extern int ip6_mroute_setsockopt(struct sock *, int, sockptr_t, unsigned int); extern int ip6_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t); extern int ip6_mr_input(struct sk_buff *skb); -extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); extern int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); extern int ip6_mr_init(void); extern void ip6_mr_cleanup(void); +int ip6mr_ioctl(struct sock *sk, int cmd, void *arg); #else static inline int ip6_mroute_setsockopt(struct sock *sock, int optname, sockptr_t optval, unsigned int optlen) @@ -48,7 +48,7 @@ int ip6_mroute_getsockopt(struct sock *sock, } static inline -int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) +int ip6mr_ioctl(struct sock *sk, int cmd, void *arg) { return -ENOIOCTLCMD; } @@ -100,6 +100,27 @@ extern int ip6mr_get_route(struct net *net, struct sk_buff *skb, #ifdef CONFIG_IPV6_MROUTE bool mroute6_is_socket(struct net *net, struct sk_buff *skb); extern int ip6mr_sk_done(struct sock *sk); +static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd, + void __user *arg) +{ + switch (cmd) { + /* These userspace buffers will be consumed by ip6mr_ioctl() */ + case SIOCGETMIFCNT_IN6: { + struct sioc_mif_req6 buffer; + + return sock_ioctl_inout(sk, cmd, arg, &buffer, + sizeof(buffer)); + } + case SIOCGETSGCNT_IN6: { + struct sioc_sg_req6 buffer; + + return sock_ioctl_inout(sk, cmd, arg, &buffer, + sizeof(buffer)); + } + } + + return 1; +} #else static inline bool mroute6_is_socket(struct net *net, struct sk_buff *skb) { @@ -109,5 +130,11 @@ static inline int ip6mr_sk_done(struct sock *sk) { return 0; } + +static inline int ip6mr_sk_ioctl(struct sock *sk, unsigned int cmd, + void __user *arg) +{ + return 1; +} #endif #endif diff --git a/include/linux/msi.h b/include/linux/msi.h index cdb14a1ef268..a50ea79522f8 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -383,6 +383,13 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); void arch_teardown_msi_irqs(struct pci_dev *dev); +#endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */ + +/* + * Xen uses non-default msi_domain_ops and hence needs a way to populate sysfs + * entries of MSI IRQs. + */ +#if defined(CONFIG_PCI_XEN) || defined(CONFIG_PCI_MSI_ARCH_FALLBACKS) #ifdef CONFIG_SYSFS int msi_device_populate_sysfs(struct device *dev); void msi_device_destroy_sysfs(struct device *dev); @@ -390,7 +397,7 @@ void msi_device_destroy_sysfs(struct device *dev); static inline int msi_device_populate_sysfs(struct device *dev) { return 0; } static inline void msi_device_destroy_sysfs(struct device *dev) { } #endif /* !CONFIG_SYSFS */ -#endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */ +#endif /* CONFIG_PCI_XEN || CONFIG_PCI_MSI_ARCH_FALLBACKS */ /* * The restore hook is still available even for fully irq domain based diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h index 15cc9b95e32b..6e471436bba5 100644 --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h @@ -34,7 +34,7 @@ struct mtd_blktrans_dev { struct blk_mq_tag_set *tag_set; spinlock_t queue_lock; void *priv; - fmode_t file_mode; + bool writable; }; struct mtd_blktrans_ops { diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 8f226d460f51..a33aa9eb9fc3 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -19,6 +19,7 @@ #include <asm/processor.h> #include <linux/osq_lock.h> #include <linux/debug_locks.h> +#include <linux/cleanup.h> #ifdef CONFIG_DEBUG_LOCK_ALLOC # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ @@ -219,4 +220,7 @@ extern void mutex_unlock(struct mutex *lock); extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); +DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) +DEFINE_FREE(mutex, struct mutex *, if (_T) mutex_unlock(_T)) + #endif /* __LINUX_MUTEX_H */ diff --git a/include/linux/net.h b/include/linux/net.h index b73ad8e3c212..41c608c1b02c 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -43,6 +43,7 @@ struct net; #define SOCK_PASSSEC 4 #define SOCK_SUPPORT_ZC 5 #define SOCK_CUSTOM_SOCKOPT 6 +#define SOCK_PASSPIDFD 7 #ifndef ARCH_HAS_SOCKET_TYPES /** @@ -206,10 +207,9 @@ struct proto_ops { size_t total_len, int flags); int (*mmap) (struct file *file, struct socket *sock, struct vm_area_struct * vma); - ssize_t (*sendpage) (struct socket *sock, struct page *page, - int offset, size_t size, int flags); ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); + void (*splice_eof)(struct socket *sock); int (*set_peek_off)(struct sock *sk, int val); int (*peek_len)(struct socket *sock); @@ -220,8 +220,6 @@ struct proto_ops { sk_read_actor_t recv_actor); /* This is different from read_sock(), it reads an entire skb at a time. */ int (*read_skb)(struct sock *sk, skb_read_actor_t recv_actor); - int (*sendpage_locked)(struct sock *sk, struct page *page, - int offset, size_t size, int flags); int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg, size_t size); int (*set_rcvlowat)(struct sock *sk, int val); @@ -339,10 +337,6 @@ int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, int flags); int kernel_getsockname(struct socket *sock, struct sockaddr *addr); int kernel_getpeername(struct socket *sock, struct sockaddr *addr); -int kernel_sendpage(struct socket *sock, struct page *page, int offset, - size_t size, int flags); -int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset, - size_t size, int flags); int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how); /* Routine returns the IP overhead imposed by a (caller-protected) socket. */ diff --git a/include/linux/net_mm.h b/include/linux/net_mm.h new file mode 100644 index 000000000000..b298998bd5a0 --- /dev/null +++ b/include/linux/net_mm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifdef CONFIG_MMU + +#ifdef CONFIG_INET +extern const struct vm_operations_struct tcp_vm_ops; +static inline bool vma_is_tcp(const struct vm_area_struct *vma) +{ + return vma->vm_ops == &tcp_vm_ops; +} +#else +static inline bool vma_is_tcp(const struct vm_area_struct *vma) +{ + return false; +} +#endif /* CONFIG_INET*/ + +#endif /* CONFIG_MMU */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 08fbd4622ccf..b828c7a75be2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -620,7 +620,7 @@ struct netdev_queue { netdevice_tracker dev_tracker; struct Qdisc __rcu *qdisc; - struct Qdisc *qdisc_sleeping; + struct Qdisc __rcu *qdisc_sleeping; #ifdef CONFIG_SYSFS struct kobject kobj; #endif @@ -768,8 +768,11 @@ static inline void rps_record_sock_flow(struct rps_sock_flow_table *table, /* We only give a hint, preemption can change CPU under us */ val |= raw_smp_processor_id(); - if (table->ents[index] != val) - table->ents[index] = val; + /* The following WRITE_ONCE() is paired with the READ_ONCE() + * here, and another one in get_rps_cpu(). + */ + if (READ_ONCE(table->ents[index]) != val) + WRITE_ONCE(table->ents[index], val); } } @@ -3121,6 +3124,10 @@ struct net_device *netdev_sk_get_lowest_dev(struct net_device *dev, struct sock *sk); struct net_device *dev_get_by_index(struct net *net, int ifindex); struct net_device *__dev_get_by_index(struct net *net, int ifindex); +struct net_device *netdev_get_by_index(struct net *net, int ifindex, + netdevice_tracker *tracker, gfp_t gfp); +struct net_device *netdev_get_by_name(struct net *net, const char *name, + netdevice_tracker *tracker, gfp_t gfp); struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); struct net_device *dev_get_by_napi_id(unsigned int napi_id); int dev_restart(struct net_device *dev); @@ -4824,13 +4831,6 @@ int skb_crc32c_csum_help(struct sk_buff *skb); int skb_csum_hwoffload_help(struct sk_buff *skb, const netdev_features_t features); -struct sk_buff *__skb_gso_segment(struct sk_buff *skb, - netdev_features_t features, bool tx_path); -struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb, - netdev_features_t features, __be16 type); -struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, - netdev_features_t features); - struct netdev_bonding_info { ifslave slave; ifbond master; @@ -4853,11 +4853,6 @@ static inline void ethtool_notify(struct net_device *dev, unsigned int cmd, } #endif -static inline -struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features) -{ - return __skb_gso_segment(skb, features, true); -} __be16 skb_network_protocol(struct sk_buff *skb, int *depth); static inline bool can_checksum_protocol(netdev_features_t features, @@ -4984,6 +4979,7 @@ netdev_features_t passthru_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features); netdev_features_t netif_skb_features(struct sk_buff *skb); +void skb_warn_bad_offload(const struct sk_buff *skb); static inline bool net_gso_ok(netdev_features_t features, int gso_type) { @@ -5032,19 +5028,6 @@ void netif_set_tso_max_segs(struct net_device *dev, unsigned int segs); void netif_inherit_tso_max(struct net_device *to, const struct net_device *from); -static inline void skb_gso_error_unwind(struct sk_buff *skb, __be16 protocol, - int pulled_hlen, u16 mac_offset, - int mac_len) -{ - skb->protocol = protocol; - skb->encapsulation = 1; - skb_push(skb, pulled_hlen); - skb_reset_transport_header(skb); - skb->mac_header = mac_offset; - skb->network_header = skb->mac_header + mac_len; - skb->mac_len = mac_len; -} - static inline bool netif_is_macsec(const struct net_device *dev) { return dev->priv_flags & IFF_MACSEC; @@ -5090,6 +5073,15 @@ static inline bool netif_is_l3_slave(const struct net_device *dev) return dev->priv_flags & IFF_L3MDEV_SLAVE; } +static inline int dev_sdif(const struct net_device *dev) +{ +#ifdef CONFIG_NET_L3_MASTER_DEV + if (netif_is_l3_slave(dev)) + return dev->ifindex; +#endif + return 0; +} + static inline bool netif_is_bridge_master(const struct net_device *dev) { return dev->priv_flags & IFF_EBRIDGE; diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 0762444e3767..d4fed4c508ca 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -481,7 +481,7 @@ struct nfnl_ct_hook { }; extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook; -/** +/* * nf_skb_duplicated - TEE target has sent a packet * * When a xtables target sends a packet, the OUTPUT and POSTROUTING @@ -492,7 +492,7 @@ extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook; */ DECLARE_PER_CPU(bool, nf_skb_duplicated); -/** +/* * Contains bitmask of ctnetlink event subscribers, if any. * Can't be pernet due to NETLINK_LISTEN_ALL_NSID setsockopt flag. */ diff --git a/include/linux/netfs.h b/include/linux/netfs.h index a1f3522daa69..b11a84f6c32b 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -300,10 +300,6 @@ void netfs_stats_show(struct seq_file *); ssize_t netfs_extract_user_iter(struct iov_iter *orig, size_t orig_len, struct iov_iter *new, iov_iter_extraction_t extraction_flags); -struct sg_table; -ssize_t netfs_extract_iter_to_sg(struct iov_iter *iter, size_t len, - struct sg_table *sgtable, unsigned int sg_max, - iov_iter_extraction_t extraction_flags); /** * netfs_inode - Get the netfs inode context from the inode diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 19c0791ed9d5..9eec3f4f5351 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -311,6 +311,7 @@ struct netlink_dump_control { int (*start)(struct netlink_callback *); int (*dump)(struct sk_buff *skb, struct netlink_callback *); int (*done)(struct netlink_callback *); + struct netlink_ext_ack *extack; void *data; struct module *module; u32 min_dump_alloc; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index ea2f7e6b1b0b..20eeba8b009d 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -63,7 +63,8 @@ struct nfs_client { u32 cl_minorversion;/* NFSv4 minorversion */ unsigned int cl_nconnect; /* Number of connections */ unsigned int cl_max_connect; /* max number of xprts allowed */ - const char * cl_principal; /* used for machine cred */ + const char * cl_principal; /* used for machine cred */ + struct xprtsec_parms cl_xprtsec; /* xprt security policy */ #if IS_ENABLED(CONFIG_NFS_V4) struct list_head cl_ds_clients; /* auth flavor data servers */ @@ -153,6 +154,7 @@ struct nfs_server { #define NFS_MOUNT_WRITE_EAGER 0x01000000 #define NFS_MOUNT_WRITE_WAIT 0x02000000 #define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000 +#define NFS_MOUNT_SHUTDOWN 0x08000000 unsigned int fattr_valid; /* Valid attributes */ unsigned int caps; /* server capabilities */ @@ -183,6 +185,7 @@ struct nfs_server { change_attr_type;/* Description of change attribute */ struct nfs_fsid fsid; + int s_sysfs_id; /* sysfs dentry index */ __u64 maxfilesize; /* maximum file size */ struct timespec64 time_delta; /* smallest time granularity */ unsigned long mount_time; /* when this fs was mounted */ @@ -259,6 +262,7 @@ struct nfs_server { /* User namespace info */ const struct cred *cred; bool has_sec_mnt_opts; + struct kobject kobj; }; /* Server capabilities */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 29a1b39794bf..12bbb5c63664 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1528,6 +1528,7 @@ struct nfs42_seek_res { struct nfs42_setxattrargs { struct nfs4_sequence_args seq_args; struct nfs_fh *fh; + const u32 *bitmask; const char *xattr_name; u32 xattr_flags; size_t xattr_len; @@ -1537,6 +1538,8 @@ struct nfs42_setxattrargs { struct nfs42_setxattrres { struct nfs4_sequence_res seq_res; struct nfs4_change_info cinfo; + struct nfs_fattr *fattr; + const struct nfs_server *server; }; struct nfs42_getxattrargs { diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 048c0b9aa623..e3e6a64b98e0 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -7,19 +7,19 @@ #include <linux/sched.h> #include <asm/irq.h> -#if defined(CONFIG_HAVE_NMI_WATCHDOG) + +/* Arch specific watchdogs might need to share extra watchdog-related APIs. */ +#if defined(CONFIG_HARDLOCKUP_DETECTOR_ARCH) || defined(CONFIG_HARDLOCKUP_DETECTOR_SPARC64) #include <asm/nmi.h> #endif #ifdef CONFIG_LOCKUP_DETECTOR void lockup_detector_init(void); +void lockup_detector_retry_init(void); void lockup_detector_soft_poweroff(void); void lockup_detector_cleanup(void); -bool is_hardlockup(void); extern int watchdog_user_enabled; -extern int nmi_watchdog_user_enabled; -extern int soft_watchdog_user_enabled; extern int watchdog_thresh; extern unsigned long watchdog_enabled; @@ -35,6 +35,7 @@ extern int sysctl_hardlockup_all_cpu_backtrace; #else /* CONFIG_LOCKUP_DETECTOR */ static inline void lockup_detector_init(void) { } +static inline void lockup_detector_retry_init(void) { } static inline void lockup_detector_soft_poweroff(void) { } static inline void lockup_detector_cleanup(void) { } #endif /* !CONFIG_LOCKUP_DETECTOR */ @@ -69,17 +70,17 @@ static inline void reset_hung_task_detector(void) { } * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. * - * 'watchdog_user_enabled', 'nmi_watchdog_user_enabled' and - * 'soft_watchdog_user_enabled' are variables that are only used as an + * 'watchdog_user_enabled', 'watchdog_hardlockup_user_enabled' and + * 'watchdog_softlockup_user_enabled' are variables that are only used as an * 'interface' between the parameters in /proc/sys/kernel and the internal * state bits in 'watchdog_enabled'. The 'watchdog_thresh' variable is * handled differently because its value is not boolean, and the lockup * detectors are 'suspended' while 'watchdog_thresh' is equal zero. */ -#define NMI_WATCHDOG_ENABLED_BIT 0 -#define SOFT_WATCHDOG_ENABLED_BIT 1 -#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) -#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +#define WATCHDOG_HARDLOCKUP_ENABLED_BIT 0 +#define WATCHDOG_SOFTOCKUP_ENABLED_BIT 1 +#define WATCHDOG_HARDLOCKUP_ENABLED (1 << WATCHDOG_HARDLOCKUP_ENABLED_BIT) +#define WATCHDOG_SOFTOCKUP_ENABLED (1 << WATCHDOG_SOFTOCKUP_ENABLED_BIT) #if defined(CONFIG_HARDLOCKUP_DETECTOR) extern void hardlockup_detector_disable(void); @@ -88,52 +89,63 @@ extern unsigned int hardlockup_panic; static inline void hardlockup_detector_disable(void) {} #endif -#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) -# define NMI_WATCHDOG_SYSCTL_PERM 0644 +/* Sparc64 has special implemetantion that is always enabled. */ +#if defined(CONFIG_HARDLOCKUP_DETECTOR) || defined(CONFIG_HARDLOCKUP_DETECTOR_SPARC64) +void arch_touch_nmi_watchdog(void); #else -# define NMI_WATCHDOG_SYSCTL_PERM 0444 +static inline void arch_touch_nmi_watchdog(void) { } +#endif + +#if defined(CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER) +void watchdog_hardlockup_touch_cpu(unsigned int cpu); +void watchdog_hardlockup_check(unsigned int cpu, struct pt_regs *regs); #endif #if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) -extern void arch_touch_nmi_watchdog(void); extern void hardlockup_detector_perf_stop(void); extern void hardlockup_detector_perf_restart(void); -extern void hardlockup_detector_perf_disable(void); -extern void hardlockup_detector_perf_enable(void); extern void hardlockup_detector_perf_cleanup(void); -extern int hardlockup_detector_perf_init(void); #else static inline void hardlockup_detector_perf_stop(void) { } static inline void hardlockup_detector_perf_restart(void) { } -static inline void hardlockup_detector_perf_disable(void) { } -static inline void hardlockup_detector_perf_enable(void) { } static inline void hardlockup_detector_perf_cleanup(void) { } -# if !defined(CONFIG_HAVE_NMI_WATCHDOG) -static inline int hardlockup_detector_perf_init(void) { return -ENODEV; } -static inline void arch_touch_nmi_watchdog(void) {} -# else -static inline int hardlockup_detector_perf_init(void) { return 0; } -# endif #endif -void watchdog_nmi_stop(void); -void watchdog_nmi_start(void); -int watchdog_nmi_probe(void); -int watchdog_nmi_enable(unsigned int cpu); -void watchdog_nmi_disable(unsigned int cpu); +void watchdog_hardlockup_stop(void); +void watchdog_hardlockup_start(void); +int watchdog_hardlockup_probe(void); +void watchdog_hardlockup_enable(unsigned int cpu); +void watchdog_hardlockup_disable(unsigned int cpu); void lockup_detector_reconfigure(void); +#ifdef CONFIG_HARDLOCKUP_DETECTOR_BUDDY +void watchdog_buddy_check_hardlockup(int hrtimer_interrupts); +#else +static inline void watchdog_buddy_check_hardlockup(int hrtimer_interrupts) {} +#endif + /** - * touch_nmi_watchdog - restart NMI watchdog timeout. + * touch_nmi_watchdog - manually reset the hardlockup watchdog timeout. * - * If the architecture supports the NMI watchdog, touch_nmi_watchdog() - * may be used to reset the timeout - for code which intentionally - * disables interrupts for a long time. This call is stateless. + * If we support detecting hardlockups, touch_nmi_watchdog() may be + * used to pet the watchdog (reset the timeout) - for code which + * intentionally disables interrupts for a long time. This call is stateless. + * + * Though this function has "nmi" in the name, the hardlockup watchdog might + * not be backed by NMIs. This function will likely be renamed to + * touch_hardlockup_watchdog() in the future. */ static inline void touch_nmi_watchdog(void) { + /* + * Pass on to the hardlockup detector selected via CONFIG_. Note that + * the hardlockup detector may not be arch-specific nor using NMIs + * and the arch_touch_nmi_watchdog() function will likely be renamed + * in the future. + */ arch_touch_nmi_watchdog(); + touch_softlockup_watchdog(); } @@ -194,10 +206,11 @@ static inline bool trigger_single_cpu_backtrace(int cpu) #ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF u64 hw_nmi_get_sample_period(int watchdog_thresh); +bool arch_perf_nmi_is_available(void); #endif #if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ - defined(CONFIG_HARDLOCKUP_DETECTOR) + defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) void watchdog_update_hrtimer_threshold(u64 period); #else static inline void watchdog_update_hrtimer_threshold(u64 period) { } diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 2aba75145144..86544707236a 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -106,12 +106,22 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); #define RAW_NOTIFIER_INIT(name) { \ .head = NULL } +#ifdef CONFIG_TREE_SRCU #define SRCU_NOTIFIER_INIT(name, pcpu) \ { \ .mutex = __MUTEX_INITIALIZER(name.mutex), \ .head = NULL, \ + .srcuu = __SRCU_USAGE_INIT(name.srcuu), \ .srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \ } +#else +#define SRCU_NOTIFIER_INIT(name, pcpu) \ + { \ + .mutex = __MUTEX_INITIALIZER(name.mutex), \ + .head = NULL, \ + .srcu = __SRCU_STRUCT_INIT(name.srcu, name.srcuu, pcpu), \ + } +#endif #define ATOMIC_NOTIFIER_HEAD(name) \ struct atomic_notifier_head name = \ diff --git a/include/linux/nubus.h b/include/linux/nubus.h index 392fc6c53e96..bdcd85e622d8 100644 --- a/include/linux/nubus.h +++ b/include/linux/nubus.h @@ -93,6 +93,7 @@ extern struct bus_type nubus_bus_type; /* Generic NuBus interface functions, modelled after the PCI interface */ #ifdef CONFIG_PROC_FS +extern bool nubus_populate_procfs; void nubus_proc_init(void); struct proc_dir_entry *nubus_proc_add_board(struct nubus_board *board); struct proc_dir_entry *nubus_proc_add_rsrc_dir(struct proc_dir_entry *procdir, diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h index fa092b9be2fd..4109f1bd6128 100644 --- a/include/linux/nvme-fc-driver.h +++ b/include/linux/nvme-fc-driver.h @@ -185,7 +185,6 @@ enum nvmefc_fcp_datadir { * @first_sgl: memory for 1st scatter/gather list segment for payload data * @sg_cnt: number of elements in the scatter/gather list * @io_dir: direction of the FCP request (see NVMEFC_FCP_xxx) - * @sqid: The nvme SQID the command is being issued on * @done: The callback routine the LLDD is to invoke upon completion of * the FCP operation. req argument is the pointer to the original * FCP IO operation. @@ -194,12 +193,13 @@ enum nvmefc_fcp_datadir { * while processing the operation. The length of the buffer * corresponds to the fcprqst_priv_sz value specified in the * nvme_fc_port_template supplied by the LLDD. + * @sqid: The nvme SQID the command is being issued on * * Values set by the LLDD indicating completion status of the FCP operation. * Must be set prior to calling the done() callback. + * @rcv_rsplen: length, in bytes, of the FCP RSP IU received. * @transferred_length: amount of payload data, in bytes, that were * transferred. Should equal payload_length on success. - * @rcv_rsplen: length, in bytes, of the FCP RSP IU received. * @status: Completion status of the FCP operation. must be 0 upon success, * negative errno value upon failure (ex: -EIO). Note: this is * NOT a reflection of the NVME CQE completion status. Only the @@ -219,14 +219,14 @@ struct nvmefc_fcp_req { int sg_cnt; enum nvmefc_fcp_datadir io_dir; - __le16 sqid; - void (*done)(struct nvmefc_fcp_req *req); void *private; - u32 transferred_length; + __le16 sqid; + u16 rcv_rsplen; + u32 transferred_length; u32 status; } __aligned(sizeof(u64)); /* alignment for other things alloc'd with */ diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 779507ac750b..182b6d614eb1 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -759,20 +759,55 @@ enum { NVME_LBART_ATTRIB_HIDE = 1 << 1, }; +enum nvme_pr_type { + NVME_PR_WRITE_EXCLUSIVE = 1, + NVME_PR_EXCLUSIVE_ACCESS = 2, + NVME_PR_WRITE_EXCLUSIVE_REG_ONLY = 3, + NVME_PR_EXCLUSIVE_ACCESS_REG_ONLY = 4, + NVME_PR_WRITE_EXCLUSIVE_ALL_REGS = 5, + NVME_PR_EXCLUSIVE_ACCESS_ALL_REGS = 6, +}; + +enum nvme_eds { + NVME_EXTENDED_DATA_STRUCT = 0x1, +}; + +struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; +}; + struct nvme_reservation_status { __le32 gen; __u8 rtype; __u8 regctl[2]; __u8 resv5[2]; __u8 ptpls; - __u8 resv10[13]; - struct { - __le16 cntlid; - __u8 rcsts; - __u8 resv3[5]; - __le64 hostid; - __le64 rkey; - } regctl_ds[]; + __u8 resv10[14]; + struct nvme_registered_ctrl regctl_ds[]; +}; + +struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 rsvd32[32]; +}; + +struct nvme_reservation_status_ext { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 resv5[2]; + __u8 ptpls; + __u8 resv10[14]; + __u8 rsvd24[40]; + struct nvme_registered_ctrl_ext regctl_eds[]; }; enum nvme_async_event_type { diff --git a/include/linux/olpc-ec.h b/include/linux/olpc-ec.h index c4602364e909..3c2891d85c41 100644 --- a/include/linux/olpc-ec.h +++ b/include/linux/olpc-ec.h @@ -56,6 +56,8 @@ extern int olpc_ec_sci_query(u16 *sci_value); extern bool olpc_ec_wakeup_available(void); +asmlinkage int xo1_do_sleep(u8 sleep_state); + #else static inline int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 0e33b5cbdb9f..f9b60313eaea 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -283,7 +283,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * @member: Name of the array member. * @count: Number of elements in the array. * - * Calculates size of memory needed for structure @p followed by an + * Calculates size of memory needed for structure of @p followed by an * array of @count number of @member elements. * * Return: number of bytes needed or SIZE_MAX on overflow. @@ -293,4 +293,20 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) sizeof(*(p)) + flex_array_size(p, member, count), \ size_add(sizeof(*(p)), flex_array_size(p, member, count))) +/** + * struct_size_t() - Calculate size of structure with trailing flexible array + * @type: structure type name. + * @member: Name of the array member. + * @count: Number of elements in the array. + * + * Calculates size of memory needed for structure @type followed by an + * array of @count number of @member elements. Prefer using struct_size() + * when possible instead, to keep calculations associated with a specific + * instance variable of type @type. + * + * Return: number of bytes needed or SIZE_MAX on overflow. + */ +#define struct_size_t(type, member, count) \ + struct_size((type *)NULL, member, count) + #endif /* __LINUX_OVERFLOW_H */ diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 1c68d67b832f..92a2063a0a23 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -617,6 +617,12 @@ PAGEFLAG_FALSE(VmemmapSelfHosted, vmemmap_self_hosted) * Please note that, confusingly, "page_mapping" refers to the inode * address_space which maps the page from disk; whereas "page_mapped" * refers to user virtual address space into which the page is mapped. + * + * For slab pages, since slab reuses the bits in struct page to store its + * internal states, the page->mapping does not exist as such, nor do these + * flags below. So in order to avoid testing non-existent bits, please + * make sure that PageSlab(page) actually evaluates to false before calling + * the following functions (e.g., PageAnon). See mm/slab.h. */ #define PAGE_MAPPING_ANON 0x1 #define PAGE_MAPPING_MOVABLE 0x2 diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 5456b7be38ae..4ac34392823a 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h @@ -37,27 +37,12 @@ void set_pageblock_migratetype(struct page *page, int migratetype); int move_freepages_block(struct zone *zone, struct page *page, int migratetype, int *num_movable); -/* - * Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE. - */ -int -start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, - int migratetype, int flags, gfp_t gfp_flags); +int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, + int migratetype, int flags, gfp_t gfp_flags); -/* - * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE. - * target range is [start_pfn, end_pfn) - */ -void -undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, - int migratetype); +void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, + int migratetype); -/* - * Test all pages in [start_pfn, end_pfn) are isolated or not. - */ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, int isol_flags); - -struct page *alloc_migrate_target(struct page *page, unsigned long private); - #endif diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index a56308a9d1a4..716953ee1ebd 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -30,6 +30,9 @@ static inline void invalidate_remote_inode(struct inode *inode) int invalidate_inode_pages2(struct address_space *mapping); int invalidate_inode_pages2_range(struct address_space *mapping, pgoff_t start, pgoff_t end); +int kiocb_invalidate_pages(struct kiocb *iocb, size_t count); +void kiocb_invalidate_post_direct_write(struct kiocb *iocb, size_t count); + int write_inode_now(struct inode *, int sync); int filemap_fdatawrite(struct address_space *); int filemap_flush(struct address_space *); @@ -54,6 +57,7 @@ int filemap_check_errors(struct address_space *mapping); void __filemap_set_wb_err(struct address_space *mapping, int err); int filemap_fdatawrite_wbc(struct address_space *mapping, struct writeback_control *wbc); +int kiocb_write_and_wait(struct kiocb *iocb, size_t count); static inline int filemap_write_and_wait(struct address_space *mapping) { @@ -1078,8 +1082,6 @@ int filemap_migrate_folio(struct address_space *mapping, struct folio *dst, #else #define filemap_migrate_folio NULL #endif -void page_endio(struct page *page, bool is_write, int err); - void folio_end_private_2(struct folio *folio); void folio_wait_private_2(struct folio *folio); int folio_wait_private_2_killable(struct folio *folio); diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index f582f7213ea5..87cc678adc85 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -3,65 +3,18 @@ * include/linux/pagevec.h * * In many places it is efficient to batch an operation up against multiple - * pages. A pagevec is a multipage container which is used for that. + * folios. A folio_batch is a container which is used for that. */ #ifndef _LINUX_PAGEVEC_H #define _LINUX_PAGEVEC_H -#include <linux/xarray.h> +#include <linux/types.h> -/* 15 pointers + header align the pagevec structure to a power of two */ +/* 15 pointers + header align the folio_batch structure to a power of two */ #define PAGEVEC_SIZE 15 -struct page; struct folio; -struct address_space; - -/* Layout must match folio_batch */ -struct pagevec { - unsigned char nr; - bool percpu_pvec_drained; - struct page *pages[PAGEVEC_SIZE]; -}; - -void __pagevec_release(struct pagevec *pvec); - -static inline void pagevec_init(struct pagevec *pvec) -{ - pvec->nr = 0; - pvec->percpu_pvec_drained = false; -} - -static inline void pagevec_reinit(struct pagevec *pvec) -{ - pvec->nr = 0; -} - -static inline unsigned pagevec_count(struct pagevec *pvec) -{ - return pvec->nr; -} - -static inline unsigned pagevec_space(struct pagevec *pvec) -{ - return PAGEVEC_SIZE - pvec->nr; -} - -/* - * Add a page to a pagevec. Returns the number of slots still available. - */ -static inline unsigned pagevec_add(struct pagevec *pvec, struct page *page) -{ - pvec->pages[pvec->nr++] = page; - return pagevec_space(pvec); -} - -static inline void pagevec_release(struct pagevec *pvec) -{ - if (pagevec_count(pvec)) - __pagevec_release(pvec); -} /** * struct folio_batch - A collection of folios. @@ -78,11 +31,6 @@ struct folio_batch { struct folio *folios[PAGEVEC_SIZE]; }; -/* Layout must match pagevec */ -static_assert(sizeof(struct pagevec) == sizeof(struct folio_batch)); -static_assert(offsetof(struct pagevec, pages) == - offsetof(struct folio_batch, folios)); - /** * folio_batch_init() - Initialise a batch of folios * @fbatch: The folio batch. @@ -105,7 +53,7 @@ static inline unsigned int folio_batch_count(struct folio_batch *fbatch) return fbatch->nr; } -static inline unsigned int fbatch_space(struct folio_batch *fbatch) +static inline unsigned int folio_batch_space(struct folio_batch *fbatch) { return PAGEVEC_SIZE - fbatch->nr; } @@ -124,12 +72,15 @@ static inline unsigned folio_batch_add(struct folio_batch *fbatch, struct folio *folio) { fbatch->folios[fbatch->nr++] = folio; - return fbatch_space(fbatch); + return folio_batch_space(fbatch); } +void __folio_batch_release(struct folio_batch *pvec); + static inline void folio_batch_release(struct folio_batch *fbatch) { - pagevec_release((struct pagevec *)fbatch); + if (folio_batch_count(fbatch)) + __folio_batch_release(fbatch); } void folio_batch_remove_exceptionals(struct folio_batch *fbatch); diff --git a/include/linux/panic.h b/include/linux/panic.h index 979b776e3bcb..6717b15e798c 100644 --- a/include/linux/panic.h +++ b/include/linux/panic.h @@ -32,6 +32,9 @@ extern int sysctl_panic_on_stackoverflow; extern bool crash_kexec_post_notifiers; +extern void __stack_chk_fail(void); +void abort(void); + /* * panic_cpu is used for synchronizing panic() and crash_kexec() execution. It * holds a CPU number which is executing panic() currently. A value of diff --git a/include/linux/parport.h b/include/linux/parport.h index a0bc9e0267b7..999eddd619b7 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -180,6 +180,8 @@ struct ieee1284_info { struct semaphore irq; }; +#define PARPORT_NAME_MAX_LEN 15 + /* A parallel port */ struct parport { unsigned long base; /* base address */ @@ -514,7 +516,7 @@ extern int parport_device_proc_register(struct pardevice *device); extern int parport_device_proc_unregister(struct pardevice *device); /* If PC hardware is the only type supported, we can optimise a bit. */ -#if !defined(CONFIG_PARPORT_NOT_PC) +#if !defined(CONFIG_PARPORT_NOT_PC) && defined(CONFIG_PARPORT_PC) #include <linux/parport_pc.h> #define parport_write_data(p,x) parport_pc_write_data(p,x) diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index 301bb0e53707..5cb694031072 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -203,7 +203,9 @@ void pci_epc_destroy(struct pci_epc *epc); int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf, enum pci_epc_interface_type type); void pci_epc_linkup(struct pci_epc *epc); +void pci_epc_linkdown(struct pci_epc *epc); void pci_epc_init_notify(struct pci_epc *epc); +void pci_epc_bme_notify(struct pci_epc *epc); void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf, enum pci_epc_interface_type type); int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no, diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index a215dc8ce693..3f44b6aec477 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -71,10 +71,14 @@ struct pci_epf_ops { * struct pci_epf_event_ops - Callbacks for capturing the EPC events * @core_init: Callback for the EPC initialization complete event * @link_up: Callback for the EPC link up event + * @link_down: Callback for the EPC link down event + * @bme: Callback for the EPC BME (Bus Master Enable) event */ struct pci_epc_event_ops { int (*core_init)(struct pci_epf *epf); int (*link_up)(struct pci_epf *epf); + int (*link_down)(struct pci_epf *epf); + int (*bme)(struct pci_epf *epf); }; /** @@ -89,7 +93,8 @@ struct pci_epc_event_ops { * @id_table: identifies EPF devices for probing */ struct pci_epf_driver { - int (*probe)(struct pci_epf *epf); + int (*probe)(struct pci_epf *epf, + const struct pci_epf_device_id *id); void (*remove)(struct pci_epf *epf); struct device_driver driver; @@ -131,6 +136,7 @@ struct pci_epf_bar { * @epc: the EPC device to which this EPF device is bound * @epf_pf: the physical EPF device to which this virtual EPF device is bound * @driver: the EPF driver to which this EPF device is bound + * @id: Pointer to the EPF device ID * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc * @lock: mutex to protect pci_epf_ops * @sec_epc: the secondary EPC device to which this EPF device is bound @@ -158,6 +164,7 @@ struct pci_epf { struct pci_epc *epc; struct pci_epf *epf_pf; struct pci_epf_driver *driver; + const struct pci_epf_device_id *id; struct list_head list; /* mutex to protect against concurrent access of pci_epf_ops */ struct mutex lock; @@ -214,8 +221,6 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, enum pci_epc_interface_type type); int pci_epf_bind(struct pci_epf *epf); void pci_epf_unbind(struct pci_epf *epf); -struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf, - struct config_group *group); int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf); void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf); #endif /* __LINUX_PCI_EPF_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 60b8772b5bd4..c69a2cc1f412 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1903,6 +1903,7 @@ static inline int pci_dev_present(const struct pci_device_id *ids) #define pci_dev_put(dev) do { } while (0) static inline void pci_set_master(struct pci_dev *dev) { } +static inline void pci_clear_master(struct pci_dev *dev) { } static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } static inline void pci_disable_device(struct pci_dev *dev) { } static inline int pcim_enable_device(struct pci_dev *pdev) { return -EIO; } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 45c3d62e616d..2dc75df1437f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2,7 +2,7 @@ /* * PCI Class, Vendor and Device IDs * - * Please keep sorted. + * Please keep sorted by numeric Vendor ID and Device ID. * * Do not add new entries to this file unless the definitions * are shared between multiple drivers. @@ -151,6 +151,9 @@ #define PCI_CLASS_SP_DPIO 0x1100 #define PCI_CLASS_SP_OTHER 0x1180 +#define PCI_BASE_CLASS_ACCELERATOR 0x12 +#define PCI_CLASS_ACCELERATOR_PROCESSING 0x1200 + #define PCI_CLASS_OTHERS 0xff /* Vendors and devices. Sort key: vendor first, device next. */ @@ -158,6 +161,11 @@ #define PCI_VENDOR_ID_LOONGSON 0x0014 +#define PCI_DEVICE_ID_LOONGSON_HDA 0x7a07 +#define PCI_DEVICE_ID_LOONGSON_HDMI 0x7a37 + +#define PCI_VENDOR_ID_SOLIDIGM 0x025e + #define PCI_VENDOR_ID_TTTECH 0x0357 #define PCI_DEVICE_ID_TTTECH_MC322 0x000a @@ -567,6 +575,8 @@ #define PCI_DEVICE_ID_AMD_19H_M50H_DF_F3 0x166d #define PCI_DEVICE_ID_AMD_19H_M60H_DF_F3 0x14e3 #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F3 0x14f3 +#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb +#define PCI_DEVICE_ID_AMD_MI200_DF_F3 0x14d3 #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 diff --git a/include/linux/pcs-altera-tse.h b/include/linux/pcs-altera-tse.h deleted file mode 100644 index 92ab9f08e835..000000000000 --- a/include/linux/pcs-altera-tse.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2022 Bootlin - * - * Maxime Chevallier <maxime.chevallier@bootlin.com> - */ - -#ifndef __LINUX_PCS_ALTERA_TSE_H -#define __LINUX_PCS_ALTERA_TSE_H - -struct phylink_pcs; -struct net_device; - -struct phylink_pcs *alt_tse_pcs_create(struct net_device *ndev, - void __iomem *pcs_base, int reg_width); - -#endif /* __LINUX_PCS_ALTERA_TSE_H */ diff --git a/include/linux/pcs-lynx.h b/include/linux/pcs-lynx.h index 5712cc2ce775..7958cccd16f2 100644 --- a/include/linux/pcs-lynx.h +++ b/include/linux/pcs-lynx.h @@ -9,9 +9,8 @@ #include <linux/mdio.h> #include <linux/phylink.h> -struct mdio_device *lynx_get_mdio_device(struct phylink_pcs *pcs); - -struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio); +struct phylink_pcs *lynx_pcs_create_mdiodev(struct mii_bus *bus, int addr); +struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node); void lynx_pcs_destroy(struct phylink_pcs *pcs); diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h index d2da1e0b4a92..ff99cf7a5d0d 100644 --- a/include/linux/pcs/pcs-xpcs.h +++ b/include/linux/pcs/pcs-xpcs.h @@ -18,6 +18,7 @@ #define DW_AN_C37_SGMII 2 #define DW_2500BASEX 3 #define DW_AN_C37_1000BASEX 4 +#define DW_10GBASER 5 struct xpcs_id; @@ -28,15 +29,15 @@ struct dw_xpcs { }; int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface); -void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode, +void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, - unsigned int mode, const unsigned long *advertising); + const unsigned long *advertising, unsigned int neg_mode); void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces); int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable); -struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev, - phy_interface_t interface); +struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr, + phy_interface_t interface); void xpcs_destroy(struct dw_xpcs *xpcs); #endif /* __LINUX_PCS_XPCS_H */ diff --git a/include/linux/pds/pds_adminq.h b/include/linux/pds/pds_adminq.h index 98a60ce87b92..bcba7fda3cc9 100644 --- a/include/linux/pds/pds_adminq.h +++ b/include/linux/pds/pds_adminq.h @@ -222,6 +222,27 @@ enum pds_core_lif_type { PDS_CORE_LIF_TYPE_DEFAULT = 0, }; +#define PDS_CORE_IFNAMSIZ 16 + +/** + * enum pds_core_logical_qtype - Logical Queue Types + * @PDS_CORE_QTYPE_ADMINQ: Administrative Queue + * @PDS_CORE_QTYPE_NOTIFYQ: Notify Queue + * @PDS_CORE_QTYPE_RXQ: Receive Queue + * @PDS_CORE_QTYPE_TXQ: Transmit Queue + * @PDS_CORE_QTYPE_EQ: Event Queue + * @PDS_CORE_QTYPE_MAX: Max queue type supported + */ +enum pds_core_logical_qtype { + PDS_CORE_QTYPE_ADMINQ = 0, + PDS_CORE_QTYPE_NOTIFYQ = 1, + PDS_CORE_QTYPE_RXQ = 2, + PDS_CORE_QTYPE_TXQ = 3, + PDS_CORE_QTYPE_EQ = 4, + + PDS_CORE_QTYPE_MAX = 16 /* don't change - used in struct size */ +}; + /** * union pds_core_lif_config - LIF configuration * @state: LIF state (enum pds_core_lif_state) @@ -584,6 +605,219 @@ struct pds_core_q_init_comp { u8 color; }; +/* + * enum pds_vdpa_cmd_opcode - vDPA Device commands + */ +enum pds_vdpa_cmd_opcode { + PDS_VDPA_CMD_INIT = 48, + PDS_VDPA_CMD_IDENT = 49, + PDS_VDPA_CMD_RESET = 51, + PDS_VDPA_CMD_VQ_RESET = 52, + PDS_VDPA_CMD_VQ_INIT = 53, + PDS_VDPA_CMD_STATUS_UPDATE = 54, + PDS_VDPA_CMD_SET_FEATURES = 55, + PDS_VDPA_CMD_SET_ATTR = 56, +}; + +/** + * struct pds_vdpa_cmd - generic command + * @opcode: Opcode + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + */ +struct pds_vdpa_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; +}; + +/** + * struct pds_vdpa_init_cmd - INIT command + * @opcode: Opcode PDS_VDPA_CMD_INIT + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + */ +struct pds_vdpa_init_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; +}; + +/** + * struct pds_vdpa_ident - vDPA identification data + * @hw_features: vDPA features supported by device + * @max_vqs: max queues available (2 queues for a single queuepair) + * @max_qlen: log(2) of maximum number of descriptors + * @min_qlen: log(2) of minimum number of descriptors + * + * This struct is used in a DMA block that is set up for the PDS_VDPA_CMD_IDENT + * transaction. Set up the DMA block and send the address in the IDENT cmd + * data, the DSC will write the ident information, then we can remove the DMA + * block after reading the answer. If the completion status is 0, then there + * is valid information, else there was an error and the data should be invalid. + */ +struct pds_vdpa_ident { + __le64 hw_features; + __le16 max_vqs; + __le16 max_qlen; + __le16 min_qlen; +}; + +/** + * struct pds_vdpa_ident_cmd - IDENT command + * @opcode: Opcode PDS_VDPA_CMD_IDENT + * @rsvd: Word boundary padding + * @vf_id: VF id + * @len: length of ident info DMA space + * @ident_pa: address for DMA of ident info (struct pds_vdpa_ident) + * only used for this transaction, then forgotten by DSC + */ +struct pds_vdpa_ident_cmd { + u8 opcode; + u8 rsvd; + __le16 vf_id; + __le32 len; + __le64 ident_pa; +}; + +/** + * struct pds_vdpa_status_cmd - STATUS_UPDATE command + * @opcode: Opcode PDS_VDPA_CMD_STATUS_UPDATE + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + * @status: new status bits + */ +struct pds_vdpa_status_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; + u8 status; +}; + +/** + * enum pds_vdpa_attr - List of VDPA device attributes + * @PDS_VDPA_ATTR_MAC: MAC address + * @PDS_VDPA_ATTR_MAX_VQ_PAIRS: Max virtqueue pairs + */ +enum pds_vdpa_attr { + PDS_VDPA_ATTR_MAC = 1, + PDS_VDPA_ATTR_MAX_VQ_PAIRS = 2, +}; + +/** + * struct pds_vdpa_setattr_cmd - SET_ATTR command + * @opcode: Opcode PDS_VDPA_CMD_SET_ATTR + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + * @attr: attribute to be changed (enum pds_vdpa_attr) + * @pad: Word boundary padding + * @mac: new mac address to be assigned as vdpa device address + * @max_vq_pairs: new limit of virtqueue pairs + */ +struct pds_vdpa_setattr_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; + u8 attr; + u8 pad[3]; + union { + u8 mac[6]; + __le16 max_vq_pairs; + } __packed; +}; + +/** + * struct pds_vdpa_vq_init_cmd - queue init command + * @opcode: Opcode PDS_VDPA_CMD_VQ_INIT + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + * @qid: Queue id (bit0 clear = rx, bit0 set = tx, qid=N is ctrlq) + * @len: log(2) of max descriptor count + * @desc_addr: DMA address of descriptor area + * @avail_addr: DMA address of available descriptors (aka driver area) + * @used_addr: DMA address of used descriptors (aka device area) + * @intr_index: interrupt index + * @avail_index: initial device position in available ring + * @used_index: initial device position in used ring + */ +struct pds_vdpa_vq_init_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; + __le16 qid; + __le16 len; + __le64 desc_addr; + __le64 avail_addr; + __le64 used_addr; + __le16 intr_index; + __le16 avail_index; + __le16 used_index; +}; + +/** + * struct pds_vdpa_vq_init_comp - queue init completion + * @status: Status of the command (enum pds_core_status_code) + * @hw_qtype: HW queue type, used in doorbell selection + * @hw_qindex: HW queue index, used in doorbell selection + * @rsvd: Word boundary padding + * @color: Color bit + */ +struct pds_vdpa_vq_init_comp { + u8 status; + u8 hw_qtype; + __le16 hw_qindex; + u8 rsvd[11]; + u8 color; +}; + +/** + * struct pds_vdpa_vq_reset_cmd - queue reset command + * @opcode: Opcode PDS_VDPA_CMD_VQ_RESET + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + * @qid: Queue id + */ +struct pds_vdpa_vq_reset_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; + __le16 qid; +}; + +/** + * struct pds_vdpa_vq_reset_comp - queue reset completion + * @status: Status of the command (enum pds_core_status_code) + * @rsvd0: Word boundary padding + * @avail_index: current device position in available ring + * @used_index: current device position in used ring + * @rsvd: Word boundary padding + * @color: Color bit + */ +struct pds_vdpa_vq_reset_comp { + u8 status; + u8 rsvd0; + __le16 avail_index; + __le16 used_index; + u8 rsvd[9]; + u8 color; +}; + +/** + * struct pds_vdpa_set_features_cmd - set hw features + * @opcode: Opcode PDS_VDPA_CMD_SET_FEATURES + * @vdpa_index: Index for vdpa subdevice + * @vf_id: VF id + * @rsvd: Word boundary padding + * @features: Feature bit mask + */ +struct pds_vdpa_set_features_cmd { + u8 opcode; + u8 vdpa_index; + __le16 vf_id; + __le32 rsvd; + __le64 features; +}; + union pds_core_adminq_cmd { u8 opcode; u8 bytes[64]; @@ -600,6 +834,16 @@ union pds_core_adminq_cmd { struct pds_core_q_identify_cmd q_ident; struct pds_core_q_init_cmd q_init; + + struct pds_vdpa_cmd vdpa; + struct pds_vdpa_init_cmd vdpa_init; + struct pds_vdpa_ident_cmd vdpa_ident; + struct pds_vdpa_status_cmd vdpa_status; + struct pds_vdpa_setattr_cmd vdpa_setattr; + struct pds_vdpa_set_features_cmd vdpa_set_features; + struct pds_vdpa_vq_init_cmd vdpa_vq_init; + struct pds_vdpa_vq_reset_cmd vdpa_vq_reset; + }; union pds_core_adminq_comp { @@ -621,6 +865,9 @@ union pds_core_adminq_comp { struct pds_core_q_identify_comp q_ident; struct pds_core_q_init_comp q_init; + + struct pds_vdpa_vq_init_comp vdpa_vq_init; + struct pds_vdpa_vq_reset_comp vdpa_vq_reset; }; #ifndef __CHECKER__ diff --git a/include/linux/pds/pds_common.h b/include/linux/pds/pds_common.h index 060331486d50..435c8e8161c2 100644 --- a/include/linux/pds/pds_common.h +++ b/include/linux/pds/pds_common.h @@ -39,26 +39,7 @@ enum pds_core_vif_types { #define PDS_DEV_TYPE_RDMA_STR "RDMA" #define PDS_DEV_TYPE_LM_STR "LM" -#define PDS_CORE_IFNAMSIZ 16 - -/** - * enum pds_core_logical_qtype - Logical Queue Types - * @PDS_CORE_QTYPE_ADMINQ: Administrative Queue - * @PDS_CORE_QTYPE_NOTIFYQ: Notify Queue - * @PDS_CORE_QTYPE_RXQ: Receive Queue - * @PDS_CORE_QTYPE_TXQ: Transmit Queue - * @PDS_CORE_QTYPE_EQ: Event Queue - * @PDS_CORE_QTYPE_MAX: Max queue type supported - */ -enum pds_core_logical_qtype { - PDS_CORE_QTYPE_ADMINQ = 0, - PDS_CORE_QTYPE_NOTIFYQ = 1, - PDS_CORE_QTYPE_RXQ = 2, - PDS_CORE_QTYPE_TXQ = 3, - PDS_CORE_QTYPE_EQ = 4, - - PDS_CORE_QTYPE_MAX = 16 /* don't change - used in struct size */ -}; +#define PDS_VDPA_DEV_NAME PDS_CORE_DRV_NAME "." PDS_DEV_TYPE_VDPA_STR int pdsc_register_notify(struct notifier_block *nb); void pdsc_unregister_notify(struct notifier_block *nb); diff --git a/include/linux/pe.h b/include/linux/pe.h index 5e1e11540870..fdf9c95709ba 100644 --- a/include/linux/pe.h +++ b/include/linux/pe.h @@ -11,25 +11,26 @@ #include <linux/types.h> /* - * Linux EFI stub v1.0 adds the following functionality: - * - Loading initrd from the LINUX_EFI_INITRD_MEDIA_GUID device path, - * - Loading/starting the kernel from firmware that targets a different - * machine type, via the entrypoint exposed in the .compat PE/COFF section. + * Starting from version v3.0, the major version field should be interpreted as + * a bit mask of features supported by the kernel's EFI stub: + * - 0x1: initrd loading from the LINUX_EFI_INITRD_MEDIA_GUID device path, + * - 0x2: initrd loading using the initrd= command line option, where the file + * may be specified using device path notation, and is not required to + * reside on the same volume as the loaded kernel image. * * The recommended way of loading and starting v1.0 or later kernels is to use * the LoadImage() and StartImage() EFI boot services, and expose the initrd * via the LINUX_EFI_INITRD_MEDIA_GUID device path. * - * Versions older than v1.0 support initrd loading via the image load options - * (using initrd=, limited to the volume from which the kernel itself was - * loaded), or via arch specific means (bootparams, DT, etc). + * Versions older than v1.0 may support initrd loading via the image load + * options (using initrd=, limited to the volume from which the kernel itself + * was loaded), or only via arch specific means (bootparams, DT, etc). * - * On x86, LoadImage() and StartImage() can be omitted if the EFI handover - * protocol is implemented, which can be inferred from the version, - * handover_offset and xloadflags fields in the bootparams structure. + * The minor version field must remain 0x0. + * (https://lore.kernel.org/all/efd6f2d4-547c-1378-1faa-53c044dbd297@gmail.com/) */ -#define LINUX_EFISTUB_MAJOR_VERSION 0x1 -#define LINUX_EFISTUB_MINOR_VERSION 0x1 +#define LINUX_EFISTUB_MAJOR_VERSION 0x3 +#define LINUX_EFISTUB_MINOR_VERSION 0x0 /* * LINUX_PE_MAGIC appears at offset 0x38 into the MS-DOS header of EFI bootable diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index e60727be79c4..ec3573119923 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -343,31 +343,19 @@ static __always_inline void __this_cpu_preempt_check(const char *op) { } pscr2_ret__; \ }) -/* - * Special handling for cmpxchg_double. cmpxchg_double is passed two - * percpu variables. The first has to be aligned to a double word - * boundary and the second has to follow directly thereafter. - * We enforce this on all architectures even if they don't support - * a double cmpxchg instruction, since it's a cheap requirement, and it - * avoids breaking the requirement for architectures with the instruction. - */ -#define __pcpu_double_call_return_bool(stem, pcp1, pcp2, ...) \ +#define __pcpu_size_call_return2bool(stem, variable, ...) \ ({ \ - bool pdcrb_ret__; \ - __verify_pcpu_ptr(&(pcp1)); \ - BUILD_BUG_ON(sizeof(pcp1) != sizeof(pcp2)); \ - VM_BUG_ON((unsigned long)(&(pcp1)) % (2 * sizeof(pcp1))); \ - VM_BUG_ON((unsigned long)(&(pcp2)) != \ - (unsigned long)(&(pcp1)) + sizeof(pcp1)); \ - switch(sizeof(pcp1)) { \ - case 1: pdcrb_ret__ = stem##1(pcp1, pcp2, __VA_ARGS__); break; \ - case 2: pdcrb_ret__ = stem##2(pcp1, pcp2, __VA_ARGS__); break; \ - case 4: pdcrb_ret__ = stem##4(pcp1, pcp2, __VA_ARGS__); break; \ - case 8: pdcrb_ret__ = stem##8(pcp1, pcp2, __VA_ARGS__); break; \ + bool pscr2_ret__; \ + __verify_pcpu_ptr(&(variable)); \ + switch(sizeof(variable)) { \ + case 1: pscr2_ret__ = stem##1(variable, __VA_ARGS__); break; \ + case 2: pscr2_ret__ = stem##2(variable, __VA_ARGS__); break; \ + case 4: pscr2_ret__ = stem##4(variable, __VA_ARGS__); break; \ + case 8: pscr2_ret__ = stem##8(variable, __VA_ARGS__); break; \ default: \ __bad_size_call_parameter(); break; \ } \ - pdcrb_ret__; \ + pscr2_ret__; \ }) #define __pcpu_size_call(stem, variable, ...) \ @@ -426,9 +414,8 @@ do { \ #define raw_cpu_xchg(pcp, nval) __pcpu_size_call_return2(raw_cpu_xchg_, pcp, nval) #define raw_cpu_cmpxchg(pcp, oval, nval) \ __pcpu_size_call_return2(raw_cpu_cmpxchg_, pcp, oval, nval) -#define raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - __pcpu_double_call_return_bool(raw_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2) - +#define raw_cpu_try_cmpxchg(pcp, ovalp, nval) \ + __pcpu_size_call_return2bool(raw_cpu_try_cmpxchg_, pcp, ovalp, nval) #define raw_cpu_sub(pcp, val) raw_cpu_add(pcp, -(val)) #define raw_cpu_inc(pcp) raw_cpu_add(pcp, 1) #define raw_cpu_dec(pcp) raw_cpu_sub(pcp, 1) @@ -488,11 +475,6 @@ do { \ raw_cpu_cmpxchg(pcp, oval, nval); \ }) -#define __this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ -({ __this_cpu_preempt_check("cmpxchg_double"); \ - raw_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2); \ -}) - #define __this_cpu_sub(pcp, val) __this_cpu_add(pcp, -(typeof(pcp))(val)) #define __this_cpu_inc(pcp) __this_cpu_add(pcp, 1) #define __this_cpu_dec(pcp) __this_cpu_sub(pcp, 1) @@ -513,9 +495,8 @@ do { \ #define this_cpu_xchg(pcp, nval) __pcpu_size_call_return2(this_cpu_xchg_, pcp, nval) #define this_cpu_cmpxchg(pcp, oval, nval) \ __pcpu_size_call_return2(this_cpu_cmpxchg_, pcp, oval, nval) -#define this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ - __pcpu_double_call_return_bool(this_cpu_cmpxchg_double_, pcp1, pcp2, oval1, oval2, nval1, nval2) - +#define this_cpu_try_cmpxchg(pcp, ovalp, nval) \ + __pcpu_size_call_return2bool(this_cpu_try_cmpxchg_, pcp, ovalp, nval) #define this_cpu_sub(pcp, val) this_cpu_add(pcp, -(typeof(pcp))(val)) #define this_cpu_inc(pcp) this_cpu_add(pcp, 1) #define this_cpu_dec(pcp) this_cpu_sub(pcp, 1) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 1338ea2aa720..b3b458442330 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -8,6 +8,7 @@ #include <linux/cpumask.h> #include <linux/pfn.h> #include <linux/init.h> +#include <linux/cleanup.h> #include <asm/percpu.h> @@ -103,12 +104,10 @@ extern void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai); extern void __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, void *base_addr); -#ifdef CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK extern int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, size_t atom_size, pcpu_fc_cpu_distance_fn_t cpu_distance_fn, pcpu_fc_cpu_to_node_fn_t cpu_to_nd_fn); -#endif #ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK void __init pcpu_populate_pte(unsigned long addr); @@ -127,6 +126,9 @@ extern void __init setup_per_cpu_areas(void); extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1); extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1); extern void free_percpu(void __percpu *__pdata); + +DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T)) + extern phys_addr_t per_cpu_ptr_to_phys(void *addr); #define alloc_percpu_gfp(type, gfp) \ diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 525b5d64e394..a0801f68762b 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -26,9 +26,11 @@ */ #define ARMPMU_EVT_64BIT 0x00001 /* Event uses a 64bit counter */ #define ARMPMU_EVT_47BIT 0x00002 /* Event uses a 47bit counter */ +#define ARMPMU_EVT_63BIT 0x00004 /* Event uses a 63bit counter */ static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_64BIT) == ARMPMU_EVT_64BIT); static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_47BIT) == ARMPMU_EVT_47BIT); +static_assert((PERF_EVENT_FLAG_ARCH & ARMPMU_EVT_63BIT) == ARMPMU_EVT_63BIT); #define HW_OP_UNSUPPORTED 0xFFFF #define C(_x) PERF_COUNT_HW_CACHE_##_x @@ -171,6 +173,8 @@ void kvm_host_pmu_init(struct arm_pmu *pmu); #define kvm_host_pmu_init(x) do { } while(0) #endif +bool arm_pmu_irq_is_nmi(void); + /* Internal functions only for core arm_pmu code */ struct arm_pmu *armpmu_alloc(void); void armpmu_free(struct arm_pmu *pmu); diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index d5628a7b5eaa..2166a69e3bf2 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -295,6 +295,8 @@ struct perf_event_pmu_context; struct perf_output_handle; +#define PMU_NULL_DEV ((void *)(~0UL)) + /** * struct pmu - generic performance monitoring unit */ @@ -303,6 +305,7 @@ struct pmu { struct module *module; struct device *dev; + struct device *parent; const struct attribute_group **attr_groups; const struct attribute_group **attr_update; const char *name; @@ -827,6 +830,14 @@ struct perf_event { void *security; #endif struct list_head sb_list; + + /* + * Certain events gets forwarded to another pmu internally by over- + * writing kernel copy of event->attr.type without user being aware + * of it. event->orig_type contains original 'type' requested by + * user. + */ + __u32 orig_type; #endif /* CONFIG_PERF_EVENTS */ }; @@ -1845,9 +1856,9 @@ int perf_event_exit_cpu(unsigned int cpu); #define perf_event_exit_cpu NULL #endif -extern void __weak arch_perf_update_userpage(struct perf_event *event, - struct perf_event_mmap_page *userpg, - u64 now); +extern void arch_perf_update_userpage(struct perf_event *event, + struct perf_event_mmap_page *userpg, + u64 now); #ifdef CONFIG_MMU extern __weak u64 arch_perf_get_page_size(struct mm_struct *mm, unsigned long addr); diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index c5a51481bbb9..5063b482e34f 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -94,14 +94,22 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address) #define pte_offset_kernel pte_offset_kernel #endif -#if defined(CONFIG_HIGHPTE) -#define pte_offset_map(dir, address) \ - ((pte_t *)kmap_atomic(pmd_page(*(dir))) + \ - pte_index((address))) -#define pte_unmap(pte) kunmap_atomic((pte)) +#ifdef CONFIG_HIGHPTE +#define __pte_map(pmd, address) \ + ((pte_t *)kmap_local_page(pmd_page(*(pmd))) + pte_index((address))) +#define pte_unmap(pte) do { \ + kunmap_local((pte)); \ + /* rcu_read_unlock() to be added later */ \ +} while (0) #else -#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) -#define pte_unmap(pte) ((void)(pte)) /* NOP */ +static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address) +{ + return pte_offset_kernel(pmd, address); +} +static inline void pte_unmap(pte_t *pte) +{ + /* rcu_read_unlock() to be added later */ +} #endif /* Find an entry in the second-level page table.. */ @@ -204,12 +212,26 @@ static inline int pudp_set_access_flags(struct vm_area_struct *vma, #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif +#ifndef ptep_get +static inline pte_t ptep_get(pte_t *ptep) +{ + return READ_ONCE(*ptep); +} +#endif + +#ifndef pmdp_get +static inline pmd_t pmdp_get(pmd_t *pmdp) +{ + return READ_ONCE(*pmdp); +} +#endif + #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { - pte_t pte = *ptep; + pte_t pte = ptep_get(ptep); int r = 1; if (!pte_young(pte)) r = 0; @@ -296,7 +318,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pte_t pte = *ptep; + pte_t pte = ptep_get(ptep); pte_clear(mm, address, ptep); page_table_check_pte_clear(mm, address, pte); return pte; @@ -309,20 +331,6 @@ static inline void ptep_clear(struct mm_struct *mm, unsigned long addr, ptep_get_and_clear(mm, addr, ptep); } -#ifndef ptep_get -static inline pte_t ptep_get(pte_t *ptep) -{ - return READ_ONCE(*ptep); -} -#endif - -#ifndef pmdp_get -static inline pmd_t pmdp_get(pmd_t *pmdp) -{ - return READ_ONCE(*pmdp); -} -#endif - #ifdef CONFIG_GUP_GET_PXX_LOW_HIGH /* * For walking the pagetables without holding any locks. Some architectures @@ -511,7 +519,7 @@ extern pud_t pudp_huge_clear_flush(struct vm_area_struct *vma, struct mm_struct; static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pte_t old_pte = *ptep; + pte_t old_pte = ptep_get(ptep); set_pte_at(mm, address, ptep, pte_wrprotect(old_pte)); } #endif @@ -591,6 +599,10 @@ extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); #endif +#ifndef arch_needs_pgtable_deposit +#define arch_needs_pgtable_deposit() (false) +#endif + #ifdef CONFIG_TRANSPARENT_HUGEPAGE /* * This is an implementation of pmdp_establish() that is only suitable for an @@ -1292,9 +1304,10 @@ static inline int pud_trans_huge(pud_t pud) } #endif -/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */ -static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) +static inline int pud_trans_unstable(pud_t *pud) { +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \ + defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) pud_t pudval = READ_ONCE(*pud); if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval)) @@ -1303,121 +1316,10 @@ static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) pud_clear_bad(pud); return 1; } - return 0; -} - -/* See pmd_trans_unstable for discussion. */ -static inline int pud_trans_unstable(pud_t *pud) -{ -#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \ - defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) - return pud_none_or_trans_huge_or_dev_or_clear_bad(pud); -#else - return 0; -#endif -} - -#ifndef arch_needs_pgtable_deposit -#define arch_needs_pgtable_deposit() (false) -#endif -/* - * This function is meant to be used by sites walking pagetables with - * the mmap_lock held in read mode to protect against MADV_DONTNEED and - * transhuge page faults. MADV_DONTNEED can convert a transhuge pmd - * into a null pmd and the transhuge page fault can convert a null pmd - * into an hugepmd or into a regular pmd (if the hugepage allocation - * fails). While holding the mmap_lock in read mode the pmd becomes - * stable and stops changing under us only if it's not null and not a - * transhuge pmd. When those races occurs and this function makes a - * difference vs the standard pmd_none_or_clear_bad, the result is - * undefined so behaving like if the pmd was none is safe (because it - * can return none anyway). The compiler level barrier() is critically - * important to compute the two checks atomically on the same pmdval. - * - * For 32bit kernels with a 64bit large pmd_t this automatically takes - * care of reading the pmd atomically to avoid SMP race conditions - * against pmd_populate() when the mmap_lock is hold for reading by the - * caller (a special atomic read not done by "gcc" as in the generic - * version above, is also needed when THP is disabled because the page - * fault can populate the pmd from under us). - */ -static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd) -{ - pmd_t pmdval = pmdp_get_lockless(pmd); - /* - * The barrier will stabilize the pmdval in a register or on - * the stack so that it will stop changing under the code. - * - * When CONFIG_TRANSPARENT_HUGEPAGE=y on x86 32bit PAE, - * pmdp_get_lockless is allowed to return a not atomic pmdval - * (for example pointing to an hugepage that has never been - * mapped in the pmd). The below checks will only care about - * the low part of the pmd with 32bit PAE x86 anyway, with the - * exception of pmd_none(). So the important thing is that if - * the low part of the pmd is found null, the high part will - * be also null or the pmd_none() check below would be - * confused. - */ -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - barrier(); #endif - /* - * !pmd_present() checks for pmd migration entries - * - * The complete check uses is_pmd_migration_entry() in linux/swapops.h - * But using that requires moving current function and pmd_trans_unstable() - * to linux/swapops.h to resolve dependency, which is too much code move. - * - * !pmd_present() is equivalent to is_pmd_migration_entry() currently, - * because !pmd_present() pages can only be under migration not swapped - * out. - * - * pmd_none() is preserved for future condition checks on pmd migration - * entries and not confusing with this function name, although it is - * redundant with !pmd_present(). - */ - if (pmd_none(pmdval) || pmd_trans_huge(pmdval) || - (IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION) && !pmd_present(pmdval))) - return 1; - if (unlikely(pmd_bad(pmdval))) { - pmd_clear_bad(pmd); - return 1; - } return 0; } -/* - * This is a noop if Transparent Hugepage Support is not built into - * the kernel. Otherwise it is equivalent to - * pmd_none_or_trans_huge_or_clear_bad(), and shall only be called in - * places that already verified the pmd is not none and they want to - * walk ptes while holding the mmap sem in read mode (write mode don't - * need this). If THP is not enabled, the pmd can't go away under the - * code even if MADV_DONTNEED runs, but if THP is enabled we need to - * run a pmd_trans_unstable before walking the ptes after - * split_huge_pmd returns (because it may have run when the pmd become - * null, but then a page fault can map in a THP and not a regular page). - */ -static inline int pmd_trans_unstable(pmd_t *pmd) -{ -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - return pmd_none_or_trans_huge_or_clear_bad(pmd); -#else - return 0; -#endif -} - -/* - * the ordering of these checks is important for pmds with _page_devmap set. - * if we check pmd_trans_unstable() first we will trip the bad_pmd() check - * inside of pmd_none_or_trans_huge_or_clear_bad(). this will end up correctly - * returning 1 but not before it spams dmesg with the pmd_clear_bad() output. - */ -static inline int pmd_devmap_trans_unstable(pmd_t *pmd) -{ - return pmd_devmap(*pmd) || pmd_trans_unstable(pmd); -} - #ifndef CONFIG_NUMA_BALANCING /* * Technically a PTE can be PROTNONE even when not doing NUMA balancing but diff --git a/include/linux/phy.h b/include/linux/phy.h index c5a0dc829714..11c1e91563d4 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -86,6 +86,7 @@ extern const int phy_10gbit_features_array[1]; #define PHY_IS_INTERNAL 0x00000001 #define PHY_RST_AFTER_CLK_EN 0x00000002 #define PHY_POLL_CABLE_TEST 0x00000004 +#define PHY_ALWAYS_CALL_SUSPEND 0x00000008 #define MDIO_DEVICE_IS_PHY 0x80000000 /** @@ -496,14 +497,17 @@ struct phy_device *mdiobus_scan_c22(struct mii_bus *bus, int addr); * Once complete, move to UP to restart the PHY. * - phy_stop aborts the running test and moves to @PHY_HALTED * - * @PHY_HALTED: PHY is up, but no polling or interrupts are done. Or - * PHY is in an error state. + * @PHY_HALTED: PHY is up, but no polling or interrupts are done. * - phy_start moves to @PHY_UP + * + * @PHY_ERROR: PHY is up, but is in an error state. + * - phy_stop moves to @PHY_HALTED */ enum phy_state { PHY_DOWN = 0, PHY_READY, PHY_HALTED, + PHY_ERROR, PHY_UP, PHY_RUNNING, PHY_NOLINK, @@ -548,6 +552,8 @@ struct macsec_ops; * @downshifted_rate: Set true if link speed has been downshifted. * @is_on_sfp_module: Set true if PHY is located on an SFP module. * @mac_managed_pm: Set true if MAC driver takes of suspending/resuming PHY + * @wol_enabled: Set to true if the PHY or the attached MAC have Wake-on-LAN + * enabled. * @state: State of the PHY for management purposes * @dev_flags: Device-specific flags used by the PHY driver. * @@ -644,6 +650,7 @@ struct phy_device { unsigned downshifted_rate:1; unsigned is_on_sfp_module:1; unsigned mac_managed_pm:1; + unsigned wol_enabled:1; unsigned autoneg:1; /* The most recently read link state */ @@ -1108,6 +1115,34 @@ struct phy_driver { #define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4) #define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 10) +/** + * phy_id_compare - compare @id1 with @id2 taking account of @mask + * @id1: first PHY ID + * @id2: second PHY ID + * @mask: the PHY ID mask, set bits are significant in matching + * + * Return true if the bits from @id1 and @id2 specified by @mask match. + * This uses an equivalent test to (@id & @mask) == (@phy_id & @mask). + */ +static inline bool phy_id_compare(u32 id1, u32 id2, u32 mask) +{ + return !((id1 ^ id2) & mask); +} + +/** + * phydev_id_compare - compare @id with the PHY's Clause 22 ID + * @phydev: the PHY device + * @id: the PHY ID to be matched + * + * Compare the @phydev clause 22 ID with the provided @id and return true or + * false depending whether it matches, using the bound driver mask. The + * @phydev must be bound to a driver. + */ +static inline bool phydev_id_compare(struct phy_device *phydev, u32 id) +{ + return phy_id_compare(id, phydev->phy_id, phydev->drv->phy_id_mask); +} + /* A Structure for boards to register fixups with the PHY Lib */ struct phy_fixup { struct list_head list; @@ -1171,10 +1206,12 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum) #define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \ timeout_us, sleep_before_read) \ ({ \ - int __ret = read_poll_timeout(phy_read, val, val < 0 || (cond), \ + int __ret, __val; \ + __ret = read_poll_timeout(__val = phy_read, val, \ + __val < 0 || (cond), \ sleep_us, timeout_us, sleep_before_read, phydev, regnum); \ - if (val < 0) \ - __ret = val; \ + if (__val < 0) \ + __ret = __val; \ if (__ret) \ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \ __ret; \ @@ -1267,11 +1304,13 @@ int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum); #define phy_read_mmd_poll_timeout(phydev, devaddr, regnum, val, cond, \ sleep_us, timeout_us, sleep_before_read) \ ({ \ - int __ret = read_poll_timeout(phy_read_mmd, val, (cond) || val < 0, \ + int __ret, __val; \ + __ret = read_poll_timeout(__val = phy_read_mmd, val, \ + __val < 0 || (cond), \ sleep_us, timeout_us, sleep_before_read, \ phydev, devaddr, regnum); \ - if (val < 0) \ - __ret = val; \ + if (__val < 0) \ + __ret = __val; \ if (__ret) \ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \ __ret; \ @@ -1900,10 +1939,8 @@ void phy_package_leave(struct phy_device *phydev); int devm_phy_package_join(struct device *dev, struct phy_device *phydev, int addr, size_t priv_size); -#if IS_ENABLED(CONFIG_PHYLIB) int __init mdio_bus_init(void); void mdio_bus_exit(void); -#endif int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data); int phy_ethtool_get_sset_count(struct phy_device *phydev); diff --git a/include/linux/phylink.h b/include/linux/phylink.h index 71755c66c162..1817940a3418 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -21,6 +21,24 @@ enum { MLO_AN_FIXED, /* Fixed-link mode */ MLO_AN_INBAND, /* In-band protocol */ + /* PCS "negotiation" mode. + * PHYLINK_PCS_NEG_NONE - protocol has no inband capability + * PHYLINK_PCS_NEG_OUTBAND - some out of band or fixed link setting + * PHYLINK_PCS_NEG_INBAND_DISABLED - inband mode disabled, e.g. + * 1000base-X with autoneg off + * PHYLINK_PCS_NEG_INBAND_ENABLED - inband mode enabled + * Additionally, this can be tested using bitmasks: + * PHYLINK_PCS_NEG_INBAND - inband mode selected + * PHYLINK_PCS_NEG_ENABLED - negotiation mode enabled + */ + PHYLINK_PCS_NEG_NONE = 0, + PHYLINK_PCS_NEG_ENABLED = BIT(4), + PHYLINK_PCS_NEG_OUTBAND = BIT(5), + PHYLINK_PCS_NEG_INBAND = BIT(6), + PHYLINK_PCS_NEG_INBAND_DISABLED = PHYLINK_PCS_NEG_INBAND, + PHYLINK_PCS_NEG_INBAND_ENABLED = PHYLINK_PCS_NEG_INBAND | + PHYLINK_PCS_NEG_ENABLED, + /* MAC_SYM_PAUSE and MAC_ASYM_PAUSE are used when configuring our * autonegotiation advertisement. They correspond to the PAUSE and * ASM_DIR bits defined by 802.3, respectively. @@ -80,6 +98,72 @@ static inline bool phylink_autoneg_inband(unsigned int mode) } /** + * phylink_pcs_neg_mode() - helper to determine PCS inband mode + * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. + * @interface: interface mode to be used + * @advertising: adertisement ethtool link mode mask + * + * Determines the negotiation mode to be used by the PCS, and returns + * one of: + * + * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband + * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY) + * will be used. + * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg + * disabled + * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled + * + * Note: this is for cases where the PCS itself is involved in negotiation + * (e.g. Clause 37, SGMII and similar) not Clause 73. + */ +static inline unsigned int phylink_pcs_neg_mode(unsigned int mode, + phy_interface_t interface, + const unsigned long *advertising) +{ + unsigned int neg_mode; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_QSGMII: + case PHY_INTERFACE_MODE_QUSGMII: + case PHY_INTERFACE_MODE_USXGMII: + /* These protocols are designed for use with a PHY which + * communicates its negotiation result back to the MAC via + * inband communication. Note: there exist PHYs that run + * with SGMII but do not send the inband data. + */ + if (!phylink_autoneg_inband(mode)) + neg_mode = PHYLINK_PCS_NEG_OUTBAND; + else + neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; + break; + + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: + /* 1000base-X is designed for use media-side for Fibre + * connections, and thus the Autoneg bit needs to be + * taken into account. We also do this for 2500base-X + * as well, but drivers may not support this, so may + * need to override this. + */ + if (!phylink_autoneg_inband(mode)) + neg_mode = PHYLINK_PCS_NEG_OUTBAND; + else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, + advertising)) + neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; + else + neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; + break; + + default: + neg_mode = PHYLINK_PCS_NEG_NONE; + break; + } + + return neg_mode; +} + +/** * struct phylink_link_state - link state structure * @advertising: ethtool bitmask containing advertised link modes * @lp_advertising: ethtool bitmask containing link partner advertised link @@ -436,6 +520,7 @@ struct phylink_pcs_ops; /** * struct phylink_pcs - PHYLINK PCS instance * @ops: a pointer to the &struct phylink_pcs_ops structure + * @neg_mode: provide PCS neg mode via "mode" argument * @poll: poll the PCS for link changes * * This structure is designed to be embedded within the PCS private data, @@ -443,6 +528,7 @@ struct phylink_pcs_ops; */ struct phylink_pcs { const struct phylink_pcs_ops *ops; + bool neg_mode; bool poll; }; @@ -460,12 +546,12 @@ struct phylink_pcs_ops { const struct phylink_link_state *state); void (*pcs_get_state)(struct phylink_pcs *pcs, struct phylink_link_state *state); - int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, + int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, const unsigned long *advertising, bool permit_pause_to_mac); void (*pcs_an_restart)(struct phylink_pcs *pcs); - void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int mode, + void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); }; @@ -508,7 +594,7 @@ void pcs_get_state(struct phylink_pcs *pcs, /** * pcs_config() - Configure the PCS mode and advertisement * @pcs: a pointer to a &struct phylink_pcs. - * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. + * @neg_mode: link negotiation mode (see below) * @interface: interface mode to be used * @advertising: adertisement ethtool link mode mask * @permit_pause_to_mac: permit forwarding pause resolution to MAC @@ -526,8 +612,12 @@ void pcs_get_state(struct phylink_pcs *pcs, * For 1000BASE-X, the advertisement should be programmed into the PCS. * * For most 10GBASE-R, there is no advertisement. + * + * The %neg_mode argument should be tested via the phylink_mode_*() family of + * functions, or for PCS that set pcs->neg_mode true, should be tested + * against the %PHYLINK_PCS_NEG_* definitions. */ -int pcs_config(struct phylink_pcs *pcs, unsigned int mode, +int pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, const unsigned long *advertising, bool permit_pause_to_mac); @@ -543,7 +633,7 @@ void pcs_an_restart(struct phylink_pcs *pcs); /** * pcs_link_up() - program the PCS for the resolved link configuration * @pcs: a pointer to a &struct phylink_pcs. - * @mode: link autonegotiation mode + * @neg_mode: link negotiation mode (see below) * @interface: link &typedef phy_interface_t mode * @speed: link speed * @duplex: link duplex @@ -552,8 +642,12 @@ void pcs_an_restart(struct phylink_pcs *pcs); * the resolved link parameters. For example, a PCS operating in SGMII * mode without in-band AN needs to be manually configured for the link * and duplex setting. Otherwise, this should be a no-op. + * + * The %mode argument should be tested via the phylink_mode_*() family of + * functions, or for PCS that set pcs->neg_mode true, should be tested + * against the %PHYLINK_PCS_NEG_* definitions. */ -void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, +void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, int speed, int duplex); #endif @@ -568,16 +662,17 @@ void phylink_generic_validate(struct phylink_config *config, unsigned long *supported, struct phylink_link_state *state); -struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, - phy_interface_t iface, - const struct phylink_mac_ops *mac_ops); +struct phylink *phylink_create(struct phylink_config *, + const struct fwnode_handle *, + phy_interface_t, + const struct phylink_mac_ops *); void phylink_destroy(struct phylink *); bool phylink_expects_phy(struct phylink *pl); int phylink_connect_phy(struct phylink *, struct phy_device *); int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags); int phylink_fwnode_phy_connect(struct phylink *pl, - struct fwnode_handle *fwnode, + const struct fwnode_handle *fwnode, u32 flags); void phylink_disconnect_phy(struct phylink *); @@ -650,11 +745,14 @@ void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, struct phylink_link_state *state); int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, const unsigned long *advertising); -int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode, +int phylink_mii_c22_pcs_config(struct mdio_device *pcs, phy_interface_t interface, - const unsigned long *advertising); + const unsigned long *advertising, + unsigned int neg_mode); void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs); +void phylink_resolve_c73(struct phylink_link_state *state); + void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, struct phylink_link_state *state); diff --git a/include/linux/pid.h b/include/linux/pid.h index b75de288a8c2..653a527574c4 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -67,7 +67,7 @@ struct pid /* wait queue for pidfd notifications */ wait_queue_head_t wait_pidfd; struct rcu_head rcu; - struct upid numbers[1]; + struct upid numbers[]; }; extern struct pid init_struct_pid; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index d2c3f16cf6b1..02e0086b10f6 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -261,18 +261,14 @@ void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); extern const struct pipe_buf_operations nosteal_pipe_buf_ops; -#ifdef CONFIG_WATCH_QUEUE unsigned long account_pipe_buffers(struct user_struct *user, unsigned long old, unsigned long new); bool too_many_pipe_buffers_soft(unsigned long user_bufs); bool too_many_pipe_buffers_hard(unsigned long user_bufs); bool pipe_is_unprivileged_user(void); -#endif /* for F_SETPIPE_SZ and F_GETPIPE_SZ */ -#ifdef CONFIG_WATCH_QUEUE int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots); -#endif long pipe_fcntl(struct file *, unsigned int, unsigned long arg); struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice); diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h index f9c5ac80d59b..80cb00db42a4 100644 --- a/include/linux/pktcdvd.h +++ b/include/linux/pktcdvd.h @@ -156,7 +156,6 @@ struct pktcdvd_device { struct block_device *bdev; /* dev attached */ dev_t pkt_dev; /* our dev */ - char name[20]; struct packet_settings settings; struct packet_stats stats; int refcnt; /* Open count */ diff --git a/include/linux/platform_data/asoc-pxa.h b/include/linux/platform_data/asoc-pxa.h index 327454cd8246..7b5b9e20fbf5 100644 --- a/include/linux/platform_data/asoc-pxa.h +++ b/include/linux/platform_data/asoc-pxa.h @@ -27,5 +27,6 @@ typedef struct { } pxa2xx_audio_ops_t; extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); +extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio); #endif diff --git a/include/linux/platform_data/davinci-cpufreq.h b/include/linux/platform_data/davinci-cpufreq.h index bc208c64e3d7..1ef91c36f609 100644 --- a/include/linux/platform_data/davinci-cpufreq.h +++ b/include/linux/platform_data/davinci-cpufreq.h @@ -16,4 +16,10 @@ struct davinci_cpufreq_config { int (*init)(void); }; +#ifdef CONFIG_CPU_FREQ +int davinci_cpufreq_init(void); +#else +static inline int davinci_cpufreq_init(void) { return 0; } +#endif + #endif /* _MACH_DAVINCI_CPUFREQ_H */ diff --git a/include/linux/platform_data/lcd-mipid.h b/include/linux/platform_data/lcd-mipid.h index 63f05eb23827..4927cfc5158c 100644 --- a/include/linux/platform_data/lcd-mipid.h +++ b/include/linux/platform_data/lcd-mipid.h @@ -15,10 +15,8 @@ enum mipid_test_result { #ifdef __KERNEL__ struct mipid_platform_data { - int nreset_gpio; int data_lines; - void (*shutdown)(struct mipid_platform_data *pdata); void (*set_bklight_level)(struct mipid_platform_data *pdata, int level); int (*get_bklight_level)(struct mipid_platform_data *pdata); diff --git a/include/linux/platform_data/leds-lp55xx.h b/include/linux/platform_data/leds-lp55xx.h index 3441064713a3..3cc8db0b12b5 100644 --- a/include/linux/platform_data/leds-lp55xx.h +++ b/include/linux/platform_data/leds-lp55xx.h @@ -73,6 +73,9 @@ struct lp55xx_platform_data { /* Clock configuration */ u8 clock_mode; + /* Charge pump mode */ + u32 charge_pump_mode; + /* optional enable GPIO */ struct gpio_desc *enable_gpiod; diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h index 91051e9907f3..054d0c3c5ec5 100644 --- a/include/linux/platform_data/mmc-omap.h +++ b/include/linux/platform_data/mmc-omap.h @@ -20,8 +20,6 @@ struct omap_mmc_platform_data { * maximum frequency on the MMC bus */ unsigned int max_freq; - /* switch the bus to a new slot */ - int (*switch_slot)(struct device *dev, int slot); /* initialize board-specific MMC functionality, can be NULL if * not supported */ int (*init)(struct device *dev); diff --git a/include/linux/platform_data/pxa2xx_udc.h b/include/linux/platform_data/pxa2xx_udc.h index ff9c35dca59d..bc99cc6a3c5f 100644 --- a/include/linux/platform_data/pxa2xx_udc.h +++ b/include/linux/platform_data/pxa2xx_udc.h @@ -25,4 +25,10 @@ struct pxa2xx_udc_mach_info { int gpio_pullup; /* high == pullup activated */ }; +#ifdef CONFIG_PXA27x +extern void pxa27x_clear_otgph(void); +#else +#define pxa27x_clear_otgph() do {} while (0) +#endif + #endif diff --git a/include/linux/platform_data/sht3x.h b/include/linux/platform_data/sht3x.h deleted file mode 100644 index 14680d2a98f7..000000000000 --- a/include/linux/platform_data/sht3x.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2016 Sensirion AG, Switzerland - * Author: David Frey <david.frey@sensirion.com> - * Author: Pascal Sachs <pascal.sachs@sensirion.com> - */ - -#ifndef __SHT3X_H_ -#define __SHT3X_H_ - -struct sht3x_platform_data { - bool blocking_io; - bool high_precision; -}; -#endif /* __SHT3X_H_ */ diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index 3101152ce449..1d6e6c424fc6 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -36,6 +36,7 @@ struct s3c64xx_spi_info { int src_clk_nr; int num_cs; bool no_cs; + bool polling; int (*cfg_gpio)(void); }; diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h index 897051e51b78..a657830232ae 100644 --- a/include/linux/platform_data/st_sensors_pdata.h +++ b/include/linux/platform_data/st_sensors_pdata.h @@ -15,7 +15,7 @@ * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). * Available only for accelerometer, magnetometer and pressure sensors. * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). - * Magnetometer DRDY is supported only on LSM9DS0. + * Magnetometer DRDY is supported only on LSM9DS0 and LSM303D. * @open_drain: set the interrupt line to be open drain if possible. * @spi_3wire: enable spi-3wire mode. * @pullups: enable/disable i2c controller pullup resistors. diff --git a/include/linux/pm.h b/include/linux/pm.h index 035d9649eba4..badad7d11f4f 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -375,23 +375,23 @@ const struct dev_pm_ops name = { \ } #ifdef CONFIG_PM -#define _EXPORT_DEV_PM_OPS(name, sec, ns) \ +#define _EXPORT_DEV_PM_OPS(name, license, ns) \ const struct dev_pm_ops name; \ - __EXPORT_SYMBOL(name, sec, ns); \ + __EXPORT_SYMBOL(name, license, ns); \ const struct dev_pm_ops name #define EXPORT_PM_FN_GPL(name) EXPORT_SYMBOL_GPL(name) #define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, ns) #else -#define _EXPORT_DEV_PM_OPS(name, sec, ns) \ +#define _EXPORT_DEV_PM_OPS(name, license, ns) \ static __maybe_unused const struct dev_pm_ops __static_##name #define EXPORT_PM_FN_GPL(name) #define EXPORT_PM_FN_NS_GPL(name, ns) #endif #define EXPORT_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "", "") -#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "_gpl", "") +#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "GPL", "") #define EXPORT_NS_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "", #ns) -#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "_gpl", #ns) +#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "GPL", #ns) /* * Use this if you want to use the same suspend and resume callbacks for suspend diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index a1aa68141d0b..7c8d65414a70 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -2,6 +2,8 @@ #ifndef __LINUX_BQ27X00_BATTERY_H__ #define __LINUX_BQ27X00_BATTERY_H__ +#include <linux/power_supply.h> + enum bq27xxx_chip { BQ27000 = 1, /* bq27000, bq27200 */ BQ27010, /* bq27010, bq27210 */ @@ -68,7 +70,9 @@ struct bq27xxx_device_info { struct bq27xxx_access_methods bus; struct bq27xxx_reg_cache cache; int charge_design_full; + bool removed; unsigned long last_update; + union power_supply_propval last_status; struct delayed_work work; struct power_supply *bat; struct list_head list; diff --git a/include/linux/pr.h b/include/linux/pr.h index 94ceec713afe..3003daec28a5 100644 --- a/include/linux/pr.h +++ b/include/linux/pr.h @@ -4,6 +4,18 @@ #include <uapi/linux/pr.h> +struct pr_keys { + u32 generation; + u32 num_keys; + u64 keys[]; +}; + +struct pr_held_reservation { + u64 key; + u32 generation; + enum pr_type type; +}; + struct pr_ops { int (*pr_register)(struct block_device *bdev, u64 old_key, u64 new_key, u32 flags); @@ -14,6 +26,19 @@ struct pr_ops { int (*pr_preempt)(struct block_device *bdev, u64 old_key, u64 new_key, enum pr_type type, bool abort); int (*pr_clear)(struct block_device *bdev, u64 key); + /* + * pr_read_keys - Read the registered keys and return them in the + * pr_keys->keys array. The keys array will have been allocated at the + * end of the pr_keys struct, and pr_keys->num_keys must be set to the + * number of keys the array can hold. If there are more than can fit + * in the array, success will still be returned and pr_keys->num_keys + * will reflect the total number of keys the device contains, so the + * caller can retry with a larger array. + */ + int (*pr_read_keys)(struct block_device *bdev, + struct pr_keys *keys_info); + int (*pr_read_reservation)(struct block_device *bdev, + struct pr_held_reservation *rsv); }; #endif /* LINUX_PR_H */ diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 0df425bf9bd7..1424670df161 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -8,6 +8,7 @@ */ #include <linux/linkage.h> +#include <linux/cleanup.h> #include <linux/list.h> /* @@ -463,4 +464,8 @@ static __always_inline void preempt_enable_nested(void) preempt_enable(); } +DEFINE_LOCK_GUARD_0(preempt, preempt_disable(), preempt_enable()) +DEFINE_LOCK_GUARD_0(preempt_notrace, preempt_disable_notrace(), preempt_enable_notrace()) +DEFINE_LOCK_GUARD_0(migrate, migrate_disable(), migrate_enable()) + #endif /* __LINUX_PREEMPT_H */ diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 0260f5ea98fe..253f2676d93a 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -158,6 +158,8 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task); #endif /* CONFIG_PROC_PID_ARCH_STATUS */ +void arch_report_meminfo(struct seq_file *m); + #else /* CONFIG_PROC_FS */ static inline void proc_root_init(void) diff --git a/include/linux/property.h b/include/linux/property.h index 66df1a15d518..8c3c6685a2ae 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -85,6 +85,18 @@ bool fwnode_device_is_compatible(const struct fwnode_handle *fwnode, const char return fwnode_property_match_string(fwnode, "compatible", compat) >= 0; } +/** + * device_is_compatible - match 'compatible' property of the device with a given string + * @dev: Pointer to the struct device + * @compat: The string to match 'compatible' property with + * + * Returns: true if matches, otherwise false. + */ +static inline bool device_is_compatible(const struct device *dev, const char *compat) +{ + return fwnode_device_is_compatible(dev_fwnode(dev), compat); +} + int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, const char *prop, const char *nargs_prop, unsigned int nargs, unsigned int index, diff --git a/include/linux/pruss_driver.h b/include/linux/pruss_driver.h index ecfded30ed05..c9a31c567e85 100644 --- a/include/linux/pruss_driver.h +++ b/include/linux/pruss_driver.h @@ -9,7 +9,55 @@ #ifndef _PRUSS_DRIVER_H_ #define _PRUSS_DRIVER_H_ +#include <linux/mutex.h> +#include <linux/remoteproc/pruss.h> #include <linux/types.h> +#include <linux/err.h> + +/* + * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the + * PRUSS_GPCFG0/1 registers + * + * NOTE: The below defines are the most common values, but there + * are some exceptions like on 66AK2G, where the RESERVED and MII2 + * values are interchanged. Also, this bit-field does not exist on + * AM335x SoCs + */ +enum pruss_gp_mux_sel { + PRUSS_GP_MUX_SEL_GP, + PRUSS_GP_MUX_SEL_ENDAT, + PRUSS_GP_MUX_SEL_RESERVED, + PRUSS_GP_MUX_SEL_SD, + PRUSS_GP_MUX_SEL_MII2, + PRUSS_GP_MUX_SEL_MAX, +}; + +/* + * enum pruss_gpi_mode - PRUSS GPI configuration modes, used + * to program the PRUSS_GPCFG0/1 registers + */ +enum pruss_gpi_mode { + PRUSS_GPI_MODE_DIRECT, + PRUSS_GPI_MODE_PARALLEL, + PRUSS_GPI_MODE_28BIT_SHIFT, + PRUSS_GPI_MODE_MII, + PRUSS_GPI_MODE_MAX, +}; + +/** + * enum pru_type - PRU core type identifier + * + * @PRU_TYPE_PRU: Programmable Real-time Unit + * @PRU_TYPE_RTU: Auxiliary Programmable Real-Time Unit + * @PRU_TYPE_TX_PRU: Transmit Programmable Real-Time Unit + * @PRU_TYPE_MAX: just keep this one at the end + */ +enum pru_type { + PRU_TYPE_PRU, + PRU_TYPE_RTU, + PRU_TYPE_TX_PRU, + PRU_TYPE_MAX, +}; /* * enum pruss_mem - PRUSS memory range identifiers @@ -39,6 +87,8 @@ struct pruss_mem_region { * @cfg_base: base iomap for CFG region * @cfg_regmap: regmap for config region * @mem_regions: data for each of the PRUSS memory regions + * @mem_in_use: to indicate if memory resource is in use + * @lock: mutex to serialize access to resources * @core_clk_mux: clk handle for PRUSS CORE_CLK_MUX * @iep_clk_mux: clk handle for PRUSS IEP_CLK_MUX */ @@ -47,8 +97,81 @@ struct pruss { void __iomem *cfg_base; struct regmap *cfg_regmap; struct pruss_mem_region mem_regions[PRUSS_MEM_MAX]; + struct pruss_mem_region *mem_in_use[PRUSS_MEM_MAX]; + struct mutex lock; /* PRU resource lock */ struct clk *core_clk_mux; struct clk *iep_clk_mux; }; +#if IS_ENABLED(CONFIG_TI_PRUSS) + +struct pruss *pruss_get(struct rproc *rproc); +void pruss_put(struct pruss *pruss); +int pruss_request_mem_region(struct pruss *pruss, enum pruss_mem mem_id, + struct pruss_mem_region *region); +int pruss_release_mem_region(struct pruss *pruss, + struct pruss_mem_region *region); +int pruss_cfg_get_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 *mux); +int pruss_cfg_set_gpmux(struct pruss *pruss, enum pruss_pru_id pru_id, u8 mux); +int pruss_cfg_gpimode(struct pruss *pruss, enum pruss_pru_id pru_id, + enum pruss_gpi_mode mode); +int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable); +int pruss_cfg_xfr_enable(struct pruss *pruss, enum pru_type pru_type, + bool enable); + +#else + +static inline struct pruss *pruss_get(struct rproc *rproc) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void pruss_put(struct pruss *pruss) { } + +static inline int pruss_request_mem_region(struct pruss *pruss, + enum pruss_mem mem_id, + struct pruss_mem_region *region) +{ + return -EOPNOTSUPP; +} + +static inline int pruss_release_mem_region(struct pruss *pruss, + struct pruss_mem_region *region) +{ + return -EOPNOTSUPP; +} + +static inline int pruss_cfg_get_gpmux(struct pruss *pruss, + enum pruss_pru_id pru_id, u8 *mux) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int pruss_cfg_set_gpmux(struct pruss *pruss, + enum pruss_pru_id pru_id, u8 mux) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int pruss_cfg_gpimode(struct pruss *pruss, + enum pruss_pru_id pru_id, + enum pruss_gpi_mode mode) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int pruss_cfg_miirt_enable(struct pruss *pruss, bool enable) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int pruss_cfg_xfr_enable(struct pruss *pruss, + enum pru_type pru_type, + bool enable); +{ + return ERR_PTR(-EOPNOTSUPP); +} + +#endif /* CONFIG_TI_PRUSS */ + #endif /* _PRUSS_DRIVER_H_ */ diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index fdffa6a98d79..1ef4e0f9bd2a 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -77,8 +77,14 @@ struct ptp_system_timestamp { * nominal frequency in parts per million, but with a * 16 bit binary fractional field. * - * @adjphase: Adjusts the phase offset of the hardware clock. - * parameter delta: Desired change in nanoseconds. + * @adjphase: Indicates that the PHC should use an internal servo + * algorithm to correct the provided phase offset. + * parameter delta: PHC servo phase adjustment target + * in nanoseconds. + * + * @getmaxphase: Advertises maximum offset that can be provided + * to the hardware clock's phase control functionality + * through adjphase. * * @adjtime: Shifts the time of the hardware clock. * parameter delta: Desired change in nanoseconds. @@ -169,6 +175,7 @@ struct ptp_clock_info { struct ptp_pin_desc *pin_config; int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm); int (*adjphase)(struct ptp_clock_info *ptp, s32 phase); + s32 (*getmaxphase)(struct ptp_clock_info *ptp); int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts); int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts, diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index 917528d102c4..d506dc63dd47 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -7,6 +7,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, umode_t mode, dev_t dev); extern int ramfs_init_fs_context(struct fs_context *fc); +extern void ramfs_kill_sb(struct super_block *sb); #ifdef CONFIG_MMU static inline int diff --git a/include/linux/rbtree_latch.h b/include/linux/rbtree_latch.h index 3d1a9e716b80..6a0999c26c7c 100644 --- a/include/linux/rbtree_latch.h +++ b/include/linux/rbtree_latch.h @@ -206,7 +206,7 @@ latch_tree_find(void *key, struct latch_tree_root *root, do { seq = raw_read_seqcount_latch(&root->seq); node = __lt_find(key, root, seq & 1, ops->comp); - } while (read_seqcount_latch_retry(&root->seq, seq)); + } while (raw_read_seqcount_latch_retry(&root->seq, seq)); return node; } diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index dcd2cf1e8326..5e5f920ade90 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -27,6 +27,7 @@ #include <linux/preempt.h> #include <linux/bottom_half.h> #include <linux/lockdep.h> +#include <linux/cleanup.h> #include <asm/processor.h> #include <linux/cpumask.h> #include <linux/context_tracking_irq.h> @@ -156,31 +157,6 @@ static inline int rcu_nocb_cpu_deoffload(int cpu) { return 0; } static inline void rcu_nocb_flush_deferred_wakeup(void) { } #endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ -/** - * RCU_NONIDLE - Indicate idle-loop code that needs RCU readers - * @a: Code that RCU needs to pay attention to. - * - * RCU read-side critical sections are forbidden in the inner idle loop, - * that is, between the ct_idle_enter() and the ct_idle_exit() -- RCU - * will happily ignore any such read-side critical sections. However, - * things like powertop need tracepoints in the inner idle loop. - * - * This macro provides the way out: RCU_NONIDLE(do_something_with_RCU()) - * will tell RCU that it needs to pay attention, invoke its argument - * (in this example, calling the do_something_with_RCU() function), - * and then tell RCU to go back to ignoring this CPU. It is permissible - * to nest RCU_NONIDLE() wrappers, but not indefinitely (but the limit is - * on the order of a million or so, even on 32-bit systems). It is - * not legal to block within RCU_NONIDLE(), nor is it permissible to - * transfer control either into or out of RCU_NONIDLE()'s statement. - */ -#define RCU_NONIDLE(a) \ - do { \ - ct_irq_enter_irqson(); \ - do { a; } while (0); \ - ct_irq_exit_irqson(); \ - } while (0) - /* * Note a quasi-voluntary context switch for RCU-tasks's benefit. * This is a macro rather than an inline function to avoid #include hell. @@ -957,9 +933,8 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) /** * kfree_rcu() - kfree an object after a grace period. - * @ptr: pointer to kfree for both single- and double-argument invocations. - * @rhf: the name of the struct rcu_head within the type of @ptr, - * but only for double-argument invocations. + * @ptr: pointer to kfree for double-argument invocations. + * @rhf: the name of the struct rcu_head within the type of @ptr. * * Many rcu callbacks functions just call kfree() on the base structure. * These functions are trivial, but their size adds up, and furthermore @@ -984,26 +959,18 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) * The BUILD_BUG_ON check must not involve any function calls, hence the * checks are done in macros here. */ -#define kfree_rcu(ptr, rhf...) kvfree_rcu(ptr, ## rhf) +#define kfree_rcu(ptr, rhf) kvfree_rcu_arg_2(ptr, rhf) +#define kvfree_rcu(ptr, rhf) kvfree_rcu_arg_2(ptr, rhf) /** - * kvfree_rcu() - kvfree an object after a grace period. - * - * This macro consists of one or two arguments and it is - * based on whether an object is head-less or not. If it - * has a head then a semantic stays the same as it used - * to be before: - * - * kvfree_rcu(ptr, rhf); - * - * where @ptr is a pointer to kvfree(), @rhf is the name - * of the rcu_head structure within the type of @ptr. + * kfree_rcu_mightsleep() - kfree an object after a grace period. + * @ptr: pointer to kfree for single-argument invocations. * * When it comes to head-less variant, only one argument * is passed and that is just a pointer which has to be * freed after a grace period. Therefore the semantic is * - * kvfree_rcu(ptr); + * kfree_rcu_mightsleep(ptr); * * where @ptr is the pointer to be freed by kvfree(). * @@ -1012,13 +979,9 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) * annotation. Otherwise, please switch and embed the * rcu_head structure within the type of @ptr. */ -#define kvfree_rcu(...) KVFREE_GET_MACRO(__VA_ARGS__, \ - kvfree_rcu_arg_2, kvfree_rcu_arg_1)(__VA_ARGS__) - +#define kfree_rcu_mightsleep(ptr) kvfree_rcu_arg_1(ptr) #define kvfree_rcu_mightsleep(ptr) kvfree_rcu_arg_1(ptr) -#define kfree_rcu_mightsleep(ptr) kvfree_rcu_mightsleep(ptr) -#define KVFREE_GET_MACRO(_1, _2, NAME, ...) NAME #define kvfree_rcu_arg_2(ptr, rhf) \ do { \ typeof (ptr) ___p = (ptr); \ @@ -1095,4 +1058,6 @@ rcu_head_after_call_rcu(struct rcu_head *rhp, rcu_callback_t f) extern int rcu_expedited; extern int rcu_normal; +DEFINE_LOCK_GUARD_0(rcu, rcu_read_lock(), rcu_read_unlock()) + #endif /* __LINUX_RCUPDATE_H */ diff --git a/include/linux/rcuwait.h b/include/linux/rcuwait.h index 8052d34da782..27343424225c 100644 --- a/include/linux/rcuwait.h +++ b/include/linux/rcuwait.h @@ -49,9 +49,9 @@ static inline void prepare_to_rcuwait(struct rcuwait *w) extern void finish_rcuwait(struct rcuwait *w); -#define rcuwait_wait_event(w, condition, state) \ +#define ___rcuwait_wait_event(w, condition, state, ret, cmd) \ ({ \ - int __ret = 0; \ + long __ret = ret; \ prepare_to_rcuwait(w); \ for (;;) { \ /* \ @@ -67,10 +67,27 @@ extern void finish_rcuwait(struct rcuwait *w); break; \ } \ \ - schedule(); \ + cmd; \ } \ finish_rcuwait(w); \ __ret; \ }) +#define rcuwait_wait_event(w, condition, state) \ + ___rcuwait_wait_event(w, condition, state, 0, schedule()) + +#define __rcuwait_wait_event_timeout(w, condition, state, timeout) \ + ___rcuwait_wait_event(w, ___wait_cond_timeout(condition), \ + state, timeout, \ + __ret = schedule_timeout(__ret)) + +#define rcuwait_wait_event_timeout(w, condition, state, timeout) \ +({ \ + long __ret = timeout; \ + if (!___wait_cond_timeout(condition)) \ + __ret = __rcuwait_wait_event_timeout(w, condition, \ + state, timeout); \ + __ret; \ +}) + #endif /* _LINUX_RCUWAIT_H_ */ diff --git a/include/linux/ref_tracker.h b/include/linux/ref_tracker.h index 9ca353ab712b..8eac4f3d5254 100644 --- a/include/linux/ref_tracker.h +++ b/include/linux/ref_tracker.h @@ -17,12 +17,15 @@ struct ref_tracker_dir { bool dead; struct list_head list; /* List of active trackers */ struct list_head quarantine; /* List of dead trackers */ + char name[32]; #endif }; #ifdef CONFIG_REF_TRACKER + static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir, - unsigned int quarantine_count) + unsigned int quarantine_count, + const char *name) { INIT_LIST_HEAD(&dir->list); INIT_LIST_HEAD(&dir->quarantine); @@ -31,14 +34,20 @@ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir, dir->dead = false; refcount_set(&dir->untracked, 1); refcount_set(&dir->no_tracker, 1); + strscpy(dir->name, name, sizeof(dir->name)); stack_depot_init(); } void ref_tracker_dir_exit(struct ref_tracker_dir *dir); +void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir, + unsigned int display_limit); + void ref_tracker_dir_print(struct ref_tracker_dir *dir, unsigned int display_limit); +int ref_tracker_dir_snprint(struct ref_tracker_dir *dir, char *buf, size_t size); + int ref_tracker_alloc(struct ref_tracker_dir *dir, struct ref_tracker **trackerp, gfp_t gfp); @@ -48,7 +57,8 @@ int ref_tracker_free(struct ref_tracker_dir *dir, #else /* CONFIG_REF_TRACKER */ static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir, - unsigned int quarantine_count) + unsigned int quarantine_count, + const char *name) { } @@ -56,11 +66,22 @@ static inline void ref_tracker_dir_exit(struct ref_tracker_dir *dir) { } +static inline void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir, + unsigned int display_limit) +{ +} + static inline void ref_tracker_dir_print(struct ref_tracker_dir *dir, unsigned int display_limit) { } +static inline int ref_tracker_dir_snprint(struct ref_tracker_dir *dir, + char *buf, size_t size) +{ + return 0; +} + static inline int ref_tracker_alloc(struct ref_tracker_dir *dir, struct ref_tracker **trackerp, gfp_t gfp) diff --git a/include/linux/regmap.h b/include/linux/regmap.h index c2b9cc5db824..8fc0b3ebce44 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1528,9 +1528,6 @@ struct regmap_irq_chip_data; * status_base. Should contain num_regs arrays. * Can be provided for chips with more complex mapping than * 1.st bit to 1.st sub-reg, 2.nd bit to 2.nd sub-reg, ... - * When used with not_fixed_stride, each one-element array - * member contains offset calculated as address from each - * peripheral to first peripheral. * @num_main_regs: Number of 'main status' irq registers for chips which have * main_status set. * @@ -1542,10 +1539,6 @@ struct regmap_irq_chip_data; * @ack_base: Base ack address. If zero then the chip is clear on read. * Using zero value is possible with @use_ack bit. * @wake_base: Base address for wake enables. If zero unsupported. - * @type_base: Base address for irq type. If zero unsupported. Deprecated, - * use @config_base instead. - * @virt_reg_base: Base addresses for extra config regs. Deprecated, use - * @config_base instead. * @config_base: Base address for IRQ type config regs. If null unsupported. * @irq_reg_stride: Stride to use for chips where registers are not contiguous. * @init_ack_masked: Ack all masked interrupts once during initalization. @@ -1571,11 +1564,6 @@ struct regmap_irq_chip_data; * registers before unmasking interrupts to clear any bits * set when they were masked. * @runtime_pm: Hold a runtime PM lock on the device when accessing it. - * @not_fixed_stride: Used when chip peripherals are not laid out with fixed - * stride. Must be used with sub_reg_offsets containing the - * offsets to each peripheral. Deprecated; the same thing - * can be accomplished with a @get_irq_reg callback, without - * the need for a @sub_reg_offsets table. * @no_status: No status register: all interrupts assumed generated by device. * * @num_regs: Number of registers in each control bank. @@ -1583,12 +1571,6 @@ struct regmap_irq_chip_data; * @irqs: Descriptors for individual IRQs. Interrupt numbers are * assigned based on the index in the array of the interrupt. * @num_irqs: Number of descriptors. - * - * @num_type_reg: Number of type registers. Deprecated, use config registers - * instead. - * @num_virt_regs: Number of non-standard irq configuration registers. - * If zero unsupported. Deprecated, use config registers - * instead. * @num_config_bases: Number of config base registers. * @num_config_regs: Number of config registers for each config base register. * @@ -1598,15 +1580,12 @@ struct regmap_irq_chip_data; * after handling the interrupts in regmap_irq_handler(). * @handle_mask_sync: Callback used to handle IRQ mask syncs. The index will be * in the range [0, num_regs) - * @set_type_virt: Driver specific callback to extend regmap_irq_set_type() - * and configure virt regs. Deprecated, use @set_type_config - * callback and config registers instead. * @set_type_config: Callback used for configuring irq types. * @get_irq_reg: Callback for mapping (base register, index) pairs to register * addresses. The base register will be one of @status_base, * @mask_base, etc., @main_status, or any of @config_base. * The index will be in the range [0, num_main_regs[ for the - * main status base, [0, num_type_settings[ for any config + * main status base, [0, num_config_regs[ for any config * register base, and [0, num_regs[ for any other base. * If unspecified then regmap_irq_get_irq_reg_linear() is used. * @irq_drv_data: Driver specific IRQ data which is passed as parameter when @@ -1629,8 +1608,6 @@ struct regmap_irq_chip { unsigned int unmask_base; unsigned int ack_base; unsigned int wake_base; - unsigned int type_base; - unsigned int *virt_reg_base; const unsigned int *config_base; unsigned int irq_reg_stride; unsigned int init_ack_masked:1; @@ -1643,7 +1620,6 @@ struct regmap_irq_chip { unsigned int type_in_mask:1; unsigned int clear_on_unmask:1; unsigned int runtime_pm:1; - unsigned int not_fixed_stride:1; unsigned int no_status:1; int num_regs; @@ -1651,18 +1627,13 @@ struct regmap_irq_chip { const struct regmap_irq *irqs; int num_irqs; - int num_type_reg; - int num_virt_regs; int num_config_bases; int num_config_regs; int (*handle_pre_irq)(void *irq_drv_data); int (*handle_post_irq)(void *irq_drv_data); - int (*handle_mask_sync)(struct regmap *map, int index, - unsigned int mask_buf_def, + int (*handle_mask_sync)(int index, unsigned int mask_buf_def, unsigned int mask_buf, void *irq_drv_data); - int (*set_type_virt)(unsigned int **buf, unsigned int type, - unsigned long hwirq, int reg); int (*set_type_config)(unsigned int **buf, unsigned int type, const struct regmap_irq *irq_data, int idx, void *irq_drv_data); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index d3b4a3d4514a..c6ef7d68eb9a 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -758,6 +758,8 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, int min_uA, int max_uA); int regulator_get_current_limit_regmap(struct regulator_dev *rdev); void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); +int regulator_find_closest_bigger(unsigned int target, const unsigned int *table, + unsigned int num_sel, unsigned int *sel); int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay); int regulator_sync_voltage_rdev(struct regulator_dev *rdev); diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h index bdcf83cd719e..c71a6a9fce7a 100644 --- a/include/linux/regulator/mt6358-regulator.h +++ b/include/linux/regulator/mt6358-regulator.h @@ -41,15 +41,12 @@ enum { MT6358_ID_VIO28, MT6358_ID_VA12, MT6358_ID_VRF18, - MT6358_ID_VCN33_BT, - MT6358_ID_VCN33_WIFI, + MT6358_ID_VCN33, MT6358_ID_VCAMA2, MT6358_ID_VMC, MT6358_ID_VLDO28, MT6358_ID_VAUD28, MT6358_ID_VSIM2, - MT6358_ID_VCORE_SSHUB, - MT6358_ID_VSRAM_OTHERS_SSHUB, MT6358_ID_RG_MAX, }; @@ -85,13 +82,10 @@ enum { MT6366_ID_VIO28, MT6366_ID_VA12, MT6366_ID_VRF18, - MT6366_ID_VCN33_BT, - MT6366_ID_VCN33_WIFI, + MT6366_ID_VCN33, MT6366_ID_VMC, MT6366_ID_VAUD28, MT6366_ID_VSIM2, - MT6366_ID_VCORE_SSHUB, - MT6366_ID_VSRAM_OTHERS_SSHUB, MT6366_ID_RG_MAX, }; diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h index 3c01c2bf84f5..505c908dbb81 100644 --- a/include/linux/regulator/pca9450.h +++ b/include/linux/regulator/pca9450.h @@ -196,11 +196,11 @@ enum { /* PCA9450_REG_LDO3_VOLT bits */ #define LDO3_EN_MASK 0xC0 -#define LDO3OUT_MASK 0x0F +#define LDO3OUT_MASK 0x1F /* PCA9450_REG_LDO4_VOLT bits */ #define LDO4_EN_MASK 0xC0 -#define LDO4OUT_MASK 0x0F +#define LDO4OUT_MASK 0x1F /* PCA9450_REG_LDO5_VOLT bits */ #define LDO5L_EN_MASK 0xC0 diff --git a/include/linux/rethook.h b/include/linux/rethook.h index c8ac1e5afcd1..fdf26cd0e742 100644 --- a/include/linux/rethook.h +++ b/include/linux/rethook.h @@ -14,7 +14,7 @@ struct rethook_node; -typedef void (*rethook_handler_t) (struct rethook_node *, void *, struct pt_regs *); +typedef void (*rethook_handler_t) (struct rethook_node *, void *, unsigned long, struct pt_regs *); /** * struct rethook - The rethook management data structure. diff --git a/include/linux/root_dev.h b/include/linux/root_dev.h index 4e78651371ba..847c9a06101b 100644 --- a/include/linux/root_dev.h +++ b/include/linux/root_dev.h @@ -9,15 +9,8 @@ enum { Root_NFS = MKDEV(UNNAMED_MAJOR, 255), Root_CIFS = MKDEV(UNNAMED_MAJOR, 254), + Root_Generic = MKDEV(UNNAMED_MAJOR, 253), Root_RAM0 = MKDEV(RAMDISK_MAJOR, 0), - Root_RAM1 = MKDEV(RAMDISK_MAJOR, 1), - Root_FD0 = MKDEV(FLOPPY_MAJOR, 0), - Root_HDA1 = MKDEV(IDE0_MAJOR, 1), - Root_HDA2 = MKDEV(IDE0_MAJOR, 2), - Root_SDA1 = MKDEV(SCSI_DISK0_MAJOR, 1), - Root_SDA2 = MKDEV(SCSI_DISK0_MAJOR, 2), - Root_HDC1 = MKDEV(IDE1_MAJOR, 1), - Root_SR0 = MKDEV(SCSI_CDROM_MAJOR, 0), }; extern dev_t ROOT_DEV; diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index efa5c324369a..1dd530ce8b45 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -15,6 +15,7 @@ #include <linux/spinlock.h> #include <linux/atomic.h> #include <linux/err.h> +#include <linux/cleanup.h> #ifdef CONFIG_DEBUG_LOCK_ALLOC # define __RWSEM_DEP_MAP_INIT(lockname) \ @@ -201,6 +202,13 @@ extern void up_read(struct rw_semaphore *sem); */ extern void up_write(struct rw_semaphore *sem); +DEFINE_GUARD(rwsem_read, struct rw_semaphore *, down_read(_T), up_read(_T)) +DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) + +DEFINE_FREE(up_read, struct rw_semaphore *, if (_T) up_read(_T)) +DEFINE_FREE(up_write, struct rw_semaphore *, if (_T) up_write(_T)) + + /* * downgrade write lock to read lock */ diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 375a5e90d86a..77df3d7b18a6 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -16,7 +16,7 @@ struct scatterlist { #ifdef CONFIG_NEED_SG_DMA_LENGTH unsigned int dma_length; #endif -#ifdef CONFIG_PCI_P2PDMA +#ifdef CONFIG_NEED_SG_DMA_FLAGS unsigned int dma_flags; #endif }; @@ -141,6 +141,30 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page, sg->length = len; } +/** + * sg_set_folio - Set sg entry to point at given folio + * @sg: SG entry + * @folio: The folio + * @len: Length of data + * @offset: Offset into folio + * + * Description: + * Use this function to set an sg entry pointing at a folio, never assign + * the folio directly. We encode sg table information in the lower bits + * of the folio pointer. See sg_page() for looking up the page belonging + * to an sg entry. + * + **/ +static inline void sg_set_folio(struct scatterlist *sg, struct folio *folio, + size_t len, size_t offset) +{ + WARN_ON_ONCE(len > UINT_MAX); + WARN_ON_ONCE(offset > UINT_MAX); + sg_assign_page(sg, &folio->page); + sg->offset = offset; + sg->length = len; +} + static inline struct page *sg_page(struct scatterlist *sg) { #ifdef CONFIG_DEBUG_SG @@ -249,17 +273,18 @@ static inline void sg_unmark_end(struct scatterlist *sg) } /* - * CONFGI_PCI_P2PDMA depends on CONFIG_64BIT which means there is 4 bytes - * in struct scatterlist (assuming also CONFIG_NEED_SG_DMA_LENGTH is set). - * Use this padding for DMA flags bits to indicate when a specific - * dma address is a bus address. + * One 64-bit architectures there is a 4-byte padding in struct scatterlist + * (assuming also CONFIG_NEED_SG_DMA_LENGTH is set). Use this padding for DMA + * flags bits to indicate when a specific dma address is a bus address or the + * buffer may have been bounced via SWIOTLB. */ -#ifdef CONFIG_PCI_P2PDMA +#ifdef CONFIG_NEED_SG_DMA_FLAGS -#define SG_DMA_BUS_ADDRESS (1 << 0) +#define SG_DMA_BUS_ADDRESS (1 << 0) +#define SG_DMA_SWIOTLB (1 << 1) /** - * sg_dma_is_bus address - Return whether a given segment was marked + * sg_dma_is_bus_address - Return whether a given segment was marked * as a bus address * @sg: SG entry * @@ -267,13 +292,13 @@ static inline void sg_unmark_end(struct scatterlist *sg) * Returns true if sg_dma_mark_bus_address() has been called on * this segment. **/ -static inline bool sg_is_dma_bus_address(struct scatterlist *sg) +static inline bool sg_dma_is_bus_address(struct scatterlist *sg) { return sg->dma_flags & SG_DMA_BUS_ADDRESS; } /** - * sg_dma_mark_bus address - Mark the scatterlist entry as a bus address + * sg_dma_mark_bus_address - Mark the scatterlist entry as a bus address * @sg: SG entry * * Description: @@ -299,9 +324,37 @@ static inline void sg_dma_unmark_bus_address(struct scatterlist *sg) sg->dma_flags &= ~SG_DMA_BUS_ADDRESS; } +/** + * sg_dma_is_swiotlb - Return whether the scatterlist was marked for SWIOTLB + * bouncing + * @sg: SG entry + * + * Description: + * Returns true if the scatterlist was marked for SWIOTLB bouncing. Not all + * elements may have been bounced, so the caller would have to check + * individual SG entries with is_swiotlb_buffer(). + */ +static inline bool sg_dma_is_swiotlb(struct scatterlist *sg) +{ + return sg->dma_flags & SG_DMA_SWIOTLB; +} + +/** + * sg_dma_mark_swiotlb - Mark the scatterlist for SWIOTLB bouncing + * @sg: SG entry + * + * Description: + * Marks a a scatterlist for SWIOTLB bounce. Not all SG entries may be + * bounced. + */ +static inline void sg_dma_mark_swiotlb(struct scatterlist *sg) +{ + sg->dma_flags |= SG_DMA_SWIOTLB; +} + #else -static inline bool sg_is_dma_bus_address(struct scatterlist *sg) +static inline bool sg_dma_is_bus_address(struct scatterlist *sg) { return false; } @@ -311,8 +364,15 @@ static inline void sg_dma_mark_bus_address(struct scatterlist *sg) static inline void sg_dma_unmark_bus_address(struct scatterlist *sg) { } +static inline bool sg_dma_is_swiotlb(struct scatterlist *sg) +{ + return false; +} +static inline void sg_dma_mark_swiotlb(struct scatterlist *sg) +{ +} -#endif +#endif /* CONFIG_NEED_SG_DMA_FLAGS */ /** * sg_phys - Return physical address of an sg entry diff --git a/include/linux/sched.h b/include/linux/sched.h index eed5d65b8d1f..609bde814cb0 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -41,7 +41,6 @@ /* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; -struct backing_dev_info; struct bio_list; struct blk_plug; struct bpf_local_storage; @@ -1186,8 +1185,6 @@ struct task_struct { /* VM state: */ struct reclaim_state *reclaim_state; - struct backing_dev_info *backing_dev_info; - struct io_context *io_context; #ifdef CONFIG_COMPACTION @@ -1852,7 +1849,9 @@ current_restore_flags(unsigned long orig_flags, unsigned long flags) } extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial); -extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_effective_cpus); +extern int task_can_attach(struct task_struct *p); +extern int dl_bw_alloc(int cpu, u64 dl_bw); +extern void dl_bw_free(int cpu, u64 dl_bw); #ifdef CONFIG_SMP extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask); extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask); @@ -2006,15 +2005,12 @@ static __always_inline void scheduler_ipi(void) */ preempt_fold_need_resched(); } -extern unsigned long wait_task_inactive(struct task_struct *, unsigned int match_state); #else static inline void scheduler_ipi(void) { } -static inline unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state) -{ - return 1; -} #endif +extern unsigned long wait_task_inactive(struct task_struct *, unsigned int match_state); + /* * Set thread flags in other task's structures. * See asm/thread_info.h for TIF_xxxx flags available: diff --git a/include/linux/sched/clock.h b/include/linux/sched/clock.h index ca008f7d3615..196f0ca351a2 100644 --- a/include/linux/sched/clock.h +++ b/include/linux/sched/clock.h @@ -12,7 +12,16 @@ * * Please use one of the three interfaces below. */ -extern unsigned long long notrace sched_clock(void); +extern u64 sched_clock(void); + +#if defined(CONFIG_ARCH_WANTS_NO_INSTR) || defined(CONFIG_GENERIC_SCHED_CLOCK) +extern u64 sched_clock_noinstr(void); +#else +static __always_inline u64 sched_clock_noinstr(void) +{ + return sched_clock(); +} +#endif /* * See the comment in kernel/sched/clock.c @@ -45,6 +54,11 @@ static inline u64 cpu_clock(int cpu) return sched_clock(); } +static __always_inline u64 local_clock_noinstr(void) +{ + return sched_clock_noinstr(); +} + static __always_inline u64 local_clock(void) { return sched_clock(); @@ -79,6 +93,7 @@ static inline u64 cpu_clock(int cpu) return sched_clock_cpu(cpu); } +extern u64 local_clock_noinstr(void); extern u64 local_clock(void); #endif diff --git a/include/linux/sched/sd_flags.h b/include/linux/sched/sd_flags.h index 57bde66d95f7..fad77b5172e2 100644 --- a/include/linux/sched/sd_flags.h +++ b/include/linux/sched/sd_flags.h @@ -132,12 +132,9 @@ SD_FLAG(SD_SERIALIZE, SDF_SHARED_PARENT | SDF_NEEDS_GROUPS) /* * Place busy tasks earlier in the domain * - * SHARED_CHILD: Usually set on the SMT level. Technically could be set further - * up, but currently assumed to be set from the base domain - * upwards (see update_top_cache_domain()). * NEEDS_GROUPS: Load balancing flag. */ -SD_FLAG(SD_ASYM_PACKING, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS) +SD_FLAG(SD_ASYM_PACKING, SDF_NEEDS_GROUPS) /* * Prefer to place tasks in a sibling domain diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 20099268fa25..669e8cff40c7 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -135,7 +135,7 @@ struct signal_struct { #ifdef CONFIG_POSIX_TIMERS /* POSIX.1b Interval Timers */ - int posix_timer_id; + unsigned int next_posix_timer_id; struct list_head posix_timers; /* ITIMER_REAL timer for the process */ diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index 537cbf9a2ade..dd35ce28bb90 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -29,7 +29,6 @@ struct kernel_clone_args { u32 io_thread:1; u32 user_worker:1; u32 no_files:1; - u32 ignore_signals:1; unsigned long stack; unsigned long stack_size; unsigned long tls; @@ -126,6 +125,8 @@ static inline void put_task_struct(struct task_struct *t) __put_task_struct(t); } +DEFINE_FREE(put_task, struct task_struct *, if (_T) put_task_struct(_T)) + static inline void put_task_struct_many(struct task_struct *t, int nr) { if (refcount_sub_and_test(nr, &t->usage)) diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 816df6cc444e..67b573d5bf28 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -203,7 +203,7 @@ struct sched_domain_topology_level { #endif }; -extern void set_sched_topology(struct sched_domain_topology_level *tl); +extern void __init set_sched_topology(struct sched_domain_topology_level *tl); #ifdef CONFIG_SCHED_DEBUG # define SD_INIT_NAME(type) .name = #type diff --git a/include/linux/sched/vhost_task.h b/include/linux/sched/vhost_task.h index 6123c10b99cf..837a23624a66 100644 --- a/include/linux/sched/vhost_task.h +++ b/include/linux/sched/vhost_task.h @@ -2,22 +2,13 @@ #ifndef _LINUX_VHOST_TASK_H #define _LINUX_VHOST_TASK_H -#include <linux/completion.h> -struct task_struct; +struct vhost_task; -struct vhost_task { - int (*fn)(void *data); - void *data; - struct completion exited; - unsigned long flags; - struct task_struct *task; -}; - -struct vhost_task *vhost_task_create(int (*fn)(void *), void *arg, +struct vhost_task *vhost_task_create(bool (*fn)(void *), void *arg, const char *name); void vhost_task_start(struct vhost_task *vtsk); void vhost_task_stop(struct vhost_task *vtsk); -bool vhost_task_should_stop(struct vhost_task *vtsk); +void vhost_task_wake(struct vhost_task *vtsk); #endif diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 0ce5746a4470..e6fe4f73ffe6 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -629,11 +629,25 @@ struct scmi_powercap_info { * @num_domains_get: get the count of powercap domains provided by SCMI. * @info_get: get the information for the specified domain. * @cap_get: get the current CAP value for the specified domain. + * On SCMI platforms supporting powercap zone disabling, this could + * report a zero value for a zone where powercapping is disabled. * @cap_set: set the CAP value for the specified domain to the provided value; * if the domain supports setting the CAP with an asynchronous command * this request will finally trigger an asynchronous transfer, but, if * @ignore_dresp here is set to true, this call will anyway return * immediately without waiting for the related delayed response. + * Note that the powercap requested value must NOT be zero, even if + * the platform supports disabling a powercap by setting its cap to + * zero (since SCMI v3.2): there are dedicated operations that should + * be used for that. (@cap_enable_set/get) + * @cap_enable_set: enable or disable the powercapping on the specified domain, + * if supported by the SCMI platform implementation. + * Note that, by the SCMI specification, the platform can + * silently ignore our disable request and decide to enforce + * anyway some other powercap value requested by another agent + * on the system: for this reason @cap_get and @cap_enable_get + * will always report the final platform view of the powercaps. + * @cap_enable_get: get the current CAP enable status for the specified domain. * @pai_get: get the current PAI value for the specified domain. * @pai_set: set the PAI value for the specified domain to the provided value. * @measurements_get: retrieve the current average power measurements for the @@ -662,6 +676,10 @@ struct scmi_powercap_proto_ops { u32 *power_cap); int (*cap_set)(const struct scmi_protocol_handle *ph, u32 domain_id, u32 power_cap, bool ignore_dresp); + int (*cap_enable_set)(const struct scmi_protocol_handle *ph, + u32 domain_id, bool enable); + int (*cap_enable_get)(const struct scmi_protocol_handle *ph, + u32 domain_id, bool *enable); int (*pai_get)(const struct scmi_protocol_handle *ph, u32 domain_id, u32 *pai); int (*pai_set)(const struct scmi_protocol_handle *ph, u32 domain_id, diff --git a/include/linux/security.h b/include/linux/security.h index e2734e9e44d5..32828502f09e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1465,6 +1465,7 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, struct sock *newsk); int security_sctp_assoc_established(struct sctp_association *asoc, struct sk_buff *skb); +int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk); #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct sock *sock, @@ -1692,6 +1693,11 @@ static inline int security_sctp_assoc_established(struct sctp_association *asoc, { return 0; } + +static inline int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk) +{ + return 0; +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_INFINIBAND diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index 3926e9027947..987a59d977c5 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h @@ -671,9 +671,9 @@ typedef struct { * * Return: sequence counter raw value. Use the lowest bit as an index for * picking which data copy to read. The full counter must then be checked - * with read_seqcount_latch_retry(). + * with raw_read_seqcount_latch_retry(). */ -static inline unsigned raw_read_seqcount_latch(const seqcount_latch_t *s) +static __always_inline unsigned raw_read_seqcount_latch(const seqcount_latch_t *s) { /* * Pairs with the first smp_wmb() in raw_write_seqcount_latch(). @@ -683,16 +683,17 @@ static inline unsigned raw_read_seqcount_latch(const seqcount_latch_t *s) } /** - * read_seqcount_latch_retry() - end a seqcount_latch_t read section + * raw_read_seqcount_latch_retry() - end a seqcount_latch_t read section * @s: Pointer to seqcount_latch_t * @start: count, from raw_read_seqcount_latch() * * Return: true if a read section retry is required, else false */ -static inline int -read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start) +static __always_inline int +raw_read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start) { - return read_seqcount_retry(&s->seqcount, start); + smp_rmb(); + return unlikely(READ_ONCE(s->seqcount.sequence) != start); } /** @@ -752,7 +753,7 @@ read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start) * entry = data_query(latch->data[idx], ...); * * // This includes needed smp_rmb() - * } while (read_seqcount_latch_retry(&latch->seq, seq)); + * } while (raw_read_seqcount_latch_retry(&latch->seq, seq)); * * return entry; * } diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 6f78f302d272..be65de65fe61 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -7,17 +7,34 @@ #ifndef _LINUX_SERIAL_8250_H #define _LINUX_SERIAL_8250_H +#include <linux/errno.h> #include <linux/serial_core.h> #include <linux/serial_reg.h> #include <linux/platform_device.h> +struct uart_8250_port; + /* * This is the platform device platform_data structure + * + * @mapsize: Port size for ioremap() + * @bugs: Port bugs + * + * @dl_read: ``u32 ()(struct uart_8250_port *up)`` + * + * UART divisor latch read. + * + * @dl_write: ``void ()(struct uart_8250_port *up, u32 value)`` + * + * Write @value into UART divisor latch. + * + * Locking: Caller holds port's lock. */ struct plat_serial8250_port { unsigned long iobase; /* io base address */ void __iomem *membase; /* ioremap cookie or NULL */ resource_size_t mapbase; /* resource base */ + resource_size_t mapsize; unsigned int uartclk; /* UART clock rate */ unsigned int irq; /* interrupt number */ unsigned long irqflags; /* request_irq flags */ @@ -28,8 +45,11 @@ struct plat_serial8250_port { unsigned char has_sysrq; /* supports magic SysRq */ unsigned int type; /* If UPF_FIXED_TYPE */ upf_t flags; /* UPF_* flags */ + u16 bugs; /* port bugs */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); + u32 (*dl_read)(struct uart_8250_port *up); + void (*dl_write)(struct uart_8250_port *up, u32 value); void (*set_termios)(struct uart_port *, struct ktermios *new, const struct ktermios *old); @@ -90,15 +110,23 @@ struct uart_8250_em485 { * their own 8250 ports without registering their own * platform device. Using these will make your driver * dependent on the 8250 driver. + * + * @dl_read: ``u32 ()(struct uart_8250_port *port)`` + * + * UART divisor latch read. + * + * @dl_write: ``void ()(struct uart_8250_port *port, u32 value)`` + * + * Write @value into UART divisor latch. + * + * Locking: Caller holds port's lock. */ - struct uart_8250_port { struct uart_port port; struct timer_list timer; /* "no irq" timer */ struct list_head list; /* ports on this IRQ */ u32 capabilities; /* port capabilities */ - unsigned short bugs; /* port bugs */ - bool fifo_bug; /* min RX trigger if enabled */ + u16 bugs; /* port bugs */ unsigned int tx_loadsz; /* transmit fifo load size */ unsigned char acr; unsigned char fcr; @@ -129,8 +157,8 @@ struct uart_8250_port { const struct uart_8250_ops *ops; /* 8250 specific callbacks */ - int (*dl_read)(struct uart_8250_port *); - void (*dl_write)(struct uart_8250_port *, int); + u32 (*dl_read)(struct uart_8250_port *up); + void (*dl_write)(struct uart_8250_port *up, u32 value); struct uart_8250_em485 *em485; void (*rs485_start_tx)(struct uart_8250_port *); @@ -183,8 +211,11 @@ void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up, u32 *capabilities)); #ifdef CONFIG_SERIAL_8250_RT288X -unsigned int au_serial_in(struct uart_port *p, int offset); -void au_serial_out(struct uart_port *p, int offset, int value); +int rt288x_setup(struct uart_port *p); +int au_platform_setup(struct plat_serial8250_port *p); +#else +static inline int rt288x_setup(struct uart_port *p) { return -ENODEV; } +static inline int au_platform_setup(struct plat_serial8250_port *p) { return -ENODEV; } #endif #endif diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 66ecec15a1bf..6d58c57acdaa 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -28,6 +28,7 @@ struct uart_port; struct serial_struct; +struct serial_port_device; struct device; struct gpio_desc; @@ -458,6 +459,7 @@ struct uart_port { struct serial_rs485 *rs485); int (*iso7816_config)(struct uart_port *, struct serial_iso7816 *iso7816); + int ctrl_id; /* optional serial core controller id */ unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ @@ -563,7 +565,8 @@ struct uart_port { unsigned int minor; resource_size_t mapbase; /* for ioremap */ resource_size_t mapsize; - struct device *dev; /* parent device */ + struct device *dev; /* serial port physical parent device */ + struct serial_port_device *port_dev; /* serial core port device */ unsigned long sysrq; /* sysrq timeout */ unsigned int sysrq_ch; /* char for sysrq */ @@ -853,7 +856,7 @@ void uart_console_write(struct uart_port *port, const char *s, int uart_register_driver(struct uart_driver *uart); void uart_unregister_driver(struct uart_driver *uart); int uart_add_one_port(struct uart_driver *reg, struct uart_port *port); -int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port); +void uart_remove_one_port(struct uart_driver *reg, struct uart_port *port); bool uart_match_port(const struct uart_port *port1, const struct uart_port *port2); diff --git a/include/linux/sfp.h b/include/linux/sfp.h index ef06a195b3c2..9346cd44814d 100644 --- a/include/linux/sfp.h +++ b/include/linux/sfp.h @@ -342,6 +342,12 @@ enum { SFP_ENCODING = 11, SFP_BR_NOMINAL = 12, SFP_RATE_ID = 13, + SFF_RID_8079 = 0x01, + SFF_RID_8431_RX_ONLY = 0x02, + SFF_RID_8431_TX_ONLY = 0x04, + SFF_RID_8431 = 0x06, + SFF_RID_10G8G = 0x0e, + SFP_LINK_LEN_SM_KM = 14, SFP_LINK_LEN_SM_100M = 15, SFP_LINK_LEN_50UM_OM2_10M = 16, @@ -465,6 +471,7 @@ enum { SFP_STATUS = 110, SFP_STATUS_TX_DISABLE = BIT(7), SFP_STATUS_TX_DISABLE_FORCE = BIT(6), + SFP_STATUS_RS0_SELECT = BIT(3), SFP_STATUS_TX_FAULT = BIT(2), SFP_STATUS_RX_LOS = BIT(1), SFP_ALARM0 = 112, @@ -496,6 +503,7 @@ enum { SFP_WARN1_RXPWR_LOW = BIT(6), SFP_EXT_STATUS = 118, + SFP_EXT_STATUS_RS1_SELECT = BIT(3), SFP_EXT_STATUS_PWRLVL_SELECT = BIT(0), SFP_VSL = 120, @@ -556,6 +564,7 @@ int sfp_get_module_eeprom_by_page(struct sfp_bus *bus, struct netlink_ext_ack *extack); void sfp_upstream_start(struct sfp_bus *bus); void sfp_upstream_stop(struct sfp_bus *bus); +void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd); void sfp_bus_put(struct sfp_bus *bus); struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode); int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, @@ -615,6 +624,11 @@ static inline void sfp_upstream_stop(struct sfp_bus *bus) { } +static inline void sfp_upstream_set_signal_rate(struct sfp_bus *bus, + unsigned int rate_kbd) +{ +} + static inline void sfp_bus_put(struct sfp_bus *bus) { } diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index 7bde8e1c228a..224293b2dd06 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -107,7 +107,10 @@ extern void synchronize_shrinkers(void); #ifdef CONFIG_SHRINKER_DEBUG extern int shrinker_debugfs_add(struct shrinker *shrinker); -extern struct dentry *shrinker_debugfs_remove(struct shrinker *shrinker); +extern struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker, + int *debugfs_id); +extern void shrinker_debugfs_remove(struct dentry *debugfs_entry, + int debugfs_id); extern int __printf(2, 3) shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...); #else /* CONFIG_SHRINKER_DEBUG */ @@ -115,10 +118,16 @@ static inline int shrinker_debugfs_add(struct shrinker *shrinker) { return 0; } -static inline struct dentry *shrinker_debugfs_remove(struct shrinker *shrinker) +static inline struct dentry *shrinker_debugfs_detach(struct shrinker *shrinker, + int *debugfs_id) { + *debugfs_id = -1; return NULL; } +static inline void shrinker_debugfs_remove(struct dentry *debugfs_entry, + int debugfs_id) +{ +} static inline __printf(2, 3) int shrinker_debugfs_rename(struct shrinker *shrinker, const char *fmt, ...) { diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 738776ab8838..91ed66952580 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -330,6 +330,7 @@ struct tc_skb_ext { u8 post_ct_snat:1; u8 post_ct_dnat:1; u8 act_miss:1; /* Set if act_miss_cookie is used */ + u8 l2_miss:1; /* Set by bridge upon FDB or MDB miss */ }; #endif @@ -1383,7 +1384,7 @@ static inline int skb_pad(struct sk_buff *skb, int pad) #define dev_kfree_skb(a) consume_skb(a) int skb_append_pagefrags(struct sk_buff *skb, struct page *page, - int offset, size_t size); + int offset, size_t size, size_t max_frags); struct skb_seq_state { __u32 lower_offset; @@ -1587,6 +1588,16 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) to->l4_hash = from->l4_hash; }; +static inline int skb_cmp_decrypted(const struct sk_buff *skb1, + const struct sk_buff *skb2) +{ +#ifdef CONFIG_TLS_DEVICE + return skb2->decrypted - skb1->decrypted; +#else + return 0; +#endif +} + static inline void skb_copy_decrypted(struct sk_buff *to, const struct sk_buff *from) { @@ -2411,20 +2422,22 @@ static inline unsigned int skb_pagelen(const struct sk_buff *skb) return skb_headlen(skb) + __skb_pagelen(skb); } +static inline void skb_frag_fill_page_desc(skb_frag_t *frag, + struct page *page, + int off, int size) +{ + frag->bv_page = page; + frag->bv_offset = off; + skb_frag_size_set(frag, size); +} + static inline void __skb_fill_page_desc_noacc(struct skb_shared_info *shinfo, int i, struct page *page, int off, int size) { skb_frag_t *frag = &shinfo->frags[i]; - /* - * Propagate page pfmemalloc to the skb if we can. The problem is - * that not all callers have unique ownership of the page but rely - * on page_is_pfmemalloc doing the right thing(tm). - */ - frag->bv_page = page; - frag->bv_offset = off; - skb_frag_size_set(frag, size); + skb_frag_fill_page_desc(frag, page, off, size); } /** @@ -2456,6 +2469,11 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size) { __skb_fill_page_desc_noacc(skb_shinfo(skb), i, page, off, size); + + /* Propagate page pfmemalloc to the skb if we can. The problem is + * that not all callers have unique ownership of the page but rely + * on page_is_pfmemalloc doing the right thing(tm). + */ page = compound_head(page); if (page_is_pfmemalloc(page)) skb->pfmemalloc = true; @@ -3484,32 +3502,6 @@ static inline void skb_frag_page_copy(skb_frag_t *fragto, fragto->bv_page = fragfrom->bv_page; } -/** - * __skb_frag_set_page - sets the page contained in a paged fragment - * @frag: the paged fragment - * @page: the page to set - * - * Sets the fragment @frag to contain @page. - */ -static inline void __skb_frag_set_page(skb_frag_t *frag, struct page *page) -{ - frag->bv_page = page; -} - -/** - * skb_frag_set_page - sets the page contained in a paged fragment of an skb - * @skb: the buffer - * @f: the fragment offset - * @page: the page to set - * - * Sets the @f'th fragment of @skb to contain @page. - */ -static inline void skb_frag_set_page(struct sk_buff *skb, int f, - struct page *page) -{ - __skb_frag_set_page(&skb_shinfo(skb)->frags[f], page); -} - bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio); /** @@ -3982,8 +3974,6 @@ int skb_zerocopy(struct sk_buff *to, struct sk_buff *from, void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); void skb_scrub_packet(struct sk_buff *skb, bool xnet); -bool skb_gso_validate_network_len(const struct sk_buff *skb, unsigned int mtu); -bool skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len); struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); struct sk_buff *skb_segment_list(struct sk_buff *skb, netdev_features_t features, unsigned int offset); @@ -4033,7 +4023,7 @@ __skb_header_pointer(const struct sk_buff *skb, int offset, int len, if (likely(hlen - offset >= len)) return (void *)data + offset; - if (!skb || unlikely(skb_copy_bits(skb, offset, buffer, len) < 0)) + if (!skb || !buffer || unlikely(skb_copy_bits(skb, offset, buffer, len) < 0)) return NULL; return buffer; @@ -4849,75 +4839,6 @@ static inline struct sec_path *skb_sec_path(const struct sk_buff *skb) #endif } -/* Keeps track of mac header offset relative to skb->head. - * It is useful for TSO of Tunneling protocol. e.g. GRE. - * For non-tunnel skb it points to skb_mac_header() and for - * tunnel skb it points to outer mac header. - * Keeps track of level of encapsulation of network headers. - */ -struct skb_gso_cb { - union { - int mac_offset; - int data_offset; - }; - int encap_level; - __wsum csum; - __u16 csum_start; -}; -#define SKB_GSO_CB_OFFSET 32 -#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_GSO_CB_OFFSET)) - -static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) -{ - return (skb_mac_header(inner_skb) - inner_skb->head) - - SKB_GSO_CB(inner_skb)->mac_offset; -} - -static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) -{ - int new_headroom, headroom; - int ret; - - headroom = skb_headroom(skb); - ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC); - if (ret) - return ret; - - new_headroom = skb_headroom(skb); - SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom); - return 0; -} - -static inline void gso_reset_checksum(struct sk_buff *skb, __wsum res) -{ - /* Do not update partial checksums if remote checksum is enabled. */ - if (skb->remcsum_offload) - return; - - SKB_GSO_CB(skb)->csum = res; - SKB_GSO_CB(skb)->csum_start = skb_checksum_start(skb) - skb->head; -} - -/* Compute the checksum for a gso segment. First compute the checksum value - * from the start of transport header to SKB_GSO_CB(skb)->csum_start, and - * then add in skb->csum (checksum from csum_start to end of packet). - * skb->csum and csum_start are then updated to reflect the checksum of the - * resultant packet starting from the transport header-- the resultant checksum - * is in the res argument (i.e. normally zero or ~ of checksum of a pseudo - * header. - */ -static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res) -{ - unsigned char *csum_start = skb_transport_header(skb); - int plen = (skb->head + SKB_GSO_CB(skb)->csum_start) - csum_start; - __wsum partial = SKB_GSO_CB(skb)->csum; - - SKB_GSO_CB(skb)->csum = res; - SKB_GSO_CB(skb)->csum_start = csum_start - skb->head; - - return csum_fold(csum_partial(csum_start, plen, partial)); -} - static inline bool skb_is_gso(const struct sk_buff *skb) { return skb_shinfo(skb)->gso_size; @@ -5116,5 +5037,8 @@ static inline void skb_mark_for_recycle(struct sk_buff *skb) #endif } +ssize_t skb_splice_from_iter(struct sk_buff *skb, struct iov_iter *iter, + ssize_t maxsize, gfp_t gfp); + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index 84f787416a54..054d7911bfc9 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -71,7 +71,6 @@ struct sk_psock_link { }; struct sk_psock_work_state { - struct sk_buff *skb; u32 len; u32 off; }; @@ -105,7 +104,7 @@ struct sk_psock { struct proto *sk_proto; struct mutex work_mutex; struct sk_psock_work_state work_state; - struct work_struct work; + struct delayed_work work; struct rcu_work rwork; }; diff --git a/include/linux/slab.h b/include/linux/slab.h index 6b3e155b70bf..848c7c82ad5a 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -12,11 +12,13 @@ #ifndef _LINUX_SLAB_H #define _LINUX_SLAB_H +#include <linux/cache.h> #include <linux/gfp.h> #include <linux/overflow.h> #include <linux/types.h> #include <linux/workqueue.h> #include <linux/percpu-refcount.h> +#include <linux/cleanup.h> /* @@ -53,16 +55,18 @@ * stays valid, the trick to using this is relying on an independent * object validation pass. Something like: * - * rcu_read_lock() - * again: + * begin: + * rcu_read_lock(); * obj = lockless_lookup(key); * if (obj) { * if (!try_get_ref(obj)) // might fail for free objects - * goto again; + * rcu_read_unlock(); + * goto begin; * * if (obj->key != key) { // not the object we expected * put_ref(obj); - * goto again; + * rcu_read_unlock(); + * goto begin; * } * } * rcu_read_unlock(); @@ -106,6 +110,18 @@ /* Avoid kmemleak tracing */ #define SLAB_NOLEAKTRACE ((slab_flags_t __force)0x00800000U) +/* + * Prevent merging with compatible kmem caches. This flag should be used + * cautiously. Valid use cases: + * + * - caches created for self-tests (e.g. kunit) + * - general caches created and used by a subsystem, only when a + * (subsystem-specific) debug option is enabled + * - performance critical caches, should be very rare and consulted with slab + * maintainers, and not used together with CONFIG_SLUB_TINY + */ +#define SLAB_NO_MERGE ((slab_flags_t __force)0x01000000U) + /* Fault injection mark */ #ifdef CONFIG_FAILSLAB # define SLAB_FAILSLAB ((slab_flags_t __force)0x02000000U) @@ -211,6 +227,8 @@ void kfree(const void *objp); void kfree_sensitive(const void *objp); size_t __ksize(const void *objp); +DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) + /** * ksize - Report actual allocation size of associated object * @@ -235,12 +253,17 @@ void kmem_dump_obj(void *object); * alignment larger than the alignment of a 64-bit integer. * Setting ARCH_DMA_MINALIGN in arch headers allows that. */ -#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8 +#ifdef ARCH_HAS_DMA_MINALIGN +#if ARCH_DMA_MINALIGN > 8 && !defined(ARCH_KMALLOC_MINALIGN) #define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN -#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN -#define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN) -#else +#endif +#endif + +#ifndef ARCH_KMALLOC_MINALIGN #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) +#elif ARCH_KMALLOC_MINALIGN > 8 +#define KMALLOC_MIN_SIZE ARCH_KMALLOC_MINALIGN +#define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE) #endif /* diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index f6df03f934e5..deb90cf4bffb 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -39,7 +39,8 @@ enum stat_item { CPU_PARTIAL_FREE, /* Refill cpu partial on free */ CPU_PARTIAL_NODE, /* Refill cpu partial from node partial */ CPU_PARTIAL_DRAIN, /* Drain cpu partial to node partial */ - NR_SLUB_STAT_ITEMS }; + NR_SLUB_STAT_ITEMS +}; #ifndef CONFIG_SLUB_TINY /* @@ -47,8 +48,13 @@ enum stat_item { * with this_cpu_cmpxchg_double() alignment requirements. */ struct kmem_cache_cpu { - void **freelist; /* Pointer to next available object */ - unsigned long tid; /* Globally unique transaction id */ + union { + struct { + void **freelist; /* Pointer to next available object */ + unsigned long tid; /* Globally unique transaction id */ + }; + freelist_aba_t freelist_tid; + }; struct slab *slab; /* The slab from which we are allocating */ #ifdef CONFIG_SLUB_CPU_PARTIAL struct slab *partial; /* Partially allocated frozen slabs */ diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 37544ea6286d..2475ef914746 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -27,8 +27,7 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_CCORR, DDP_COMPONENT_COLOR0, DDP_COMPONENT_COLOR1, - DDP_COMPONENT_DITHER, - DDP_COMPONENT_DITHER0 = DDP_COMPONENT_DITHER, + DDP_COMPONENT_DITHER0, DDP_COMPONENT_DITHER1, DDP_COMPONENT_DP_INTF0, DDP_COMPONENT_DP_INTF1, diff --git a/include/linux/soc/pxa/smemc.h b/include/linux/soc/pxa/smemc.h index f1ffea236c15..4feb1dded3ec 100644 --- a/include/linux/soc/pxa/smemc.h +++ b/include/linux/soc/pxa/smemc.h @@ -10,4 +10,20 @@ int pxa2xx_smemc_get_sdram_rows(void); unsigned int pxa3xx_smemc_get_memclkdiv(void); void __iomem *pxa_smemc_get_mdrefr(void); +/* + * Once fully converted to the clock framework, all these functions should be + * removed, and replaced with a clk_get(NULL, "core"). + */ +#ifdef CONFIG_PXA25x +extern unsigned pxa25x_get_clk_frequency_khz(int); +#else +#define pxa25x_get_clk_frequency_khz(x) (0) +#endif + +#ifdef CONFIG_PXA27x +extern unsigned pxa27x_get_clk_frequency_khz(int); +#else +#define pxa27x_get_clk_frequency_khz(x) (0) +#endif + #endif diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index c55a0bc8cb0e..821a19135bb6 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -490,9 +490,13 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq, unsigned int *index, unsigned long *res_freq, bool exact); +void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len); + int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len, dma_addr_t *iova); +void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len); + int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len, dma_addr_t *iova); diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index 423220e66026..93417ba1ead4 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -69,9 +69,6 @@ struct llcc_slice_desc { /** * struct llcc_edac_reg_data - llcc edac registers data for each error type * @name: Name of the error - * @synd_reg: Syndrome register address - * @count_status_reg: Status register address to read the error count - * @ways_status_reg: Status register address to read the error ways * @reg_cnt: Number of registers * @count_mask: Mask value to get the error count * @ways_mask: Mask value to get the error ways @@ -80,9 +77,6 @@ struct llcc_slice_desc { */ struct llcc_edac_reg_data { char *name; - u64 synd_reg; - u64 count_status_reg; - u64 ways_status_reg; u32 reg_cnt; u32 count_mask; u32 ways_mask; diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h index 86e1b358688a..223db6a9c733 100644 --- a/include/linux/soc/qcom/smem.h +++ b/include/linux/soc/qcom/smem.h @@ -11,4 +11,6 @@ int qcom_smem_get_free_space(unsigned host); phys_addr_t qcom_smem_virt_to_phys(void *p); +int qcom_smem_get_soc_id(u32 *id); + #endif diff --git a/include/linux/soc/qcom/socinfo.h b/include/linux/soc/qcom/socinfo.h new file mode 100644 index 000000000000..e78777bb0f4a --- /dev/null +++ b/include/linux/soc/qcom/socinfo.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __QCOM_SOCINFO_H__ +#define __QCOM_SOCINFO_H__ + +/* + * SMEM item id, used to acquire handles to respective + * SMEM region. + */ +#define SMEM_HW_SW_BUILD_ID 137 + +#define SMEM_SOCINFO_BUILD_ID_LENGTH 32 +#define SMEM_SOCINFO_CHIP_ID_LENGTH 32 + +/* Socinfo SMEM item structure */ +struct socinfo { + __le32 fmt; + __le32 id; + __le32 ver; + char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH]; + /* Version 2 */ + __le32 raw_id; + __le32 raw_ver; + /* Version 3 */ + __le32 hw_plat; + /* Version 4 */ + __le32 plat_ver; + /* Version 5 */ + __le32 accessory_chip; + /* Version 6 */ + __le32 hw_plat_subtype; + /* Version 7 */ + __le32 pmic_model; + __le32 pmic_die_rev; + /* Version 8 */ + __le32 pmic_model_1; + __le32 pmic_die_rev_1; + __le32 pmic_model_2; + __le32 pmic_die_rev_2; + /* Version 9 */ + __le32 foundry_id; + /* Version 10 */ + __le32 serial_num; + /* Version 11 */ + __le32 num_pmics; + __le32 pmic_array_offset; + /* Version 12 */ + __le32 chip_family; + __le32 raw_device_family; + __le32 raw_device_num; + /* Version 13 */ + __le32 nproduct_id; + char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH]; + /* Version 14 */ + __le32 num_clusters; + __le32 ncluster_array_offset; + __le32 num_subset_parts; + __le32 nsubset_parts_array_offset; + /* Version 15 */ + __le32 nmodem_supported; + /* Version 16 */ + __le32 feature_code; + __le32 pcode; + __le32 npartnamemap_offset; + __le32 nnum_partname_mapping; + /* Version 17 */ + __le32 oem_variant; + /* Version 18 */ + __le32 num_kvps; + __le32 kvps_offset; + /* Version 19 */ + __le32 num_func_clusters; + __le32 boot_cluster; + __le32 boot_core; +}; + +#endif diff --git a/include/linux/socket.h b/include/linux/socket.h index 13c3a237b9c9..39b74d83c7c4 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -177,6 +177,7 @@ static inline size_t msg_data_left(struct msghdr *msg) #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ #define SCM_SECURITY 0x03 /* rw: security label */ +#define SCM_PIDFD 0x04 /* ro: pidfd (int) */ struct ucred { __u32 pid; @@ -318,7 +319,6 @@ struct ucred { #define MSG_MORE 0x8000 /* Sender will send more */ #define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */ #define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */ -#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */ #define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */ #define MSG_EOF MSG_FIN #define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */ @@ -327,6 +327,7 @@ struct ucred { */ #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ +#define MSG_SPLICE_PAGES 0x8000000 /* Splice the pages from the iterator in sendmsg() */ #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exec for file descriptor received through @@ -337,6 +338,9 @@ struct ucred { #define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */ #endif +/* Flags to be cleared on entry by sendmsg and sendmmsg syscalls */ +#define MSG_INTERNAL_SENDMSG_FLAGS \ + (MSG_SPLICE_PAGES | MSG_SENDPAGE_NOPOLICY | MSG_SENDPAGE_DECRYPTED) /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ #define SOL_IP 0 diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index ef645de13ae9..f523ceabd059 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -5,6 +5,7 @@ #define __SOUNDWIRE_H #include <linux/bug.h> +#include <linux/lockdep_types.h> #include <linux/mod_devicetable.h> #include <linux/bitfield.h> @@ -846,6 +847,7 @@ struct sdw_defer { * @post_bank_switch: Callback for post bank switch * @read_ping_status: Read status from PING frames, reported with two bits per Device. * Bits 31:24 are reserved. + * @new_peripheral_assigned: Callback to handle enumeration of new peripheral. */ struct sdw_master_ops { int (*read_prop)(struct sdw_bus *bus); @@ -860,7 +862,7 @@ struct sdw_master_ops { int (*pre_bank_switch)(struct sdw_bus *bus); int (*post_bank_switch)(struct sdw_bus *bus); u32 (*read_ping_status)(struct sdw_bus *bus); - + void (*new_peripheral_assigned)(struct sdw_bus *bus, int dev_num); }; /** @@ -906,7 +908,9 @@ struct sdw_bus { struct list_head slaves; DECLARE_BITMAP(assigned, SDW_MAX_DEVICES); struct mutex bus_lock; + struct lock_class_key bus_lock_key; struct mutex msg_lock; + struct lock_class_key msg_lock_key; int (*compute_params)(struct sdw_bus *bus); const struct sdw_master_ops *ops; const struct sdw_master_port_ops *port_ops; diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index 207701aeeb47..11fc88fb0d78 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -7,6 +7,10 @@ #include <linux/irqreturn.h> #include <linux/soundwire/sdw.h> +/********************************************************************* + * cAVS and ACE1.x definitions + *********************************************************************/ + #define SDW_SHIM_BASE 0x2C000 #define SDW_ALH_BASE 0x2C800 #define SDW_SHIM_BASE_ACE 0x38000 @@ -101,13 +105,84 @@ #define SDW_ALH_STRMZCFG_DMAT GENMASK(7, 0) #define SDW_ALH_STRMZCFG_CHN GENMASK(19, 16) +/********************************************************************* + * ACE2.x definitions for SHIM registers - only accessible when the + * HDAudio extended link LCTL.SPA/CPA = 1. + *********************************************************************/ +/* x variable is link index */ +#define SDW_SHIM2_GENERIC_BASE(x) (0x00030000 + 0x8000 * (x)) +#define SDW_IP_BASE(x) (0x00030100 + 0x8000 * (x)) +#define SDW_SHIM2_VS_BASE(x) (0x00036000 + 0x8000 * (x)) + +/* SHIM2 Generic Registers */ +/* Read-only capabilities */ +#define SDW_SHIM2_LECAP 0x00 +#define SDW_SHIM2_LECAP_HDS BIT(0) /* unset -> Host mode */ +#define SDW_SHIM2_LECAP_MLC GENMASK(3, 1) /* Number of Lanes */ + +/* PCM Stream capabilities */ +#define SDW_SHIM2_PCMSCAP 0x10 +#define SDW_SHIM2_PCMSCAP_ISS GENMASK(3, 0) /* Input-only streams */ +#define SDW_SHIM2_PCMSCAP_OSS GENMASK(7, 4) /* Output-only streams */ +#define SDW_SHIM2_PCMSCAP_BSS GENMASK(12, 8) /* Bidirectional streams */ + +/* Read-only PCM Stream Channel Count, y variable is stream */ +#define SDW_SHIM2_PCMSYCHC(y) (0x14 + (0x4 * (y))) +#define SDW_SHIM2_PCMSYCHC_CS GENMASK(3, 0) /* Channels Supported */ + +/* PCM Stream Channel Map */ +#define SDW_SHIM2_PCMSYCHM(y) (0x16 + (0x4 * (y))) +#define SDW_SHIM2_PCMSYCHM_LCHAN GENMASK(3, 0) /* Lowest channel used by the FIFO port */ +#define SDW_SHIM2_PCMSYCHM_HCHAN GENMASK(7, 4) /* Lowest channel used by the FIFO port */ +#define SDW_SHIM2_PCMSYCHM_STRM GENMASK(13, 8) /* HDaudio stream tag */ +#define SDW_SHIM2_PCMSYCHM_DIR BIT(15) /* HDaudio stream direction */ + +/* SHIM2 vendor-specific registers */ +#define SDW_SHIM2_INTEL_VS_LVSCTL 0x04 +#define SDW_SHIM2_INTEL_VS_LVSCTL_FCG BIT(26) +#define SDW_SHIM2_INTEL_VS_LVSCTL_MLCS GENMASK(29, 27) +#define SDW_SHIM2_INTEL_VS_LVSCTL_DCGD BIT(30) +#define SDW_SHIM2_INTEL_VS_LVSCTL_ICGD BIT(31) + +#define SDW_SHIM2_MLCS_XTAL_CLK 0x0 +#define SDW_SHIM2_MLCS_CARDINAL_CLK 0x1 +#define SDW_SHIM2_MLCS_AUDIO_PLL_CLK 0x2 +#define SDW_SHIM2_MLCS_MCLK_INPUT_CLK 0x3 +#define SDW_SHIM2_MLCS_WOV_RING_OSC_CLK 0x4 + +#define SDW_SHIM2_INTEL_VS_WAKEEN 0x08 +#define SDW_SHIM2_INTEL_VS_WAKEEN_PWE BIT(0) + +#define SDW_SHIM2_INTEL_VS_WAKESTS 0x0A +#define SDW_SHIM2_INTEL_VS_WAKEEN_PWS BIT(0) + +#define SDW_SHIM2_INTEL_VS_IOCTL 0x0C +#define SDW_SHIM2_INTEL_VS_IOCTL_MIF BIT(0) +#define SDW_SHIM2_INTEL_VS_IOCTL_CO BIT(1) +#define SDW_SHIM2_INTEL_VS_IOCTL_COE BIT(2) +#define SDW_SHIM2_INTEL_VS_IOCTL_DO BIT(3) +#define SDW_SHIM2_INTEL_VS_IOCTL_DOE BIT(4) +#define SDW_SHIM2_INTEL_VS_IOCTL_BKE BIT(5) +#define SDW_SHIM2_INTEL_VS_IOCTL_WPDD BIT(6) +#define SDW_SHIM2_INTEL_VS_IOCTL_ODC BIT(7) +#define SDW_SHIM2_INTEL_VS_IOCTL_CIBD BIT(8) +#define SDW_SHIM2_INTEL_VS_IOCTL_DIBD BIT(9) +#define SDW_SHIM2_INTEL_VS_IOCTL_HAMIFD BIT(10) + +#define SDW_SHIM2_INTEL_VS_ACTMCTL 0x0E +#define SDW_SHIM2_INTEL_VS_ACTMCTL_DACTQE BIT(0) +#define SDW_SHIM2_INTEL_VS_ACTMCTL_DODS BIT(1) +#define SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE BIT(2) +#define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS GENMASK(4, 3) +#define SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE BIT(5) + /** * struct sdw_intel_stream_params_data: configuration passed during * the @params_stream callback, e.g. for interaction with DSP * firmware. */ struct sdw_intel_stream_params_data { - int stream; + struct snd_pcm_substream *substream; struct snd_soc_dai *dai; struct snd_pcm_hw_params *hw_params; int link_id; @@ -120,7 +195,7 @@ struct sdw_intel_stream_params_data { * firmware. */ struct sdw_intel_stream_free_data { - int stream; + struct snd_pcm_substream *substream; struct snd_soc_dai *dai; int link_id; }; @@ -134,7 +209,7 @@ struct sdw_intel_ops { struct sdw_intel_stream_params_data *params_data); int (*free_stream)(struct device *dev, struct sdw_intel_stream_free_data *free_data); - int (*trigger)(struct snd_soc_dai *dai, int cmd, int stream); + int (*trigger)(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai); }; /** @@ -194,6 +269,8 @@ struct sdw_intel_slave_id { struct sdw_slave_id id; }; +struct hdac_bus; + /** * struct sdw_intel_ctx - context allocated by the controller * driver probe @@ -248,6 +325,10 @@ struct sdw_intel_ctx { * DSP driver. The quirks are common for all links for now. * @shim_base: sdw shim base. * @alh_base: sdw alh base. + * @ext: extended HDaudio link support + * @hbus: hdac_bus pointer, needed for power management + * @eml_lock: mutex protecting shared registers in the HDaudio multi-link + * space */ struct sdw_intel_res { const struct sdw_intel_hw_ops *hw_ops; @@ -262,6 +343,9 @@ struct sdw_intel_res { u32 clock_stop_quirks; u32 shim_base; u32 alh_base; + bool ext; + struct hdac_bus *hbus; + struct mutex *eml_lock; }; /* @@ -315,6 +399,7 @@ struct sdw_intel; * @sync_go: helper for multi-link synchronization * @sync_check_cmdsync_unlocked: helper for multi-link synchronization * and bank switch - shim_lock is assumed to be locked at higher level + * @program_sdi: helper for codec command/control based on dev_num */ struct sdw_intel_hw_ops { void (*debugfs_init)(struct sdw_intel *sdw); @@ -341,8 +426,11 @@ struct sdw_intel_hw_ops { int (*sync_go_unlocked)(struct sdw_intel *sdw); int (*sync_go)(struct sdw_intel *sdw); bool (*sync_check_cmdsync_unlocked)(struct sdw_intel *sdw); + + void (*program_sdi)(struct sdw_intel *sdw, int dev_num); }; extern const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops; +extern const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops; #endif diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index d424c1aadf38..a04c1c34c344 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -35,8 +35,6 @@ struct ads7846_platform_data { u16 debounce_tol; /* tolerance used for filtering */ u16 debounce_rep; /* additional consecutive good readings * required after the first two */ - int gpio_pendown; /* the GPIO used to decide the pendown - * state if get_pendown_state == NULL */ int gpio_pendown_debounce; /* platform specific debounce time for * the gpio_pendown */ int (*get_pendown_state)(void); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cfe42f8cd7a4..32c94eae8926 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1261,6 +1261,23 @@ static inline bool spi_is_bpw_supported(struct spi_device *spi, u32 bpw) return false; } +/** + * spi_controller_xfer_timeout - Compute a suitable timeout value + * @ctlr: SPI device + * @xfer: Transfer descriptor + * + * Compute a relevant timeout value for the given transfer. We derive the time + * that it would take on a single data line and take twice this amount of time + * with a minimum of 500ms to avoid false positives on loaded systems. + * + * Returns: Transfer timeout value in milliseconds. + */ +static inline unsigned int spi_controller_xfer_timeout(struct spi_controller *ctlr, + struct spi_transfer *xfer) +{ + return max(xfer->len * 8 * 2 / (xfer->speed_hz / 1000), 500U); +} + /*---------------------------------------------------------------------------*/ /* SPI transfer replacement methods which make use of spi_res */ diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index be48f1cb1878..31d3d747a9db 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -61,6 +61,7 @@ #include <linux/stringify.h> #include <linux/bottom_half.h> #include <linux/lockdep.h> +#include <linux/cleanup.h> #include <asm/barrier.h> #include <asm/mmiowb.h> @@ -502,5 +503,35 @@ int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, void free_bucket_spinlocks(spinlock_t *locks); +DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, + raw_spin_lock(_T->lock), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, + raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), + raw_spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, + raw_spin_lock_irq(_T->lock), + raw_spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, + raw_spin_lock_irqsave(_T->lock, _T->flags), + raw_spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + +DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, + spin_lock(_T->lock), + spin_unlock(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, + spin_lock_irq(_T->lock), + spin_unlock_irq(_T->lock)) + +DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + #undef __LINUX_INSIDE_SPINLOCK_H #endif /* __LINUX_SPINLOCK_H */ diff --git a/include/linux/splice.h b/include/linux/splice.h index a55179fd60fc..6c461573434d 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -38,6 +38,7 @@ struct splice_desc { struct file *file; /* file to read/write */ void *data; /* cookie */ } u; + void (*splice_eof)(struct splice_desc *sd); /* Unexpected EOF handler */ loff_t pos; /* file position */ loff_t *opos; /* sendfile: output position */ size_t num_spliced; /* number of bytes already spliced */ @@ -76,6 +77,9 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *, struct splice_pipe_desc *); extern ssize_t add_to_pipe(struct pipe_inode_info *, struct pipe_buffer *); +long vfs_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, splice_direct_actor *); extern long do_splice(struct file *in, loff_t *off_in, @@ -84,6 +88,8 @@ extern long do_splice(struct file *in, loff_t *off_in, extern long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags); +extern ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); /* * for dynamic pipe sizing diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 41c4b26fb1c1..127ef3b2e607 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -212,7 +212,7 @@ static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp) srcu_check_nmi_safety(ssp, false); retval = __srcu_read_lock(ssp); - srcu_lock_acquire(&(ssp)->dep_map); + srcu_lock_acquire(&ssp->dep_map); return retval; } @@ -229,7 +229,7 @@ static inline int srcu_read_lock_nmisafe(struct srcu_struct *ssp) __acquires(ssp srcu_check_nmi_safety(ssp, true); retval = __srcu_read_lock_nmisafe(ssp); - rcu_lock_acquire(&(ssp)->dep_map); + rcu_lock_acquire(&ssp->dep_map); return retval; } @@ -284,7 +284,7 @@ static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx) { WARN_ON_ONCE(idx & ~0x1); srcu_check_nmi_safety(ssp, false); - srcu_lock_release(&(ssp)->dep_map); + srcu_lock_release(&ssp->dep_map); __srcu_read_unlock(ssp, idx); } @@ -300,7 +300,7 @@ static inline void srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx) { WARN_ON_ONCE(idx & ~0x1); srcu_check_nmi_safety(ssp, true); - rcu_lock_release(&(ssp)->dep_map); + rcu_lock_release(&ssp->dep_map); __srcu_read_unlock_nmisafe(ssp, idx); } @@ -343,4 +343,9 @@ static inline void smp_mb__after_srcu_read_unlock(void) /* __srcu_read_unlock has smp_mb() internally so nothing to do here. */ } +DEFINE_LOCK_GUARD_1(srcu, struct srcu_struct, + _T->idx = srcu_read_lock(_T->lock), + srcu_read_unlock(_T->lock, _T->idx), + int idx) + #endif diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 225751a8fd8e..06090538fe2d 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -293,5 +293,6 @@ struct plat_stmmacenet_data { bool sph_disable; bool serdes_up_after_phy_linkup; const struct dwmac4_addrs *dwmac4_addrs; + bool has_integrated_pcs; }; #endif diff --git a/include/linux/string.h b/include/linux/string.h index c062c581a98b..dbfc66400050 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -169,7 +169,7 @@ static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt) #endif void *memchr_inv(const void *s, int c, size_t n); -char *strreplace(char *s, char old, char new); +char *strreplace(char *str, char old, char new); extern void kfree_const(const void *x); diff --git a/include/linux/string_choices.h b/include/linux/string_choices.h new file mode 100644 index 000000000000..48120222b9b2 --- /dev/null +++ b/include/linux/string_choices.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_STRING_CHOICES_H_ +#define _LINUX_STRING_CHOICES_H_ + +#include <linux/types.h> + +static inline const char *str_enable_disable(bool v) +{ + return v ? "enable" : "disable"; +} + +static inline const char *str_enabled_disabled(bool v) +{ + return v ? "enabled" : "disabled"; +} + +static inline const char *str_hi_lo(bool v) +{ + return v ? "hi" : "lo"; +} +#define str_lo_hi(v) str_hi_lo(!(v)) + +static inline const char *str_high_low(bool v) +{ + return v ? "high" : "low"; +} +#define str_low_high(v) str_high_low(!(v)) + +static inline const char *str_read_write(bool v) +{ + return v ? "read" : "write"; +} + +static inline const char *str_on_off(bool v) +{ + return v ? "on" : "off"; +} + +static inline const char *str_yes_no(bool v) +{ + return v ? "yes" : "no"; +} + +#endif diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index fae6beaaa217..789ab30045da 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -4,6 +4,7 @@ #include <linux/bits.h> #include <linux/ctype.h> +#include <linux/string_choices.h> #include <linux/string.h> #include <linux/types.h> @@ -113,29 +114,4 @@ void kfree_strarray(char **array, size_t n); char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n); -static inline const char *str_yes_no(bool v) -{ - return v ? "yes" : "no"; -} - -static inline const char *str_on_off(bool v) -{ - return v ? "on" : "off"; -} - -static inline const char *str_enable_disable(bool v) -{ - return v ? "enable" : "disable"; -} - -static inline const char *str_enabled_disabled(bool v) -{ - return v ? "enabled" : "disabled"; -} - -static inline const char *str_read_write(bool v) -{ - return v ? "read" : "write"; -} - #endif diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 3e6ce288a7fc..61e58327b1aa 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -120,6 +120,7 @@ struct rpc_authops { struct rpcsec_gss_info *); int (*key_timeout)(struct rpc_auth *, struct rpc_cred *); + int (*ping)(struct rpc_clnt *clnt); }; struct rpc_credops { @@ -144,6 +145,7 @@ struct rpc_credops { extern const struct rpc_authops authunix_ops; extern const struct rpc_authops authnull_ops; +extern const struct rpc_authops authtls_ops; int __init rpc_init_authunix(void); int __init rpcauth_init_module(void); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 770ef2cb5775..4f41d839face 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -30,7 +30,13 @@ #include <linux/sunrpc/xprtmultipath.h> struct rpc_inode; -struct rpc_sysfs_client; +struct rpc_sysfs_client { + struct kobject kobject; + struct net *net; + struct rpc_clnt *clnt; + struct rpc_xprt_switch *xprt_switch; +}; + /* * The high-level client handle @@ -57,7 +63,9 @@ struct rpc_clnt { cl_discrtry : 1,/* disconnect before retry */ cl_noretranstimeo: 1,/* No retransmit timeouts */ cl_autobind : 1,/* use getport() */ - cl_chatty : 1;/* be verbose */ + cl_chatty : 1,/* be verbose */ + cl_shutdown : 1;/* rpc immediate -EIO */ + struct xprtsec_parms cl_xprtsec; /* transport security policy */ struct rpc_rtt * cl_rtt; /* RTO estimator data */ const struct rpc_timeout *cl_timeout; /* Timeout strategy */ @@ -139,6 +147,7 @@ struct rpc_create_args { struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ const struct cred *cred; unsigned int max_connect; + struct xprtsec_parms xprtsec; }; struct rpc_add_xprt_test { diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 762d7231e574..f8751118c122 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -161,16 +161,15 @@ static inline bool svc_put_not_last(struct svc_serv *serv) extern u32 svc_max_payload(const struct svc_rqst *rqstp); /* - * RPC Requsts and replies are stored in one or more pages. + * RPC Requests and replies are stored in one or more pages. * We maintain an array of pages for each server thread. * Requests are copied into these pages as they arrive. Remaining * pages are available to write the reply into. * - * Pages are sent using ->sendpage so each server thread needs to - * allocate more to replace those used in sending. To help keep track - * of these pages we have a receive list where all pages initialy live, - * and a send list where pages are moved to when there are to be part - * of a reply. + * Pages are sent using ->sendmsg with MSG_SPLICE_PAGES so each server thread + * needs to allocate more to replace those used in sending. To help keep track + * of these pages we have a receive list where all pages initialy live, and a + * send list where pages are moved to when there are to be part of a reply. * * We use xdr_buf for holding responses as it fits well with NFS * read responses (that have a header, and some data pages, and possibly @@ -223,7 +222,7 @@ struct svc_rqst { struct page * *rq_next_page; /* next reply page to use */ struct page * *rq_page_end; /* one past the last page */ - struct pagevec rq_pvec; + struct folio_batch rq_fbatch; struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ struct bio_vec rq_bvec[RPCSVC_MAXPAGES]; @@ -509,6 +508,27 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp) } /** + * svcxdr_encode_opaque_pages - Insert pages into an xdr_stream + * @xdr: xdr_stream to be updated + * @pages: array of pages to insert + * @base: starting offset of first data byte in @pages + * @len: number of data bytes in @pages to insert + * + * After the @pages are added, the tail iovec is instantiated pointing + * to end of the head buffer, and the stream is set up to encode + * subsequent items into the tail. + */ +static inline void svcxdr_encode_opaque_pages(struct svc_rqst *rqstp, + struct xdr_stream *xdr, + struct page **pages, + unsigned int base, + unsigned int len) +{ + xdr_write_pages(xdr, pages, base, len); + xdr->page_ptr = rqstp->rq_next_page - 1; +} + +/** * svcxdr_set_auth_slack - * @rqstp: RPC transaction * @slack: buffer space to reserve for the transaction's security flavor diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 24aa159d29a7..a5ee0af2a310 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -135,7 +135,6 @@ struct svc_rdma_recv_ctxt { struct ib_sge rc_recv_sge; void *rc_recv_buf; struct xdr_stream rc_stream; - bool rc_temp; u32 rc_byte_len; unsigned int rc_page_count; u32 rc_inv_rkey; @@ -155,12 +154,12 @@ struct svc_rdma_send_ctxt { struct ib_send_wr sc_send_wr; struct ib_cqe sc_cqe; - struct completion sc_done; struct xdr_buf sc_hdrbuf; struct xdr_stream sc_stream; void *sc_xprt_buf; + int sc_page_count; int sc_cur_sge_no; - + struct page *sc_pages[RPCSVC_MAXPAGES]; struct ib_sge sc_sges[]; }; @@ -176,7 +175,7 @@ extern struct svc_rdma_recv_ctxt * extern void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma, struct svc_rdma_recv_ctxt *ctxt); extern void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma); -extern void svc_rdma_release_rqst(struct svc_rqst *rqstp); +extern void svc_rdma_release_ctxt(struct svc_xprt *xprt, void *ctxt); extern int svc_rdma_recvfrom(struct svc_rqst *); /* svc_rdma_rw.c */ diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 867479204840..a6b12631db21 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -23,7 +23,7 @@ struct svc_xprt_ops { int (*xpo_sendto)(struct svc_rqst *); int (*xpo_result_payload)(struct svc_rqst *, unsigned int, unsigned int); - void (*xpo_release_rqst)(struct svc_rqst *); + void (*xpo_release_ctxt)(struct svc_xprt *xprt, void *ctxt); void (*xpo_detach)(struct svc_xprt *); void (*xpo_free)(struct svc_xprt *); void (*xpo_kill_temp_xprt)(struct svc_xprt *); diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index d16ae621782c..a7116048a4d4 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -61,10 +61,9 @@ int svc_recv(struct svc_rqst *, long); void svc_send(struct svc_rqst *rqstp); void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); -bool svc_alien_sock(struct net *net, int fd); -int svc_addsock(struct svc_serv *serv, const int fd, - char *name_return, const size_t len, - const struct cred *cred); +int svc_addsock(struct svc_serv *serv, struct net *net, + const int fd, char *name_return, const size_t len, + const struct cred *cred); void svc_init_xprt_sock(void); void svc_cleanup_xprt_sock(void); struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot); diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 72014c9216fc..f89ec4b5ea16 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -242,8 +242,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, struct page **pages, struct rpc_rqst *rqst); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); -extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, - size_t nbytes); +extern int xdr_reserve_space_vec(struct xdr_stream *xdr, size_t nbytes); extern void __xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); extern void xdr_truncate_decode(struct xdr_stream *xdr, size_t len); diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index b9f59aabee53..b52411bcfe4e 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -129,6 +129,21 @@ struct rpc_rqst { #define rq_svec rq_snd_buf.head #define rq_slen rq_snd_buf.len +/* RPC transport layer security policies */ +enum xprtsec_policies { + RPC_XPRTSEC_NONE = 0, + RPC_XPRTSEC_TLS_ANON, + RPC_XPRTSEC_TLS_X509, +}; + +struct xprtsec_parms { + enum xprtsec_policies policy; + + /* authentication material */ + key_serial_t cert_serial; + key_serial_t privkey_serial; +}; + struct rpc_xprt_ops { void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); int (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); @@ -185,6 +200,7 @@ enum xprt_transports { XPRT_TRANSPORT_RDMA = 256, XPRT_TRANSPORT_BC_RDMA = XPRT_TRANSPORT_RDMA | XPRT_TRANSPORT_BC, XPRT_TRANSPORT_LOCAL = 257, + XPRT_TRANSPORT_TCP_TLS = 258, }; struct rpc_sysfs_xprt; @@ -229,6 +245,7 @@ struct rpc_xprt { */ unsigned long bind_timeout, reestablish_timeout; + struct xprtsec_parms xprtsec; unsigned int connect_cookie; /* A cookie that gets bumped every time the transport is reconnected */ @@ -333,6 +350,7 @@ struct xprt_create { struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ struct rpc_xprt_switch *bc_xps; unsigned int flags; + struct xprtsec_parms xprtsec; }; struct xprt_class { diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index 38284f25eddf..700a1e6c047c 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h @@ -57,9 +57,11 @@ struct sock_xprt { struct work_struct error_worker; struct work_struct recv_worker; struct mutex recv_mutex; + struct completion handshake_done; struct sockaddr_storage srcaddr; unsigned short srcport; int xprt_err; + struct rpc_clnt *clnt; /* * UDP socket buffer size parameters @@ -90,5 +92,6 @@ struct sock_xprt { #define XPRT_SOCK_WAKE_DISCONNECT (7) #define XPRT_SOCK_CONNECT_SENT (8) #define XPRT_SOCK_NOSPACE (9) +#define XPRT_SOCK_IGNORE_RECV (10) #endif /* _LINUX_SUNRPC_XPRTSOCK_H */ diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h index df81043b9e71..42b249b4c24b 100644 --- a/include/linux/surface_aggregator/device.h +++ b/include/linux/surface_aggregator/device.h @@ -243,11 +243,7 @@ static inline bool is_ssam_device(struct device *d) * Return: Returns the pointer to the &struct ssam_device_driver wrapping the * given device driver @d. */ -static inline -struct ssam_device_driver *to_ssam_device_driver(struct device_driver *d) -{ - return container_of(d, struct ssam_device_driver, driver); -} +#define to_ssam_device_driver(d) container_of_const(d, struct ssam_device_driver, driver) const struct ssam_device_id *ssam_device_id_match(const struct ssam_device_id *table, const struct ssam_device_uid uid); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index d0d4598a7b3f..ef503088942d 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -202,6 +202,7 @@ struct platform_s2idle_ops { }; #ifdef CONFIG_SUSPEND +extern suspend_state_t pm_suspend_target_state; extern suspend_state_t mem_sleep_current; extern suspend_state_t mem_sleep_default; @@ -337,6 +338,8 @@ extern bool sync_on_suspend_enabled; #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL +#define pm_suspend_target_state (PM_SUSPEND_ON) + static inline void pm_suspend_clear_flags(void) {} static inline void pm_set_suspend_via_firmware(void) {} static inline void pm_set_resume_via_firmware(void) {} @@ -364,9 +367,6 @@ struct pbe { struct pbe *next; }; -/* mm/page_alloc.c */ -extern void mark_free_pages(struct zone *zone); - /** * struct platform_hibernation_ops - hibernation platform support * @@ -452,6 +452,10 @@ extern struct pbe *restore_pblist; int pfn_is_nosave(unsigned long pfn); int hibernate_quiet_exec(int (*func)(void *data), void *data); +int hibernate_resume_nonboot_cpu_disable(void); +int arch_hibernation_header_save(void *addr, unsigned int max_size); +int arch_hibernation_header_restore(void *addr); + #else /* CONFIG_HIBERNATION */ static inline void register_nosave_region(unsigned long b, unsigned long e) {} static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } @@ -468,6 +472,8 @@ static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { } #endif /* CONFIG_HIBERNATION */ +int arch_resume_nosmt(void); + #ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV int is_hibernate_resume_dev(dev_t dev); #else @@ -503,7 +509,11 @@ extern void pm_report_max_hw_sleep(u64 t); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; -extern suspend_state_t pm_suspend_target_state; + +static inline bool pm_suspended_storage(void) +{ + return !gfp_has_io_fs(gfp_allowed_mask); +} extern bool pm_wakeup_pending(void); extern void pm_system_wakeup(void); @@ -538,6 +548,7 @@ static inline void ksys_sync_helper(void) {} #define pm_notifier(fn, pri) do { (void)(fn); } while (0) +static inline bool pm_suspended_storage(void) { return false; } static inline bool pm_wakeup_pending(void) { return false; } static inline void pm_system_wakeup(void) {} static inline void pm_wakeup_clear(bool reset) {} @@ -551,6 +562,7 @@ static inline void unlock_system_sleep(unsigned int flags) {} #ifdef CONFIG_PM_SLEEP_DEBUG extern bool pm_print_times_enabled; extern bool pm_debug_messages_on; +extern bool pm_debug_messages_should_print(void); static inline int pm_dyn_debug_messages_on(void) { #ifdef CONFIG_DYNAMIC_DEBUG @@ -564,14 +576,14 @@ static inline int pm_dyn_debug_messages_on(void) #endif #define __pm_pr_dbg(fmt, ...) \ do { \ - if (pm_debug_messages_on) \ + if (pm_debug_messages_should_print()) \ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ else if (pm_dyn_debug_messages_on()) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define __pm_deferred_pr_dbg(fmt, ...) \ do { \ - if (pm_debug_messages_on) \ + if (pm_debug_messages_should_print()) \ printk_deferred(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) #else @@ -589,7 +601,8 @@ static inline int pm_dyn_debug_messages_on(void) /** * pm_pr_dbg - print pm sleep debug messages * - * If pm_debug_messages_on is enabled, print message. + * If pm_debug_messages_on is enabled and the system is entering/leaving + * suspend, print message. * If pm_debug_messages_on is disabled and CONFIG_DYNAMIC_DEBUG is enabled, * print message only from instances explicitly enabled on dynamic debug's * control. diff --git a/include/linux/swap.h b/include/linux/swap.h index 3c69cb653cb9..456546443f1f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -337,25 +337,6 @@ struct swap_info_struct { */ }; -#ifdef CONFIG_64BIT -#define SWAP_RA_ORDER_CEILING 5 -#else -/* Avoid stack overflow, because we need to save part of page table */ -#define SWAP_RA_ORDER_CEILING 3 -#define SWAP_RA_PTE_CACHE_SIZE (1 << SWAP_RA_ORDER_CEILING) -#endif - -struct vma_swap_readahead { - unsigned short win; - unsigned short offset; - unsigned short nr_pte; -#ifdef CONFIG_64BIT - pte_t *ptes; -#else - pte_t ptes[SWAP_RA_PTE_CACHE_SIZE]; -#endif -}; - static inline swp_entry_t folio_swap_entry(struct folio *folio) { swp_entry_t entry = { .val = page_private(&folio->page) }; @@ -368,6 +349,7 @@ static inline void folio_set_swap_entry(struct folio *folio, swp_entry_t entry) } /* linux/mm/workingset.c */ +bool workingset_test_recent(void *shadow, bool file, bool *workingset); void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages); void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg); void workingset_refault(struct folio *folio, void *shadow); @@ -457,10 +439,9 @@ static inline bool node_reclaim_enabled(void) } void check_move_unevictable_folios(struct folio_batch *fbatch); -void check_move_unevictable_pages(struct pagevec *pvec); -extern void kswapd_run(int nid); -extern void kswapd_stop(int nid); +extern void __meminit kswapd_run(int nid); +extern void __meminit kswapd_stop(int nid); #ifdef CONFIG_SWAP @@ -512,7 +493,7 @@ int find_first_swap(dev_t *device); extern unsigned int count_swap_pages(int, int); extern sector_t swapdev_block(int, pgoff_t); extern int __swap_count(swp_entry_t entry); -extern int __swp_swapcount(swp_entry_t entry); +extern int swap_swapcount(struct swap_info_struct *si, swp_entry_t entry); extern int swp_swapcount(swp_entry_t entry); extern struct swap_info_struct *page_swap_info(struct page *); extern struct swap_info_struct *swp_swap_info(swp_entry_t entry); @@ -590,7 +571,7 @@ static inline int __swap_count(swp_entry_t entry) return 0; } -static inline int __swp_swapcount(swp_entry_t entry) +static inline int swap_swapcount(struct swap_info_struct *si, swp_entry_t entry) { return 0; } diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 3a451b7afcb3..4c932cb45e0b 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -332,15 +332,9 @@ static inline bool is_migration_entry_dirty(swp_entry_t entry) return false; } -extern void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, - spinlock_t *ptl); extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address); -#ifdef CONFIG_HUGETLB_PAGE -extern void __migration_entry_wait_huge(struct vm_area_struct *vma, - pte_t *ptep, spinlock_t *ptl); extern void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte); -#endif /* CONFIG_HUGETLB_PAGE */ #else /* CONFIG_MIGRATION */ static inline swp_entry_t make_readable_migration_entry(pgoff_t offset) { @@ -362,15 +356,10 @@ static inline int is_migration_entry(swp_entry_t swp) return 0; } -static inline void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep, - spinlock_t *ptl) { } static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, - unsigned long address) { } -#ifdef CONFIG_HUGETLB_PAGE -static inline void __migration_entry_wait_huge(struct vm_area_struct *vma, - pte_t *ptep, spinlock_t *ptl) { } -static inline void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) { } -#endif /* CONFIG_HUGETLB_PAGE */ + unsigned long address) { } +static inline void migration_entry_wait_huge(struct vm_area_struct *vma, + pte_t *pte) { } static inline int is_writable_migration_entry(swp_entry_t entry) { return 0; diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 7af2673b47ba..4e52cd5e0bdc 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -76,7 +76,6 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys, * @nslabs: The number of IO TLB blocks (in groups of 64) between @start and * @end. For default swiotlb, this is command line adjustable via * setup_io_tlb_npages. - * @used: The number of used IO TLB block. * @list: The free list describing the number of free entries available * from each index. * @orig_addr: The original address corresponding to a mapped entry. @@ -98,7 +97,6 @@ struct io_tlb_mem { phys_addr_t end; void *vaddr; unsigned long nslabs; - unsigned long used; struct dentry *debugfs; bool late_alloc; bool force_bounce; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 33a0ee3bcb2e..d18ce144037e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -72,6 +72,8 @@ struct open_how; struct mount_attr; struct landlock_ruleset_attr; enum landlock_rule_type; +struct cachestat_range; +struct cachestat; #include <linux/types.h> #include <linux/aio_abi.h> @@ -1058,6 +1060,9 @@ asmlinkage long sys_memfd_secret(unsigned int flags); asmlinkage long sys_set_mempolicy_home_node(unsigned long start, unsigned long len, unsigned long home_node, unsigned long flags); +asmlinkage long sys_cachestat(unsigned int fd, + struct cachestat_range __user *cstat_range, + struct cachestat __user *cstat, unsigned int flags); /* * Architecture-specific system calls @@ -1280,6 +1285,7 @@ asmlinkage long sys_ni_syscall(void); #endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */ +asmlinkage long sys_ni_posix_timers(void); /* * Kernel code should not call syscalls (i.e., sys_xyzyyz()) directly. diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 3d08277959af..59d451f455bf 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -89,7 +89,7 @@ int proc_do_static_key(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); /* - * Register a set of sysctl names by calling register_sysctl_table + * Register a set of sysctl names by calling register_sysctl * with an initialised array of struct ctl_table's. An entry with * NULL procname terminates the table. table->de will be * set up by the registration and need not be initialised in advance. @@ -137,7 +137,17 @@ struct ctl_table { void *data; int maxlen; umode_t mode; - struct ctl_table *child; /* Deprecated */ + /** + * enum type - Enumeration to differentiate between ctl target types + * @SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations + * @SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Used to identify a permanently + * empty directory target to serve + * as mount point. + */ + enum { + SYSCTL_TABLE_TYPE_DEFAULT, + SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY + } type; proc_handler *proc_handler; /* Callback for text formatting */ struct ctl_table_poll *poll; void *extra1; @@ -197,20 +207,6 @@ struct ctl_path { #ifdef CONFIG_SYSCTL -#define DECLARE_SYSCTL_BASE(_name, _table) \ -static struct ctl_table _name##_base_table[] = { \ - { \ - .procname = #_name, \ - .mode = 0555, \ - .child = _table, \ - }, \ - { }, \ -} - -extern int __register_sysctl_base(struct ctl_table *base_table); - -#define register_sysctl_base(_name) __register_sysctl_base(_name##_base_table) - void proc_sys_poll_notify(struct ctl_table_poll *poll); extern void setup_sysctl_set(struct ctl_table_set *p, @@ -222,7 +218,6 @@ struct ctl_table_header *__register_sysctl_table( struct ctl_table_set *set, const char *path, struct ctl_table *table); struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table); -struct ctl_table_header *register_sysctl_table(struct ctl_table * table); void unregister_sysctl_table(struct ctl_table_header * table); extern int sysctl_init_bases(void); @@ -244,24 +239,10 @@ extern int unaligned_enabled; extern int unaligned_dump_stack; extern int no_unaligned_warning; -extern struct ctl_table sysctl_mount_point[]; +#define SYSCTL_PERM_EMPTY_DIR (1 << 0) #else /* CONFIG_SYSCTL */ -#define DECLARE_SYSCTL_BASE(_name, _table) - -static inline int __register_sysctl_base(struct ctl_table *base_table) -{ - return 0; -} - -#define register_sysctl_base(table) __register_sysctl_base(table) - -static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table) -{ - return NULL; -} - static inline void register_sysctl_init(const char *path, struct ctl_table *table) { } diff --git a/include/linux/tegra-icc.h b/include/linux/tegra-icc.h new file mode 100644 index 000000000000..4b4d4bee290c --- /dev/null +++ b/include/linux/tegra-icc.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2022-2023 NVIDIA CORPORATION. All rights reserved. + */ + +#ifndef LINUX_TEGRA_ICC_H +#define LINUX_TEGRA_ICC_H + +enum tegra_icc_client_type { + TEGRA_ICC_NONE, + TEGRA_ICC_NISO, + TEGRA_ICC_ISO_DISPLAY, + TEGRA_ICC_ISO_VI, + TEGRA_ICC_ISO_AUDIO, + TEGRA_ICC_ISO_VIFAL, +}; + +/* ICC ID's for MC client's used in BPMP */ +#define TEGRA_ICC_BPMP_DEBUG 1 +#define TEGRA_ICC_BPMP_CPU_CLUSTER0 2 +#define TEGRA_ICC_BPMP_CPU_CLUSTER1 3 +#define TEGRA_ICC_BPMP_CPU_CLUSTER2 4 +#define TEGRA_ICC_BPMP_GPU 5 +#define TEGRA_ICC_BPMP_CACTMON 6 +#define TEGRA_ICC_BPMP_DISPLAY 7 +#define TEGRA_ICC_BPMP_VI 8 +#define TEGRA_ICC_BPMP_EQOS 9 +#define TEGRA_ICC_BPMP_PCIE_0 10 +#define TEGRA_ICC_BPMP_PCIE_1 11 +#define TEGRA_ICC_BPMP_PCIE_2 12 +#define TEGRA_ICC_BPMP_PCIE_3 13 +#define TEGRA_ICC_BPMP_PCIE_4 14 +#define TEGRA_ICC_BPMP_PCIE_5 15 +#define TEGRA_ICC_BPMP_PCIE_6 16 +#define TEGRA_ICC_BPMP_PCIE_7 17 +#define TEGRA_ICC_BPMP_PCIE_8 18 +#define TEGRA_ICC_BPMP_PCIE_9 19 +#define TEGRA_ICC_BPMP_PCIE_10 20 +#define TEGRA_ICC_BPMP_DLA_0 21 +#define TEGRA_ICC_BPMP_DLA_1 22 +#define TEGRA_ICC_BPMP_SDMMC_1 23 +#define TEGRA_ICC_BPMP_SDMMC_2 24 +#define TEGRA_ICC_BPMP_SDMMC_3 25 +#define TEGRA_ICC_BPMP_SDMMC_4 26 +#define TEGRA_ICC_BPMP_NVDEC 27 +#define TEGRA_ICC_BPMP_NVENC 28 +#define TEGRA_ICC_BPMP_NVJPG_0 29 +#define TEGRA_ICC_BPMP_NVJPG_1 30 +#define TEGRA_ICC_BPMP_OFAA 31 +#define TEGRA_ICC_BPMP_XUSB_HOST 32 +#define TEGRA_ICC_BPMP_XUSB_DEV 33 +#define TEGRA_ICC_BPMP_TSEC 34 +#define TEGRA_ICC_BPMP_VIC 35 +#define TEGRA_ICC_BPMP_APE 36 +#define TEGRA_ICC_BPMP_APEDMA 37 +#define TEGRA_ICC_BPMP_SE 38 +#define TEGRA_ICC_BPMP_ISP 39 +#define TEGRA_ICC_BPMP_HDA 40 +#define TEGRA_ICC_BPMP_VIFAL 41 +#define TEGRA_ICC_BPMP_VI2FAL 42 +#define TEGRA_ICC_BPMP_VI2 43 +#define TEGRA_ICC_BPMP_RCE 44 +#define TEGRA_ICC_BPMP_PVA 45 + +#endif /* LINUX_TEGRA_ICC_H */ diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index c02646884fa8..9ea0b28068f4 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -256,6 +256,11 @@ check_copy_size(const void *addr, size_t bytes, bool is_source) static inline void arch_setup_new_exec(void) { } #endif +void arch_task_cache_init(void); /* for CONFIG_SH */ +void arch_release_task_struct(struct task_struct *tsk); +int arch_dup_task_struct(struct task_struct *dst, + struct task_struct *src); + #endif /* __KERNEL__ */ #endif /* _LINUX_THREAD_INFO_H */ diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h index 90cd08ab2f5d..02333f47c994 100644 --- a/include/linux/thunderbolt.h +++ b/include/linux/thunderbolt.h @@ -172,6 +172,20 @@ int tb_register_property_dir(const char *key, struct tb_property_dir *dir); void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir); /** + * enum tb_link_width - Thunderbolt/USB4 link width + * @TB_LINK_WIDTH_SINGLE: Single lane link + * @TB_LINK_WIDTH_DUAL: Dual lane symmetric link + * @TB_LINK_WIDTH_ASYM_TX: Dual lane asymmetric Gen 4 link with 3 trasmitters + * @TB_LINK_WIDTH_ASYM_RX: Dual lane asymmetric Gen 4 link with 3 receivers + */ +enum tb_link_width { + TB_LINK_WIDTH_SINGLE = BIT(0), + TB_LINK_WIDTH_DUAL = BIT(1), + TB_LINK_WIDTH_ASYM_TX = BIT(2), + TB_LINK_WIDTH_ASYM_RX = BIT(3), +}; + +/** * struct tb_xdomain - Cross-domain (XDomain) connection * @dev: XDomain device * @tb: Pointer to the domain @@ -186,7 +200,7 @@ void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir); * @vendor_name: Name of the vendor (or %NULL if not known) * @device_name: Name of the device (or %NULL if not known) * @link_speed: Speed of the link in Gb/s - * @link_width: Width of the link (1 or 2) + * @link_width: Width of the downstream facing link * @link_usb4: Downstream link is USB4 * @is_unplugged: The XDomain is unplugged * @needs_uuid: If the XDomain does not have @remote_uuid it will be @@ -234,7 +248,7 @@ struct tb_xdomain { const char *vendor_name; const char *device_name; unsigned int link_speed; - unsigned int link_width; + enum tb_link_width link_width; bool link_usb4; bool is_unplugged; bool needs_uuid; diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h index bb9d3f5542f8..03d9c5ac01d1 100644 --- a/include/linux/time_namespace.h +++ b/include/linux/time_namespace.h @@ -44,7 +44,6 @@ struct time_namespace *copy_time_ns(unsigned long flags, struct time_namespace *old_ns); void free_time_ns(struct time_namespace *ns); void timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk); -struct vdso_data *arch_get_vdso_data(void *vvar_page); struct page *find_timens_vvar_page(struct vm_area_struct *vma); static inline void put_time_ns(struct time_namespace *ns) @@ -163,4 +162,6 @@ static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim) } #endif +struct vdso_data *arch_get_vdso_data(void *vvar_page); + #endif /* _LINUX_TIMENS_H */ diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 77693389c3f9..6a1e8f157255 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -282,6 +282,7 @@ enum tpm_chip_flags { TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), TPM_CHIP_FLAG_FIRMWARE_UPGRADE = BIT(7), + TPM_CHIP_FLAG_SUSPENDED = BIT(8), }; #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 0e373222a6df..3930e676436c 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -318,6 +318,7 @@ enum { TRACE_EVENT_FL_KPROBE_BIT, TRACE_EVENT_FL_UPROBE_BIT, TRACE_EVENT_FL_EPROBE_BIT, + TRACE_EVENT_FL_FPROBE_BIT, TRACE_EVENT_FL_CUSTOM_BIT, }; @@ -332,6 +333,7 @@ enum { * KPROBE - Event is a kprobe * UPROBE - Event is a uprobe * EPROBE - Event is an event probe + * FPROBE - Event is an function probe * CUSTOM - Event is a custom event (to be attached to an exsiting tracepoint) * This is set when the custom event has not been attached * to a tracepoint yet, then it is cleared when it is. @@ -346,6 +348,7 @@ enum { TRACE_EVENT_FL_KPROBE = (1 << TRACE_EVENT_FL_KPROBE_BIT), TRACE_EVENT_FL_UPROBE = (1 << TRACE_EVENT_FL_UPROBE_BIT), TRACE_EVENT_FL_EPROBE = (1 << TRACE_EVENT_FL_EPROBE_BIT), + TRACE_EVENT_FL_FPROBE = (1 << TRACE_EVENT_FL_FPROBE_BIT), TRACE_EVENT_FL_CUSTOM = (1 << TRACE_EVENT_FL_CUSTOM_BIT), }; @@ -806,6 +809,7 @@ enum { FILTER_TRACE_FN, FILTER_COMM, FILTER_CPU, + FILTER_STACKTRACE, }; extern int trace_event_raw_init(struct trace_event_call *call); diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h index e7c2276be33e..4dc4955f0fbf 100644 --- a/include/linux/tracepoint-defs.h +++ b/include/linux/tracepoint-defs.h @@ -35,6 +35,7 @@ struct tracepoint { struct static_call_key *static_call_key; void *static_call_tramp; void *iterator; + void *probestub; int (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 6811e43c1b5c..88c0ba623ee6 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -303,6 +303,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) __section("__tracepoints_strings") = #_name; \ extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \ int __traceiter_##_name(void *__data, proto); \ + void __probestub_##_name(void *__data, proto); \ struct tracepoint __tracepoint_##_name __used \ __section("__tracepoints") = { \ .name = __tpstrtab_##_name, \ @@ -310,6 +311,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) .static_call_key = &STATIC_CALL_KEY(tp_func_##_name), \ .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \ .iterator = &__traceiter_##_name, \ + .probestub = &__probestub_##_name, \ .regfunc = _reg, \ .unregfunc = _unreg, \ .funcs = NULL }; \ @@ -330,6 +332,9 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) } \ return 0; \ } \ + void __probestub_##_name(void *__data, proto) \ + { \ + } \ DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); #define DEFINE_TRACE(name, proto, args) \ diff --git a/include/linux/types.h b/include/linux/types.h index 688fb943556a..253168bb3fe1 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -10,6 +10,11 @@ #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] +#ifdef __SIZEOF_INT128__ +typedef __s128 s128; +typedef __u128 u128; +#endif + typedef u32 __kernel_dev_t; typedef __kernel_fd_set fd_set; @@ -35,6 +40,7 @@ typedef __kernel_uid16_t uid16_t; typedef __kernel_gid16_t gid16_t; typedef unsigned long uintptr_t; +typedef long intptr_t; #ifdef CONFIG_HAVE_UID16 /* This is defined by include/asm-{arch}/posix_types.h */ diff --git a/include/linux/uacce.h b/include/linux/uacce.h index 0a81c3dfd26c..e290c0269944 100644 --- a/include/linux/uacce.h +++ b/include/linux/uacce.h @@ -86,6 +86,7 @@ enum uacce_q_state { * @state: queue state machine * @pasid: pasid associated to the mm * @handle: iommu_sva handle returned by iommu_sva_bind_device() + * @mapping: user space mapping of the queue */ struct uacce_queue { struct uacce_device *uacce; @@ -97,6 +98,7 @@ struct uacce_queue { enum uacce_q_state state; u32 pasid; struct iommu_sva *handle; + struct address_space *mapping; }; /** @@ -114,7 +116,6 @@ struct uacce_queue { * @mutex: protects uacce operation * @priv: private pointer of the uacce * @queues: list of queues - * @inode: core vfs */ struct uacce_device { const char *algs; @@ -130,7 +131,6 @@ struct uacce_device { struct mutex mutex; void *priv; struct list_head queues; - struct inode *inode; }; #if IS_ENABLED(CONFIG_UACCE) diff --git a/include/linux/uio.h b/include/linux/uio.h index 044c1d8c230c..ff81e5ccaef2 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -11,7 +11,6 @@ #include <uapi/linux/uio.h> struct page; -struct pipe_inode_info; typedef unsigned int __bitwise iov_iter_extraction_t; @@ -25,7 +24,6 @@ enum iter_type { ITER_IOVEC, ITER_KVEC, ITER_BVEC, - ITER_PIPE, ITER_XARRAY, ITER_DISCARD, ITER_UBUF, @@ -74,7 +72,6 @@ struct iov_iter { const struct kvec *kvec; const struct bio_vec *bvec; struct xarray *xarray; - struct pipe_inode_info *pipe; void __user *ubuf; }; size_t count; @@ -82,10 +79,6 @@ struct iov_iter { }; union { unsigned long nr_segs; - struct { - unsigned int head; - unsigned int start_head; - }; loff_t xarray_start; }; }; @@ -133,11 +126,6 @@ static inline bool iov_iter_is_bvec(const struct iov_iter *i) return iov_iter_type(i) == ITER_BVEC; } -static inline bool iov_iter_is_pipe(const struct iov_iter *i) -{ - return iov_iter_type(i) == ITER_PIPE; -} - static inline bool iov_iter_is_discard(const struct iov_iter *i) { return iov_iter_type(i) == ITER_DISCARD; @@ -286,19 +274,11 @@ void iov_iter_kvec(struct iov_iter *i, unsigned int direction, const struct kvec unsigned long nr_segs, size_t count); void iov_iter_bvec(struct iov_iter *i, unsigned int direction, const struct bio_vec *bvec, unsigned long nr_segs, size_t count); -void iov_iter_pipe(struct iov_iter *i, unsigned int direction, struct pipe_inode_info *pipe, - size_t count); void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count); void iov_iter_xarray(struct iov_iter *i, unsigned int direction, struct xarray *xarray, loff_t start, size_t count); -ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, - size_t maxsize, unsigned maxpages, size_t *start, - iov_iter_extraction_t extraction_flags); ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start); -ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, - struct page ***pages, size_t maxsize, size_t *start, - iov_iter_extraction_t extraction_flags); ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i, struct page ***pages, size_t maxsize, size_t *start); int iov_iter_npages(const struct iov_iter *i, int maxpages); @@ -433,4 +413,9 @@ static inline bool iov_iter_extract_will_pin(const struct iov_iter *iter) return user_backed_iter(iter); } +struct sg_table; +ssize_t extract_iter_to_sg(struct iov_iter *iter, size_t len, + struct sg_table *sgtable, unsigned int sg_max, + iov_iter_extraction_t extraction_flags); + #endif diff --git a/include/linux/ulpi/driver.h b/include/linux/ulpi/driver.h index c7a1810373e3..a8cb617a3028 100644 --- a/include/linux/ulpi/driver.h +++ b/include/linux/ulpi/driver.h @@ -15,9 +15,9 @@ struct ulpi_ops; * @dev: device interface */ struct ulpi { + struct device dev; struct ulpi_device_id id; const struct ulpi_ops *ops; - struct device dev; }; #define to_ulpi_dev(d) container_of(d, struct ulpi, dev) diff --git a/include/linux/umh.h b/include/linux/umh.h index 5d1f6129b847..daa6a7048c11 100644 --- a/include/linux/umh.h +++ b/include/linux/umh.h @@ -42,8 +42,6 @@ call_usermodehelper_setup(const char *path, char **argv, char **envp, extern int call_usermodehelper_exec(struct subprocess_info *info, int wait); -extern struct ctl_table usermodehelper_table[]; - enum umh_disable_depth { UMH_ENABLED = 0, UMH_FREEZING, diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index a2448e98854f..07531c4f4350 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -443,7 +443,7 @@ static inline struct usb_composite_driver *to_cdriver( * @bcd_webusb_version: 0x0100 by default, WebUSB specification version * @b_webusb_vendor_code: 0x0 by default, vendor code for WebUSB * @landing_page: empty by default, landing page to announce in WebUSB - * @use_webusb:: false by default, interested gadgets set it + * @use_webusb: false by default, interested gadgets set it * @os_desc_config: the configuration to be used with OS descriptors * @setup_pending: true when setup request is queued but not completed * @os_desc_pending: true when os_desc request is queued but not completed diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 094c77eaf455..4e9623e8492b 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -267,7 +267,7 @@ struct hc_driver { int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup); /* called after entering D0 (etc), before resuming the hub */ - int (*pci_resume)(struct usb_hcd *hcd, bool hibernated); + int (*pci_resume)(struct usb_hcd *hcd, pm_message_t state); /* called just before hibernate final D3 state, allows host to poweroff parts */ int (*pci_poweroff_late)(struct usb_hcd *hcd, bool do_wakeup); @@ -501,6 +501,11 @@ void *hcd_buffer_alloc(struct usb_bus *bus, size_t size, void hcd_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); +void *hcd_buffer_alloc_pages(struct usb_hcd *hcd, + size_t size, gfp_t mem_flags, dma_addr_t *dma); +void hcd_buffer_free_pages(struct usb_hcd *hcd, + size_t size, void *addr, dma_addr_t dma); + /* generic bus glue, needed for host controllers that don't use PCI */ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); diff --git a/include/linux/usb/midi-v2.h b/include/linux/usb/midi-v2.h new file mode 100644 index 000000000000..16f09d959a2d --- /dev/null +++ b/include/linux/usb/midi-v2.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * <linux/usb/midi-v2.h> -- USB MIDI 2.0 definitions. + */ + +#ifndef __LINUX_USB_MIDI_V2_H +#define __LINUX_USB_MIDI_V2_H + +#include <linux/types.h> +#include <linux/usb/midi.h> + +/* A.1 MS Class-Specific Interface Descriptor Types */ +#define USB_DT_CS_GR_TRM_BLOCK 0x26 + +/* A.1 MS Class-Specific Interface Descriptor Subtypes */ +/* same as MIDI 1.0 */ + +/* A.2 MS Class-Specific Endpoint Descriptor Subtypes */ +#define USB_MS_GENERAL_2_0 0x02 + +/* A.3 MS Class-Specific Group Terminal Block Descriptor Subtypes */ +#define USB_MS_GR_TRM_BLOCK_UNDEFINED 0x00 +#define USB_MS_GR_TRM_BLOCK_HEADER 0x01 +#define USB_MS_GR_TRM_BLOCK 0x02 + +/* A.4 MS Interface Header MIDIStreaming Class Revision */ +#define USB_MS_REV_MIDI_1_0 0x0100 +#define USB_MS_REV_MIDI_2_0 0x0200 + +/* A.5 MS MIDI IN and OUT Jack Types */ +/* same as MIDI 1.0 */ + +/* A.6 Group Terminal Block Types */ +#define USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL 0x00 +#define USB_MS_GR_TRM_BLOCK_TYPE_INPUT_ONLY 0x01 +#define USB_MS_GR_TRM_BLOCK_TYPE_OUTPUT_ONLY 0x02 + +/* A.7 Group Terminal Default MIDI Protocol */ +#define USB_MS_MIDI_PROTO_UNKNOWN 0x00 /* Unknown (Use MIDI-CI) */ +#define USB_MS_MIDI_PROTO_1_0_64 0x01 /* MIDI 1.0, UMP up to 64bits */ +#define USB_MS_MIDI_PROTO_1_0_64_JRTS 0x02 /* MIDI 1.0, UMP up to 64bits, Jitter Reduction Timestamps */ +#define USB_MS_MIDI_PROTO_1_0_128 0x03 /* MIDI 1.0, UMP up to 128bits */ +#define USB_MS_MIDI_PROTO_1_0_128_JRTS 0x04 /* MIDI 1.0, UMP up to 128bits, Jitter Reduction Timestamps */ +#define USB_MS_MIDI_PROTO_2_0 0x11 /* MIDI 2.0 */ +#define USB_MS_MIDI_PROTO_2_0_JRTS 0x12 /* MIDI 2.0, Jitter Reduction Timestamps */ + +/* 5.2.2.1 Class-Specific MS Interface Header Descriptor */ +/* Same as MIDI 1.0, use struct usb_ms_header_descriptor */ + +/* 5.3.2 Class-Specific MIDI Streaming Data Endpoint Descriptor */ +struct usb_ms20_endpoint_descriptor { + __u8 bLength; /* 4+n */ + __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */ + __u8 bDescriptorSubtype; /* USB_MS_GENERAL_2_0 */ + __u8 bNumGrpTrmBlock; /* Number of Group Terminal Blocks: n */ + __u8 baAssoGrpTrmBlkID[]; /* ID of the Group Terminal Blocks [n] */ +} __packed; + +#define USB_DT_MS20_ENDPOINT_SIZE(n) (4 + (n)) + +/* As above, but more useful for defining your own descriptors: */ +#define DECLARE_USB_MS20_ENDPOINT_DESCRIPTOR(n) \ +struct usb_ms20_endpoint_descriptor_##n { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bNumGrpTrmBlock; \ + __u8 baAssoGrpTrmBlkID[n]; \ +} __packed + +/* 5.4.1 Class-Specific Group Terminal Block Header Descriptor */ +struct usb_ms20_gr_trm_block_header_descriptor { + __u8 bLength; /* 5 */ + __u8 bDescriptorType; /* USB_DT_CS_GR_TRM_BLOCK */ + __u8 bDescriptorSubtype; /* USB_MS_GR_TRM_BLOCK_HEADER */ + __le16 wTotalLength; /* Total number of bytes */ +} __packed; + +/* 5.4.2.1 Group Terminal Block Descriptor */ +struct usb_ms20_gr_trm_block_descriptor { + __u8 bLength; /* 13 */ + __u8 bDescriptorType; /* USB_DT_CS_GR_TRM_BLOCK */ + __u8 bDescriptorSubtype; /* USB_MS_GR_TRM_BLOCK */ + __u8 bGrpTrmBlkID; /* ID of this Group Terminal Block */ + __u8 bGrpTrmBlkType; /* Group Terminal Block Type */ + __u8 nGroupTrm; /* The first member Group Terminal in this block */ + __u8 nNumGroupTrm; /* Number of member Group Terminals spanned */ + __u8 iBlockItem; /* String ID of Block item */ + __u8 bMIDIProtocol; /* Default MIDI protocol */ + __le16 wMaxInputBandwidth; /* Max input bandwidth capability in 4kB/s */ + __le16 wMaxOutputBandwidth; /* Max output bandwidth capability in 4kB/s */ +} __packed; + +#endif /* __LINUX_USB_MIDI_V2_H */ diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index e4a3ad3c800f..3963e55e88a3 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -99,9 +99,6 @@ struct musb_hdrc_platform_data { /* (HOST or OTG) program PHY for external Vbus */ unsigned extvbus:1; - /* Power the device on or off */ - int (*set_power)(int state); - /* MUSB configuration-specific details */ const struct musb_hdrc_config *config; @@ -135,14 +132,4 @@ static inline int musb_mailbox(enum musb_vbus_id_status status) #define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */ #define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */ -#ifdef CONFIG_ARCH_OMAP2 - -extern int __init tusb6010_setup_interface( - struct musb_hdrc_platform_data *data, - unsigned ps_refclk, unsigned waitpin, - unsigned async_cs, unsigned sync_cs, - unsigned irq, unsigned dmachan); - -#endif /* OMAP2 */ - #endif /* __LINUX_USB_MUSB_H */ diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 7eeb5f9c4f0d..1a0a4dc87980 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -278,7 +278,7 @@ struct usb_serial_driver { int (*set_serial)(struct tty_struct *tty, struct serial_struct *ss); void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port, const struct ktermios *old); - void (*break_ctl)(struct tty_struct *tty, int break_state); + int (*break_ctl)(struct tty_struct *tty, int break_state); unsigned int (*chars_in_buffer)(struct tty_struct *tty); void (*wait_until_sent)(struct tty_struct *tty, long timeout); bool (*tx_empty)(struct usb_serial_port *port); diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index 9292f0e07846..2489a7857d8e 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -60,8 +60,7 @@ struct typec_mux_desc { #if IS_ENABLED(CONFIG_TYPEC) -struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode, - const struct typec_altmode_desc *desc); +struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode); void typec_mux_put(struct typec_mux *mux); int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state); @@ -74,8 +73,7 @@ void *typec_mux_get_drvdata(struct typec_mux_dev *mux); #else -static inline struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode, - const struct typec_altmode_desc *desc) +static inline struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) { return NULL; } @@ -102,10 +100,9 @@ static inline void *typec_mux_get_drvdata(struct typec_mux_dev *mux) #endif /* CONFIG_TYPEC */ -static inline struct typec_mux * -typec_mux_get(struct device *dev, const struct typec_altmode_desc *desc) +static inline struct typec_mux *typec_mux_get(struct device *dev) { - return fwnode_typec_mux_get(dev_fwnode(dev), desc); + return fwnode_typec_mux_get(dev_fwnode(dev)); } #endif /* __USB_TYPEC_MUX */ diff --git a/include/linux/user_events.h b/include/linux/user_events.h index 2847f5a18a86..8afa8c3a0973 100644 --- a/include/linux/user_events.h +++ b/include/linux/user_events.h @@ -17,9 +17,10 @@ #ifdef CONFIG_USER_EVENTS struct user_event_mm { - struct list_head link; + struct list_head mms_link; struct list_head enablers; struct mm_struct *mm; + /* Used for one-shot lists, protected by event_mutex */ struct user_event_mm *next; refcount_t refcnt; refcount_t tasks; diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index d78b01524349..ac7b0c96d351 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -188,8 +188,8 @@ extern bool userfaultfd_remove(struct vm_area_struct *vma, unsigned long start, unsigned long end); -extern int userfaultfd_unmap_prep(struct mm_struct *mm, unsigned long start, - unsigned long end, struct list_head *uf); +extern int userfaultfd_unmap_prep(struct vm_area_struct *vma, + unsigned long start, unsigned long end, struct list_head *uf); extern void userfaultfd_unmap_complete(struct mm_struct *mm, struct list_head *uf); extern bool userfaultfd_wp_unpopulated(struct vm_area_struct *vma); @@ -271,7 +271,7 @@ static inline bool userfaultfd_remove(struct vm_area_struct *vma, return true; } -static inline int userfaultfd_unmap_prep(struct mm_struct *mm, +static inline int userfaultfd_unmap_prep(struct vm_area_struct *vma, unsigned long start, unsigned long end, struct list_head *uf) { diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 367fd79226a3..562e8754869d 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -59,8 +59,7 @@ struct vfio_pci_core_device { struct perm_bits *msi_perm; spinlock_t irqlock; struct mutex igate; - struct vfio_pci_irq_ctx *ctx; - int num_ctx; + struct xarray ctx; int irq_type; int num_regions; struct vfio_pci_region *region; @@ -69,17 +68,18 @@ struct vfio_pci_core_device { u16 msix_size; u32 msix_offset; u32 rbar[7]; - bool pci_2_3; - bool virq_disabled; - bool reset_works; - bool extended_caps; - bool bardirty; - bool has_vga; - bool needs_reset; - bool nointx; - bool needs_pm_restore; - bool pm_intx_masked; - bool pm_runtime_engaged; + bool has_dyn_msix:1; + bool pci_2_3:1; + bool virq_disabled:1; + bool reset_works:1; + bool extended_caps:1; + bool bardirty:1; + bool has_vga:1; + bool needs_reset:1; + bool nointx:1; + bool needs_pm_restore:1; + bool pm_intx_masked:1; + bool pm_runtime_engaged:1; struct pci_saved_state *pci_saved_state; struct pci_saved_state *pm_save; int ioeventfds_nr; diff --git a/include/linux/via-gpio.h b/include/linux/via-gpio.h deleted file mode 100644 index ac34668fd442..000000000000 --- a/include/linux/via-gpio.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Support for viafb GPIO ports. - * - * Copyright 2009 Jonathan Corbet <corbet@lwn.net> - */ - -#ifndef __VIA_GPIO_H__ -#define __VIA_GPIO_H__ - -extern int viafb_gpio_lookup(const char *name); -extern int viafb_gpio_init(void); -extern void viafb_gpio_exit(void); -#endif diff --git a/include/linux/virtio.h b/include/linux/virtio.h index b93238db94e3..de6041deee37 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -103,6 +103,7 @@ int virtqueue_resize(struct virtqueue *vq, u32 num, * @config_enabled: configuration change reporting enabled * @config_change_pending: configuration change reported while disabled * @config_lock: protects configuration change reporting + * @vqs_list_lock: protects @vqs. * @dev: underlying device. * @id: the device type identification (used to match it with a driver). * @config: the configuration ops for this device. @@ -117,7 +118,7 @@ struct virtio_device { bool config_enabled; bool config_change_pending; spinlock_t config_lock; - spinlock_t vqs_list_lock; /* Protects VQs list access */ + spinlock_t vqs_list_lock; struct device dev; struct virtio_device_id id; const struct virtio_config_ops *config; @@ -160,6 +161,8 @@ size_t virtio_max_dma_size(const struct virtio_device *vdev); * @feature_table_size: number of entries in the feature table array. * @feature_table_legacy: same as feature_table but when working in legacy mode. * @feature_table_size_legacy: number of entries in feature table legacy array. + * @validate: the function to call to validate features and config space. + * Returns 0 or -errno. * @probe: the function to call when a device is found. Returns 0 or -errno. * @scan: optional function to call after successful probe; intended * for virtio-scsi to invoke a scan. diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h index c4eeb79b0139..067ac1d789bc 100644 --- a/include/linux/virtio_pci_modern.h +++ b/include/linux/virtio_pci_modern.h @@ -38,6 +38,12 @@ struct virtio_pci_modern_device { int modern_bars; struct virtio_device_id id; + + /* optional check for vendor virtio device, returns dev_id or -ERRNO */ + int (*device_id_check)(struct pci_dev *pdev); + + /* optional mask for devices with limited DMA space */ + u64 dma_mask; }; /* diff --git a/include/linux/watch_queue.h b/include/linux/watch_queue.h index fc6bba20273b..45cd42f55d49 100644 --- a/include/linux/watch_queue.h +++ b/include/linux/watch_queue.h @@ -38,7 +38,7 @@ struct watch_filter { struct watch_queue { struct rcu_head rcu; struct watch_filter __rcu *filter; - struct pipe_inode_info *pipe; /* The pipe we're using as a buffer */ + struct pipe_inode_info *pipe; /* Pipe we use as a buffer, NULL if queue closed */ struct hlist_head watches; /* Contributory watches */ struct page **notes; /* Preallocated notifications */ unsigned long *notes_bitmap; /* Allocation bitmap for notes */ @@ -46,7 +46,6 @@ struct watch_queue { spinlock_t lock; unsigned int nr_notes; /* Number of notes */ unsigned int nr_pages; /* Number of pages in notes[] */ - bool defunct; /* T when queues closed */ }; /* diff --git a/include/linux/wmi.h b/include/linux/wmi.h index b88d7b58e61e..763bd382cf2d 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -13,25 +13,46 @@ #include <linux/mod_devicetable.h> #include <uapi/linux/wmi.h> +/** + * struct wmi_device - WMI device structure + * @dev: Device associated with this WMI device + * @setable: True for devices implementing the Set Control Method + * + * This represents WMI devices discovered by the WMI driver core. + */ struct wmi_device { struct device dev; - /* True for data blocks implementing the Set Control Method */ + /* private: used by the WMI driver core */ bool setable; }; -/* evaluate the ACPI method associated with this device */ extern acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out); -/* Caller must kfree the result. */ extern union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance); +u8 wmidev_instance_count(struct wmi_device *wdev); + extern int set_required_buffer_size(struct wmi_device *wdev, u64 length); +/** + * struct wmi_driver - WMI driver structure + * @driver: Driver model structure + * @id_table: List of WMI GUIDs supported by this driver + * @no_notify_data: WMI events provide no event data + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @notify: Callback for receiving WMI events + * @filter_callback: Callback for filtering device IOCTLs + * + * This represents WMI drivers which handle WMI devices. + * @filter_callback is only necessary for drivers which + * want to set up a WMI IOCTL interface. + */ struct wmi_driver { struct device_driver driver; const struct wmi_device_id *id_table; @@ -47,8 +68,24 @@ struct wmi_driver { extern int __must_check __wmi_driver_register(struct wmi_driver *driver, struct module *owner); extern void wmi_driver_unregister(struct wmi_driver *driver); + +/** + * wmi_driver_register() - Helper macro to register a WMI driver + * @driver: wmi_driver struct + * + * Helper macro for registering a WMI driver. It automatically passes + * THIS_MODULE to the underlying function. + */ #define wmi_driver_register(driver) __wmi_driver_register((driver), THIS_MODULE) +/** + * module_wmi_driver() - Helper macro to register/unregister a WMI driver + * @__wmi_driver: wmi_driver struct + * + * Helper macro for WMI drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit(). + */ #define module_wmi_driver(__wmi_driver) \ module_driver(__wmi_driver, wmi_driver_register, \ wmi_driver_unregister) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 3992c994787f..683efe29fa69 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -68,7 +68,6 @@ enum { WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, __WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, - WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING), /* * When a work item is off queue, its high bits point to the last @@ -79,12 +78,6 @@ enum { WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS, WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, - WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1, - - /* convenience constants */ - WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, - WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, - WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT, /* bit mask for work_busy() return values */ WORK_BUSY_PENDING = 1 << 0, @@ -94,6 +87,14 @@ enum { WORKER_DESC_LEN = 24, }; +/* Convenience constants - of type 'unsigned long', not 'enum'! */ +#define WORK_OFFQ_CANCELING (1ul << __WORK_OFFQ_CANCELING) +#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1) +#define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT) + +#define WORK_STRUCT_FLAG_MASK ((1ul << WORK_STRUCT_FLAG_BITS) - 1) +#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) + struct work_struct { atomic_long_t data; struct list_head entry; diff --git a/include/linux/zpool.h b/include/linux/zpool.h index e8997010612a..3296438eec06 100644 --- a/include/linux/zpool.h +++ b/include/linux/zpool.h @@ -14,10 +14,6 @@ struct zpool; -struct zpool_ops { - int (*evict)(struct zpool *pool, unsigned long handle); -}; - /* * Control how a handle is mapped. It will be ignored if the * implementation does not support it. Its use is optional. @@ -39,8 +35,7 @@ enum zpool_mapmode { bool zpool_has_pool(char *type); -struct zpool *zpool_create_pool(const char *type, const char *name, - gfp_t gfp, const struct zpool_ops *ops); +struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp); const char *zpool_get_type(struct zpool *pool); @@ -53,9 +48,6 @@ int zpool_malloc(struct zpool *pool, size_t size, gfp_t gfp, void zpool_free(struct zpool *pool, unsigned long handle); -int zpool_shrink(struct zpool *pool, unsigned int pages, - unsigned int *reclaimed); - void *zpool_map_handle(struct zpool *pool, unsigned long handle, enum zpool_mapmode mm); @@ -72,7 +64,6 @@ u64 zpool_get_total_size(struct zpool *pool); * @destroy: destroy a pool. * @malloc: allocate mem from a pool. * @free: free mem from a pool. - * @shrink: shrink the pool. * @sleep_mapped: whether zpool driver can sleep during map. * @map: map a handle. * @unmap: unmap a handle. @@ -87,10 +78,7 @@ struct zpool_driver { atomic_t refcount; struct list_head list; - void *(*create)(const char *name, - gfp_t gfp, - const struct zpool_ops *ops, - struct zpool *zpool); + void *(*create)(const char *name, gfp_t gfp); void (*destroy)(void *pool); bool malloc_support_movable; @@ -98,9 +86,6 @@ struct zpool_driver { unsigned long *handle); void (*free)(void *pool, unsigned long handle); - int (*shrink)(void *pool, unsigned int pages, - unsigned int *reclaimed); - bool sleep_mapped; void *(*map)(void *pool, unsigned long handle, enum zpool_mapmode mm); @@ -113,7 +98,6 @@ void zpool_register_driver(struct zpool_driver *driver); int zpool_unregister_driver(struct zpool_driver *driver); -bool zpool_evictable(struct zpool *pool); bool zpool_can_sleep_mapped(struct zpool *pool); #endif diff --git a/include/media/dvb_net.h b/include/media/dvb_net.h index 9980b1dd750b..4a921ea96091 100644 --- a/include/media/dvb_net.h +++ b/include/media/dvb_net.h @@ -39,6 +39,9 @@ struct net_device; * @exit: flag to indicate when the device is being removed. * @demux: pointer to &struct dmx_demux. * @ioctl_mutex: protect access to this struct. + * @remove_mutex: mutex that avoids a race condition between a callback + * called when the hardware is disconnected and the + * file_operations of dvb_net. * * Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network * devices. @@ -51,6 +54,7 @@ struct dvb_net { unsigned int exit:1; struct dmx_demux *demux; struct mutex ioctl_mutex; + struct mutex remove_mutex; }; /** diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h index 29d25c8a6f13..e5a00d126612 100644 --- a/include/media/dvbdev.h +++ b/include/media/dvbdev.h @@ -130,7 +130,7 @@ struct dvb_adapter { * struct dvb_device - represents a DVB device node * * @list_head: List head with all DVB devices - * @ref: reference counter + * @ref: reference count for this device * @fops: pointer to struct file_operations * @adapter: pointer to the adapter that holds this device node * @type: type of the device, as defined by &enum dvb_device_type. @@ -194,6 +194,21 @@ struct dvb_device { }; /** + * struct dvbdevfops_node - fops nodes registered in dvbdevfops_list + * + * @fops: Dynamically allocated fops for ->owner registration + * @type: type of dvb_device + * @template: dvb_device used for registration + * @list_head: list_head for dvbdevfops_list + */ +struct dvbdevfops_node { + struct file_operations *fops; + enum dvb_device_type type; + const struct dvb_device *template; + struct list_head list_head; +}; + +/** * dvb_device_get - Increase dvb_device reference * * @dvbdev: pointer to struct dvb_device @@ -251,10 +266,10 @@ int dvb_register_device(struct dvb_adapter *adap, /** * dvb_remove_device - Remove a registered DVB device * + * @dvbdev: pointer to struct dvb_device + * * This does not free memory. dvb_free_device() will do that when * reference counter is empty - * - * @dvbdev: pointer to struct dvb_device */ void dvb_remove_device(struct dvb_device *dvbdev); diff --git a/include/media/jpeg.h b/include/media/jpeg.h new file mode 100644 index 000000000000..a01e142e99a7 --- /dev/null +++ b/include/media/jpeg.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _MEDIA_JPEG_H_ +#define _MEDIA_JPEG_H_ + +/* JPEG markers */ +#define JPEG_MARKER_TEM 0x01 +#define JPEG_MARKER_SOF0 0xc0 +#define JPEG_MARKER_DHT 0xc4 +#define JPEG_MARKER_RST 0xd0 +#define JPEG_MARKER_SOI 0xd8 +#define JPEG_MARKER_EOI 0xd9 +#define JPEG_MARKER_SOS 0xda +#define JPEG_MARKER_DQT 0xdb +#define JPEG_MARKER_DRI 0xdd +#define JPEG_MARKER_DHP 0xde +#define JPEG_MARKER_APP0 0xe0 +#define JPEG_MARKER_COM 0xfe + +#endif /* _MEDIA_JPEG_H_ */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 741f9c629c6f..2b6cd343ee9e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -741,7 +741,7 @@ static inline void media_entity_cleanup(struct media_entity *entity) {} * media_get_pad_index() - retrieves a pad index from an entity * * @entity: entity where the pads belong - * @is_sink: true if the pad is a sink, false if it is a source + * @pad_type: the type of the pad, one of MEDIA_PAD_FL_* pad types * @sig_type: type of signal of the pad to be search * * This helper function finds the first pad index inside an entity that @@ -752,7 +752,7 @@ static inline void media_entity_cleanup(struct media_entity *entity) {} * On success, return the pad number. If the pad was not found or the media * entity is a NULL pointer, return -EINVAL. */ -int media_get_pad_index(struct media_entity *entity, bool is_sink, +int media_get_pad_index(struct media_entity *entity, u32 pad_type, enum media_pad_signal_type sig_type); /** @@ -1079,7 +1079,7 @@ struct media_pipeline *media_pad_pipeline(struct media_pad *pad); * Return: returns the pad number on success or a negative error code. */ int media_entity_get_fwnode_pad(struct media_entity *entity, - struct fwnode_handle *fwnode, + const struct fwnode_handle *fwnode, unsigned long direction_flags); /** diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 1bdaea248089..d278836fd9cb 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -480,6 +480,7 @@ enum v4l2_pixel_encoding { * @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4). * @comp_planes: Number of component planes, which includes the alpha plane (1 to 4). * @bpp: Array of per-plane bytes per pixel + * @bpp_div: Array of per-plane bytes per pixel divisors to support fractional pixel sizes. * @hdiv: Horizontal chroma subsampling factor * @vdiv: Vertical chroma subsampling factor * @block_w: Per-plane macroblock pixel width (optional) @@ -491,6 +492,7 @@ struct v4l2_format_info { u8 mem_planes; u8 comp_planes; u8 bpp[4]; + u8 bpp_div[4]; u8 hdiv; u8 vdiv; u8 block_w[4]; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 7788eeb3e2bb..59679a42b3e7 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -52,6 +52,10 @@ struct video_device; * @p_hdr10_cll: Pointer to an HDR10 Content Light Level structure. * @p_hdr10_mastering: Pointer to an HDR10 Mastering Display structure. * @p_area: Pointer to an area. + * @p_av1_sequence: Pointer to an AV1 sequence structure. + * @p_av1_tile_group_entry: Pointer to an AV1 tile group entry structure. + * @p_av1_frame: Pointer to an AV1 frame structure. + * @p_av1_film_grain: Pointer to an AV1 film grain structure. * @p: Pointer to a compound value. * @p_const: Pointer to a constant compound value. */ @@ -81,6 +85,10 @@ union v4l2_ctrl_ptr { struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll; struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; struct v4l2_area *p_area; + struct v4l2_ctrl_av1_sequence *p_av1_sequence; + struct v4l2_ctrl_av1_tile_group_entry *p_av1_tile_group_entry; + struct v4l2_ctrl_av1_frame *p_av1_frame; + struct v4l2_ctrl_av1_film_grain *p_av1_film_grain; void *p; const void *p_const; }; diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index bb9de6a899e0..d6c8eb2b5201 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -593,7 +593,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, static inline unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) { - return m2m_ctx->out_q_ctx.num_rdy; + unsigned int num_buf_rdy; + unsigned long flags; + + spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy; + spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags); + + return num_buf_rdy; } /** @@ -605,7 +612,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) static inline unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) { - return m2m_ctx->cap_q_ctx.num_rdy; + unsigned int num_buf_rdy; + unsigned long flags; + + spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); + num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy; + spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags); + + return num_buf_rdy; } /** diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index cfd19e72d0fc..b325df0d54d6 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1119,6 +1119,7 @@ struct v4l2_subdev { * @vfh: pointer to &struct v4l2_fh * @state: pointer to &struct v4l2_subdev_state * @owner: module pointer to the owner of this file handle + * @client_caps: bitmask of ``V4L2_SUBDEV_CLIENT_CAP_*`` */ struct v4l2_subdev_fh { struct v4l2_fh vfh; diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 1b4230cd42a3..af729859385e 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -185,7 +185,7 @@ struct bt_iso_ucast_qos { struct bt_iso_bcast_qos { __u8 big; __u8 bis; - __u8 sync_interval; + __u8 sync_factor; __u8 packing; __u8 framing; struct bt_iso_io_qos in; diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 07df96c47ef4..872dcb91a540 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -350,6 +350,7 @@ enum { enum { HCI_SETUP, HCI_CONFIG, + HCI_DEBUGFS_CREATED, HCI_AUTO_OFF, HCI_RFKILLED, HCI_MGMT, diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a6c8aee2f256..9654567cfae3 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -515,6 +515,7 @@ struct hci_dev { struct work_struct cmd_sync_work; struct list_head cmd_sync_work_list; struct mutex cmd_sync_work_lock; + struct mutex unregister_lock; struct work_struct cmd_sync_cancel_work; struct work_struct reenable_adv_work; @@ -1201,7 +1202,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev, if (id != BT_ISO_QOS_CIS_UNSET && id != c->iso_qos.ucast.cis) continue; - if (ba_type == c->dst_type && !bacmp(&c->dst, ba)) { + /* Match destination address if set */ + if (!ba || (ba_type == c->dst_type && !bacmp(&c->dst, ba))) { rcu_read_unlock(); return c; } @@ -1327,7 +1329,7 @@ int hci_le_create_cis(struct hci_conn *conn); struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, u8 role); -int hci_conn_del(struct hci_conn *conn); +void hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index a5801649f619..5e68b3dd4422 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -979,6 +979,7 @@ struct mgmt_ev_auth_failed { #define MGMT_DEV_FOUND_NOT_CONNECTABLE BIT(2) #define MGMT_DEV_FOUND_INITIATED_CONN BIT(3) #define MGMT_DEV_FOUND_NAME_REQUEST_FAILED BIT(4) +#define MGMT_DEV_FOUND_SCAN_RSP BIT(5) #define MGMT_EV_DEVICE_FOUND 0x0012 struct mgmt_ev_device_found { diff --git a/include/net/bonding.h b/include/net/bonding.h index a60a24923b55..b57bec6e737e 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-1.0+ */ /* * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'. * @@ -7,9 +8,6 @@ * BUT, I'm the one who modified it for ethernet, so: * (c) Copyright 1999, Thomas Davis, tadavis@lbl.gov * - * This software may be used and distributed according to the terms - * of the GNU Public License, incorporated herein by reference. - * */ #ifndef _NET_BONDING_H @@ -221,6 +219,7 @@ struct bonding { struct bond_up_slave __rcu *usable_slaves; struct bond_up_slave __rcu *all_slaves; bool force_primary; + bool notifier_ctx; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ int (*recv_probe)(const struct sk_buff *, struct bonding *, struct slave *); @@ -233,7 +232,7 @@ struct bonding { */ spinlock_t mode_lock; spinlock_t stats_lock; - u8 send_peer_notif; + u32 send_peer_notif; u8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9e04f69712b1..7c7d03aa9d06 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -7,7 +7,7 @@ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2021, 2023 Intel Corporation */ #include <linux/ethtool.h> @@ -1702,6 +1702,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy, * @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode * @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS * @RATE_INFO_FLAGS_EHT_MCS: EHT MCS information + * @RATE_INFO_FLAGS_S1G_MCS: MCS field filled with S1G MCS */ enum rate_info_flags { RATE_INFO_FLAGS_MCS = BIT(0), @@ -1712,6 +1713,7 @@ enum rate_info_flags { RATE_INFO_FLAGS_EDMG = BIT(5), RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6), RATE_INFO_FLAGS_EHT_MCS = BIT(7), + RATE_INFO_FLAGS_S1G_MCS = BIT(8), }; /** @@ -1728,6 +1730,11 @@ enum rate_info_flags { * @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation * @RATE_INFO_BW_320: 320 MHz bandwidth * @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT RU allocation + * @RATE_INFO_BW_1: 1 MHz bandwidth + * @RATE_INFO_BW_2: 2 MHz bandwidth + * @RATE_INFO_BW_4: 4 MHz bandwidth + * @RATE_INFO_BW_8: 8 MHz bandwidth + * @RATE_INFO_BW_16: 16 MHz bandwidth */ enum rate_info_bw { RATE_INFO_BW_20 = 0, @@ -1739,6 +1746,11 @@ enum rate_info_bw { RATE_INFO_BW_HE_RU, RATE_INFO_BW_320, RATE_INFO_BW_EHT_RU, + RATE_INFO_BW_1, + RATE_INFO_BW_2, + RATE_INFO_BW_4, + RATE_INFO_BW_8, + RATE_INFO_BW_16, }; /** @@ -1747,8 +1759,8 @@ enum rate_info_bw { * Information about a receiving or transmitting bitrate * * @flags: bitflag of flags from &enum rate_info_flags - * @mcs: mcs index if struct describes an HT/VHT/HE rate * @legacy: bitrate in 100kbit/s for 802.11abg + * @mcs: mcs index if struct describes an HT/VHT/HE/EHT/S1G rate * @nss: number of streams (VHT & HE only) * @bw: bandwidth (from &enum rate_info_bw) * @he_gi: HE guard interval (from &enum nl80211_he_gi) @@ -1761,9 +1773,9 @@ enum rate_info_bw { * only valid if bw is %RATE_INFO_BW_EHT_RU) */ struct rate_info { - u8 flags; - u8 mcs; + u16 flags; u16 legacy; + u8 mcs; u8 nss; u8 bw; u8 he_gi; @@ -2454,6 +2466,7 @@ struct cfg80211_scan_info { * @short_ssid_valid: @short_ssid is valid and can be used * @psc_no_listen: when set, and the channel is a PSC channel, no need to wait * 20 TUs before starting to send probe requests. + * @psd_20: The AP's 20 MHz PSD value. */ struct cfg80211_scan_6ghz_params { u32 short_ssid; @@ -2462,6 +2475,7 @@ struct cfg80211_scan_6ghz_params { bool unsolicited_probe; bool short_ssid_valid; bool psc_no_listen; + s8 psd_20; }; /** @@ -2708,6 +2722,7 @@ enum cfg80211_signal_type { * the BSS that requested the scan in which the beacon/probe was received. * @chains: bitmask for filled values in @chain_signal. * @chain_signal: per-chain signal strength of last received BSS in dBm. + * @drv_data: Data to be passed through to @inform_bss */ struct cfg80211_inform_bss { struct ieee80211_channel *chan; @@ -2718,6 +2733,8 @@ struct cfg80211_inform_bss { u8 parent_bssid[ETH_ALEN] __aligned(2); u8 chains; s8 chain_signal[IEEE80211_MAX_CHAINS]; + + void *drv_data; }; /** @@ -2870,11 +2887,14 @@ struct cfg80211_auth_request { * if this is %NULL for a link, that link is not requested * @elems: extra elements for the per-STA profile for this link * @elems_len: length of the elements + * @disabled: If set this link should be included during association etc. but it + * should not be used until enabled by the AP MLD. */ struct cfg80211_assoc_link { struct cfg80211_bss *bss; const u8 *elems; size_t elems_len; + bool disabled; }; /** @@ -4086,6 +4106,13 @@ struct mgmt_frame_regs { * * @change_bss: Modify parameters for a given BSS. * + * @inform_bss: Called by cfg80211 while being informed about new BSS data + * for every BSS found within the reported data or frame. This is called + * from within the cfg8011 inform_bss handlers while holding the bss_lock. + * The data parameter is passed through from drv_data inside + * struct cfg80211_inform_bss. + * The new IE data for the BSS is explicitly passed. + * * @set_txq_params: Set TX queue parameters * * @libertas_set_mesh_channel: Only for backward compatibility for libertas, @@ -4473,6 +4500,9 @@ struct cfg80211_ops { int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); + void (*inform_bss)(struct wiphy *wiphy, struct cfg80211_bss *bss, + const struct cfg80211_bss_ies *ies, void *data); + int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_txq_params *params); @@ -4592,9 +4622,10 @@ struct cfg80211_ops { struct cfg80211_gtk_rekey_data *data); int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, - const u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, u32 peer_capability, - bool initiator, const u8 *buf, size_t len); + const u8 *peer, int link_id, + u8 action_code, u8 dialog_token, u16 status_code, + u32 peer_capability, bool initiator, + const u8 *buf, size_t len); int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, enum nl80211_tdls_operation oper); @@ -5724,12 +5755,17 @@ struct cfg80211_cqm_config; * wiphy_lock - lock the wiphy * @wiphy: the wiphy to lock * - * This is mostly exposed so it can be done around registering and - * unregistering netdevs that aren't created through cfg80211 calls, - * since that requires locking in cfg80211 when the notifiers is - * called, but that cannot differentiate which way it's called. + * This is needed around registering and unregistering netdevs that + * aren't created through cfg80211 calls, since that requires locking + * in cfg80211 when the notifiers is called, but that cannot + * differentiate which way it's called. + * + * It can also be used by drivers for their own purposes. * * When cfg80211 ops are called, the wiphy is already locked. + * + * Note that this makes sure that no workers that have been queued + * with wiphy_queue_work() are running. */ static inline void wiphy_lock(struct wiphy *wiphy) __acquires(&wiphy->mtx) @@ -5749,6 +5785,88 @@ static inline void wiphy_unlock(struct wiphy *wiphy) mutex_unlock(&wiphy->mtx); } +struct wiphy_work; +typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *); + +struct wiphy_work { + struct list_head entry; + wiphy_work_func_t func; +}; + +static inline void wiphy_work_init(struct wiphy_work *work, + wiphy_work_func_t func) +{ + INIT_LIST_HEAD(&work->entry); + work->func = func; +} + +/** + * wiphy_work_queue - queue work for the wiphy + * @wiphy: the wiphy to queue for + * @work: the work item + * + * This is useful for work that must be done asynchronously, and work + * queued here has the special property that the wiphy mutex will be + * held as if wiphy_lock() was called, and that it cannot be running + * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can + * use just cancel_work() instead of cancel_work_sync(), it requires + * being in a section protected by wiphy_lock(). + */ +void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); + +/** + * wiphy_work_cancel - cancel previously queued work + * @wiphy: the wiphy, for debug purposes + * @work: the work to cancel + * + * Cancel the work *without* waiting for it, this assumes being + * called under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); + +struct wiphy_delayed_work { + struct wiphy_work work; + struct wiphy *wiphy; + struct timer_list timer; +}; + +void wiphy_delayed_work_timer(struct timer_list *t); + +static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork, + wiphy_work_func_t func) +{ + timer_setup(&dwork->timer, wiphy_delayed_work_timer, 0); + wiphy_work_init(&dwork->work, func); +} + +/** + * wiphy_delayed_work_queue - queue delayed work for the wiphy + * @wiphy: the wiphy to queue for + * @dwork: the delayable worker + * @delay: number of jiffies to wait before queueing + * + * This is useful for work that must be done asynchronously, and work + * queued here has the special property that the wiphy mutex will be + * held as if wiphy_lock() was called, and that it cannot be running + * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can + * use just cancel_work() instead of cancel_work_sync(), it requires + * being in a section protected by wiphy_lock(). + */ +void wiphy_delayed_work_queue(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork, + unsigned long delay); + +/** + * wiphy_delayed_work_cancel - cancel previously queued delayed work + * @wiphy: the wiphy, for debug purposes + * @dwork: the delayed work to cancel + * + * Cancel the work *without* waiting for it, this assumes being + * called under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_delayed_work_cancel(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork); + /** * struct wireless_dev - wireless device state * @@ -6561,6 +6679,28 @@ cfg80211_find_vendor_ie(unsigned int oui, int oui_type, } /** + * cfg80211_defragment_element - Defrag the given element data into a buffer + * + * @elem: the element to defragment + * @ies: elements where @elem is contained + * @ieslen: length of @ies + * @data: buffer to store element data + * @data_len: length of @data + * @frag_id: the element ID of fragments + * + * Return: length of @data, or -EINVAL on error + * + * Copy out all data from an element that may be fragmented into @data, while + * skipping all headers. + * + * The function uses memmove() internally. It is acceptable to defragment an + * element in-place. + */ +ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies, + size_t ieslen, u8 *data, size_t data_len, + u8 frag_id); + +/** * cfg80211_send_layer2_update - send layer 2 update frame * * @dev: network device @@ -9067,4 +9207,17 @@ static inline int cfg80211_color_change_notify(struct net_device *dev) bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, const struct cfg80211_chan_def *chandef); +/** + * cfg80211_links_removed - Notify about removed STA MLD setup links. + * @dev: network device. + * @link_mask: BIT mask of removed STA MLD setup link IDs. + * + * Inform cfg80211 and the userspace about removed STA MLD setup links due to + * AP MLD removing the corresponding affiliated APs with Multi-Link + * reconfiguration. Note that it's not valid to remove all links, in this + * case disconnect instead. + * Also note that the wdev mutex must be held. + */ +void cfg80211_links_removed(struct net_device *dev, u16 link_mask); + #endif /* __NET_CFG80211_H */ diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 0c2778a836db..e00057984489 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b) * setting. * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was * temporarily stopped. + * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to + * send/receive datagrams. */ enum wpan_phy_flags { WPAN_PHY_FLAG_TXPOWER = BIT(1), WPAN_PHY_FLAG_CCA_ED_LEVEL = BIT(2), WPAN_PHY_FLAG_CCA_MODE = BIT(3), WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4), + WPAN_PHY_FLAG_DATAGRAMS_ONLY = BIT(5), }; struct wpan_phy { diff --git a/include/net/devlink.h b/include/net/devlink.h index 6a942e70e451..9a3c51aa6e81 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -123,6 +123,7 @@ struct devlink_port { struct list_head list; struct list_head region_list; struct devlink *devlink; + const struct devlink_port_ops *ops; unsigned int index; spinlock_t type_lock; /* Protects type and type_eth/ib * structures consistency. @@ -1261,7 +1262,7 @@ struct devlink_ops { /** * @supported_flash_update_params: * mask of parameters supported by the driver's .flash_update - * implemementation. + * implementation. */ u32 supported_flash_update_params; unsigned long reload_actions; @@ -1273,12 +1274,6 @@ struct devlink_ops { int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action, enum devlink_reload_limit limit, u32 *actions_performed, struct netlink_ext_ack *extack); - int (*port_type_set)(struct devlink_port *devlink_port, - enum devlink_port_type port_type); - int (*port_split)(struct devlink *devlink, struct devlink_port *port, - unsigned int count, struct netlink_ext_ack *extack); - int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port, - struct netlink_ext_ack *extack); int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index, u16 pool_index, struct devlink_sb_pool_info *pool_info); @@ -1435,80 +1430,17 @@ struct devlink_ops { const struct devlink_trap_policer *policer, u64 *p_drops); /** - * @port_function_hw_addr_get: Port function's hardware address get function. - * - * Should be used by device drivers to report the hardware address of a function managed - * by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port - * function handling for a particular port. - * - * Note: @extack can be NULL when port notifier queries the port function. - */ - int (*port_function_hw_addr_get)(struct devlink_port *port, u8 *hw_addr, - int *hw_addr_len, - struct netlink_ext_ack *extack); - /** - * @port_function_hw_addr_set: Port function's hardware address set function. - * - * Should be used by device drivers to set the hardware address of a function managed - * by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port - * function handling for a particular port. - */ - int (*port_function_hw_addr_set)(struct devlink_port *port, - const u8 *hw_addr, int hw_addr_len, - struct netlink_ext_ack *extack); - /** - * @port_fn_roce_get: Port function's roce get function. - * - * Query RoCE state of a function managed by the devlink port. - * Return -EOPNOTSUPP if port function RoCE handling is not supported. - */ - int (*port_fn_roce_get)(struct devlink_port *devlink_port, - bool *is_enable, - struct netlink_ext_ack *extack); - /** - * @port_fn_roce_set: Port function's roce set function. - * - * Enable/Disable the RoCE state of a function managed by the devlink - * port. - * Return -EOPNOTSUPP if port function RoCE handling is not supported. - */ - int (*port_fn_roce_set)(struct devlink_port *devlink_port, - bool enable, struct netlink_ext_ack *extack); - /** - * @port_fn_migratable_get: Port function's migratable get function. - * - * Query migratable state of a function managed by the devlink port. - * Return -EOPNOTSUPP if port function migratable handling is not - * supported. - */ - int (*port_fn_migratable_get)(struct devlink_port *devlink_port, - bool *is_enable, - struct netlink_ext_ack *extack); - /** - * @port_fn_migratable_set: Port function's migratable set function. - * - * Enable/Disable migratable state of a function managed by the devlink - * port. - * Return -EOPNOTSUPP if port function migratable handling is not - * supported. - */ - int (*port_fn_migratable_set)(struct devlink_port *devlink_port, - bool enable, - struct netlink_ext_ack *extack); - /** * port_new() - Add a new port function of a specified flavor * @devlink: Devlink instance * @attrs: attributes of the new port * @extack: extack for reporting error messages - * @new_port_index: index of the new port + * @devlink_port: pointer to store new devlink port pointer * * Devlink core will call this device driver function upon user request * to create a new port function of a specified flavor and optional * attributes * * Notes: - * - Called without devlink instance lock being held. Drivers must - * implement own means of synchronization * - On success, drivers must register a port with devlink core * * Return: 0 on success, negative value otherwise. @@ -1516,56 +1448,7 @@ struct devlink_ops { int (*port_new)(struct devlink *devlink, const struct devlink_port_new_attrs *attrs, struct netlink_ext_ack *extack, - unsigned int *new_port_index); - /** - * port_del() - Delete a port function - * @devlink: Devlink instance - * @port_index: port function index to delete - * @extack: extack for reporting error messages - * - * Devlink core will call this device driver function upon user request - * to delete a previously created port function - * - * Notes: - * - Called without devlink instance lock being held. Drivers must - * implement own means of synchronization - * - On success, drivers must unregister the corresponding devlink - * port - * - * Return: 0 on success, negative value otherwise. - */ - int (*port_del)(struct devlink *devlink, unsigned int port_index, - struct netlink_ext_ack *extack); - /** - * port_fn_state_get() - Get the state of a port function - * @devlink: Devlink instance - * @port: The devlink port - * @state: Admin configured state - * @opstate: Current operational state - * @extack: extack for reporting error messages - * - * Reports the admin and operational state of a devlink port function - * - * Return: 0 on success, negative value otherwise. - */ - int (*port_fn_state_get)(struct devlink_port *port, - enum devlink_port_fn_state *state, - enum devlink_port_fn_opstate *opstate, - struct netlink_ext_ack *extack); - /** - * port_fn_state_set() - Set the admin state of a port function - * @devlink: Devlink instance - * @port: The devlink port - * @state: Admin state - * @extack: extack for reporting error messages - * - * Set the admin state of a devlink port function - * - * Return: 0 on success, negative value otherwise. - */ - int (*port_fn_state_set)(struct devlink_port *port, - enum devlink_port_fn_state state, - struct netlink_ext_ack *extack); + struct devlink_port **devlink_port); /** * Rate control callbacks. @@ -1655,15 +1538,116 @@ void devl_unregister(struct devlink *devlink); void devlink_register(struct devlink *devlink); void devlink_unregister(struct devlink *devlink); void devlink_free(struct devlink *devlink); + +/** + * struct devlink_port_ops - Port operations + * @port_split: Callback used to split the port into multiple ones. + * @port_unsplit: Callback used to unsplit the port group back into + * a single port. + * @port_type_set: Callback used to set a type of a port. + * @port_del: Callback used to delete selected port along with related function. + * Devlink core calls this upon user request to delete + * a port previously created by devlink_ops->port_new(). + * @port_fn_hw_addr_get: Callback used to set port function's hardware address. + * Should be used by device drivers to report + * the hardware address of a function managed + * by the devlink port. + * @port_fn_hw_addr_set: Callback used to set port function's hardware address. + * Should be used by device drivers to set the hardware + * address of a function managed by the devlink port. + * @port_fn_roce_get: Callback used to get port function's RoCE capability. + * Should be used by device drivers to report + * the current state of RoCE capability of a function + * managed by the devlink port. + * @port_fn_roce_set: Callback used to set port function's RoCE capability. + * Should be used by device drivers to enable/disable + * RoCE capability of a function managed + * by the devlink port. + * @port_fn_migratable_get: Callback used to get port function's migratable + * capability. Should be used by device drivers + * to report the current state of migratable capability + * of a function managed by the devlink port. + * @port_fn_migratable_set: Callback used to set port function's migratable + * capability. Should be used by device drivers + * to enable/disable migratable capability of + * a function managed by the devlink port. + * @port_fn_state_get: Callback used to get port function's state. + * Should be used by device drivers to report + * the current admin and operational state of a + * function managed by the devlink port. + * @port_fn_state_set: Callback used to get port function's state. + * Should be used by device drivers set + * the admin state of a function managed + * by the devlink port. + * + * Note: Driver should return -EOPNOTSUPP if it doesn't support + * port function (@port_fn_*) handling for a particular port. + */ +struct devlink_port_ops { + int (*port_split)(struct devlink *devlink, struct devlink_port *port, + unsigned int count, struct netlink_ext_ack *extack); + int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port, + struct netlink_ext_ack *extack); + int (*port_type_set)(struct devlink_port *devlink_port, + enum devlink_port_type port_type); + int (*port_del)(struct devlink *devlink, struct devlink_port *port, + struct netlink_ext_ack *extack); + int (*port_fn_hw_addr_get)(struct devlink_port *port, u8 *hw_addr, + int *hw_addr_len, + struct netlink_ext_ack *extack); + int (*port_fn_hw_addr_set)(struct devlink_port *port, + const u8 *hw_addr, int hw_addr_len, + struct netlink_ext_ack *extack); + int (*port_fn_roce_get)(struct devlink_port *devlink_port, + bool *is_enable, + struct netlink_ext_ack *extack); + int (*port_fn_roce_set)(struct devlink_port *devlink_port, + bool enable, struct netlink_ext_ack *extack); + int (*port_fn_migratable_get)(struct devlink_port *devlink_port, + bool *is_enable, + struct netlink_ext_ack *extack); + int (*port_fn_migratable_set)(struct devlink_port *devlink_port, + bool enable, + struct netlink_ext_ack *extack); + int (*port_fn_state_get)(struct devlink_port *port, + enum devlink_port_fn_state *state, + enum devlink_port_fn_opstate *opstate, + struct netlink_ext_ack *extack); + int (*port_fn_state_set)(struct devlink_port *port, + enum devlink_port_fn_state state, + struct netlink_ext_ack *extack); +}; + void devlink_port_init(struct devlink *devlink, struct devlink_port *devlink_port); void devlink_port_fini(struct devlink_port *devlink_port); -int devl_port_register(struct devlink *devlink, - struct devlink_port *devlink_port, - unsigned int port_index); -int devlink_port_register(struct devlink *devlink, - struct devlink_port *devlink_port, - unsigned int port_index); + +int devl_port_register_with_ops(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index, + const struct devlink_port_ops *ops); + +static inline int devl_port_register(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index) +{ + return devl_port_register_with_ops(devlink, devlink_port, + port_index, NULL); +} + +int devlink_port_register_with_ops(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index, + const struct devlink_port_ops *ops); + +static inline int devlink_port_register(struct devlink *devlink, + struct devlink_port *devlink_port, + unsigned int port_index) +{ + return devlink_port_register_with_ops(devlink, devlink_port, + port_index, NULL); +} + void devl_port_unregister(struct devlink_port *devlink_port); void devlink_port_unregister(struct devlink_port *devlink_port); void devlink_port_type_eth_set(struct devlink_port *devlink_port); diff --git a/include/net/dsa.h b/include/net/dsa.h index 8903053fa5aa..d309ee7ed04b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -314,9 +314,17 @@ struct dsa_port { struct list_head fdbs; struct list_head mdbs; - /* List of VLANs that CPU and DSA ports are members of. */ struct mutex vlans_lock; - struct list_head vlans; + union { + /* List of VLANs that CPU and DSA ports are members of. + * Access to this is serialized by the sleepable @vlans_lock. + */ + struct list_head vlans; + /* List of VLANs that user ports are members of. + * Access to this is serialized by netif_addr_lock_bh(). + */ + struct list_head user_vlans; + }; }; /* TODO: ideally DSA ports would have a single dp->link_dp member, @@ -867,9 +875,15 @@ struct dsa_switch_ops { phy_interface_t iface); int (*phylink_mac_link_state)(struct dsa_switch *ds, int port, struct phylink_link_state *state); + int (*phylink_mac_prepare)(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface); void (*phylink_mac_config)(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state); + int (*phylink_mac_finish)(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface); void (*phylink_mac_an_restart)(struct dsa_switch *ds, int port); void (*phylink_mac_link_down)(struct dsa_switch *ds, int port, unsigned int mode, @@ -959,6 +973,14 @@ struct dsa_switch_ops { void (*port_disable)(struct dsa_switch *ds, int port); /* + * Compatibility between device trees defining multiple CPU ports and + * drivers which are not OK to use by default the numerically smallest + * CPU port of a switch for its local ports. This can return NULL, + * meaning "don't know/don't care". + */ + struct dsa_port *(*preferred_default_local_cpu_port)(struct dsa_switch *ds); + + /* * Port's MAC EEE settings */ int (*set_mac_eee)(struct dsa_switch *ds, int port, diff --git a/include/net/flow.h b/include/net/flow.h index bb8651a6eaa7..7f0adda3bf2f 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -116,11 +116,10 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif, } /* Reset some input parameters after previous lookup */ -static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos, +static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __be32 daddr, __be32 saddr) { fl4->flowi4_oif = oif; - fl4->flowi4_tos = tos; fl4->daddr = daddr; fl4->saddr = saddr; } diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 85b2281576ed..8664ed4fbbdf 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -243,10 +243,12 @@ struct flow_dissector_key_ip { * struct flow_dissector_key_meta: * @ingress_ifindex: ingress ifindex * @ingress_iftype: ingress interface type + * @l2_miss: packet did not match an L2 entry during forwarding */ struct flow_dissector_key_meta { int ingress_ifindex; u16 ingress_iftype; + u8 l2_miss; }; /** @@ -299,6 +301,26 @@ struct flow_dissector_key_l2tpv3 { __be32 session_id; }; +/** + * struct flow_dissector_key_cfm + * @mdl_ver: maintenance domain level (mdl) and cfm protocol version + * @opcode: code specifying a type of cfm protocol packet + * + * See 802.1ag, ITU-T G.8013/Y.1731 + * 1 2 + * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | mdl | version | opcode | + * +-----+---------+-+-+-+-+-+-+-+-+ + */ +struct flow_dissector_key_cfm { + u8 mdl_ver; + u8 opcode; +}; + +#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5) +#define FLOW_DIS_CFM_MDL_MAX 7 + enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */ FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ @@ -331,6 +353,7 @@ enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */ FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */ FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */ + FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */ FLOW_DISSECTOR_KEY_MAX, }; diff --git a/include/net/gro.h b/include/net/gro.h index a4fab706240d..75efa6fb8441 100644 --- a/include/net/gro.h +++ b/include/net/gro.h @@ -11,11 +11,23 @@ #include <net/udp.h> struct napi_gro_cb { - /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */ - void *frag0; + union { + struct { + /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */ + void *frag0; - /* Length of frag0. */ - unsigned int frag0_len; + /* Length of frag0. */ + unsigned int frag0_len; + }; + + struct { + /* used in skb_gro_receive() slow path */ + struct sk_buff *last; + + /* jiffies when first packet was created/queued */ + unsigned long age; + }; + }; /* This indicates where we are processing relative to skb->data. */ int data_offset; @@ -32,9 +44,6 @@ struct napi_gro_cb { /* Used in ipv6_gro_receive() and foo-over-udp */ u16 proto; - /* jiffies when first packet was created/queued */ - unsigned long age; - /* Used in napi_gro_cb::free */ #define NAPI_GRO_FREE 1 #define NAPI_GRO_FREE_STOLEN_HEAD 2 @@ -77,9 +86,6 @@ struct napi_gro_cb { /* used to support CHECKSUM_COMPLETE for tunneling protocols */ __wsum csum; - - /* used in skb_gro_receive() slow path */ - struct sk_buff *last; }; #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) @@ -446,5 +452,6 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb, gro_normal_list(napi); } +extern struct list_head offload_base; #endif /* _NET_IPV6_GRO_H */ diff --git a/include/net/gso.h b/include/net/gso.h new file mode 100644 index 000000000000..29975440cad5 --- /dev/null +++ b/include/net/gso.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _NET_GSO_H +#define _NET_GSO_H + +#include <linux/skbuff.h> + +/* Keeps track of mac header offset relative to skb->head. + * It is useful for TSO of Tunneling protocol. e.g. GRE. + * For non-tunnel skb it points to skb_mac_header() and for + * tunnel skb it points to outer mac header. + * Keeps track of level of encapsulation of network headers. + */ +struct skb_gso_cb { + union { + int mac_offset; + int data_offset; + }; + int encap_level; + __wsum csum; + __u16 csum_start; +}; +#define SKB_GSO_CB_OFFSET 32 +#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_GSO_CB_OFFSET)) + +static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) +{ + return (skb_mac_header(inner_skb) - inner_skb->head) - + SKB_GSO_CB(inner_skb)->mac_offset; +} + +static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) +{ + int new_headroom, headroom; + int ret; + + headroom = skb_headroom(skb); + ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC); + if (ret) + return ret; + + new_headroom = skb_headroom(skb); + SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom); + return 0; +} + +static inline void gso_reset_checksum(struct sk_buff *skb, __wsum res) +{ + /* Do not update partial checksums if remote checksum is enabled. */ + if (skb->remcsum_offload) + return; + + SKB_GSO_CB(skb)->csum = res; + SKB_GSO_CB(skb)->csum_start = skb_checksum_start(skb) - skb->head; +} + +/* Compute the checksum for a gso segment. First compute the checksum value + * from the start of transport header to SKB_GSO_CB(skb)->csum_start, and + * then add in skb->csum (checksum from csum_start to end of packet). + * skb->csum and csum_start are then updated to reflect the checksum of the + * resultant packet starting from the transport header-- the resultant checksum + * is in the res argument (i.e. normally zero or ~ of checksum of a pseudo + * header. + */ +static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res) +{ + unsigned char *csum_start = skb_transport_header(skb); + int plen = (skb->head + SKB_GSO_CB(skb)->csum_start) - csum_start; + __wsum partial = SKB_GSO_CB(skb)->csum; + + SKB_GSO_CB(skb)->csum = res; + SKB_GSO_CB(skb)->csum_start = csum_start - skb->head; + + return csum_fold(csum_partial(csum_start, plen, partial)); +} + +struct sk_buff *__skb_gso_segment(struct sk_buff *skb, + netdev_features_t features, bool tx_path); + +static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb, + netdev_features_t features) +{ + return __skb_gso_segment(skb, features, true); +} + +struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb, + netdev_features_t features, __be16 type); + +struct sk_buff *skb_mac_gso_segment(struct sk_buff *skb, + netdev_features_t features); + +bool skb_gso_validate_network_len(const struct sk_buff *skb, unsigned int mtu); + +bool skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len); + +static inline void skb_gso_error_unwind(struct sk_buff *skb, __be16 protocol, + int pulled_hlen, u16 mac_offset, + int mac_len) +{ + skb->protocol = protocol; + skb->encapsulation = 1; + skb_push(skb, pulled_hlen); + skb_reset_transport_header(skb); + skb->mac_header = mac_offset; + skb->network_header = skb->mac_header + mac_len; + skb->mac_len = mac_len; +} + +#endif /* _NET_GSO_H */ diff --git a/include/net/handshake.h b/include/net/handshake.h index 3352b1ab43b3..2e26e436e85f 100644 --- a/include/net/handshake.h +++ b/include/net/handshake.h @@ -24,6 +24,7 @@ struct tls_handshake_args { struct socket *ta_sock; tls_done_func_t ta_done; void *ta_data; + const char *ta_peername; unsigned int ta_timeout_ms; key_serial_t ta_keyring; key_serial_t ta_my_cert; diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index f980a72f2ce6..c4722a9963de 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h @@ -535,6 +535,8 @@ enum ieee80211_radiotap_eht_usig_common { IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN = 0x00000008, IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN = 0x00000010, IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC = 0x00000020, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_CHECKED = 0x00000040, + IEEE80211_RADIOTAP_EHT_USIG_COMMON_VALIDATE_BITS_OK = 0x00000080, IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER = 0x00007000, IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW = 0x00038000, IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL = 0x00040000, diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index da8a3e648c7a..063313df447d 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -74,6 +74,10 @@ struct ieee802154_beacon_hdr { #endif } __packed; +struct ieee802154_mac_cmd_pl { + u8 cmd_id; +} __packed; + struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) u8 level:3, @@ -149,6 +153,16 @@ struct ieee802154_beacon_frame { struct ieee802154_beacon_hdr mac_pl; }; +struct ieee802154_mac_cmd_frame { + struct ieee802154_hdr mhr; + struct ieee802154_mac_cmd_pl mac_pl; +}; + +struct ieee802154_beacon_req_frame { + struct ieee802154_hdr mhr; + struct ieee802154_mac_cmd_pl mac_pl; +}; + /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from * the contents of hdr will be, and the actual value of those bits in * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame @@ -174,9 +188,13 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, */ int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); -/* pushes a beacon frame into an skb */ +/* pushes/pulls various frame types into/from an skb */ int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon); +int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame, + const void *pl, unsigned int pl_len); +int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb, + struct ieee802154_mac_cmd_pl *mac_pl); int ieee802154_max_payload(const struct ieee802154_hdr *hdr); diff --git a/include/net/inet_common.h b/include/net/inet_common.h index cec453c18f1d..b86b8e21de7f 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -31,10 +31,11 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags); int inet_accept(struct socket *sock, struct socket *newsock, int flags, bool kern); +void __inet_accept(struct socket *sock, struct socket *newsock, + struct sock *newsk); int inet_send_prepare(struct sock *sk); int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size); -ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, - size_t size, int flags); +void inet_splice_eof(struct socket *sock); int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags); int inet_shutdown(struct socket *sock, int how); diff --git a/include/net/ip.h b/include/net/ip.h index c3fffaa92d6e..50d435855ae2 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -76,6 +76,7 @@ struct ipcm_cookie { __be32 addr; int oif; struct ip_options_rcu *opt; + __u8 protocol; __u8 ttl; __s16 tos; char priority; @@ -96,6 +97,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, ipcm->sockc.tsflags = inet->sk.sk_tsflags; ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr; + ipcm->protocol = inet->inet_num; } #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) @@ -220,8 +222,6 @@ int ip_append_data(struct sock *sk, struct flowi4 *fl4, unsigned int flags); int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb); -ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, - int offset, size_t size, int flags); struct sk_buff *__ip_make_skb(struct sock *sk, struct flowi4 *fl4, struct sk_buff_head *queue, struct inet_cork *cork); @@ -242,14 +242,22 @@ static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base); } -static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet) +/* Get the route scope that should be used when sending a packet. */ +static inline u8 ip_sendmsg_scope(const struct inet_sock *inet, + const struct ipcm_cookie *ipc, + const struct msghdr *msg) { - return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos); + if (sock_flag(&inet->sk, SOCK_LOCALROUTE) || + msg->msg_flags & MSG_DONTROUTE || + (ipc->opt && ipc->opt->opt.is_strictroute)) + return RT_SCOPE_LINK; + + return RT_SCOPE_UNIVERSE; } -static inline __u8 get_rtconn_flags(struct ipcm_cookie* ipc, struct sock* sk) +static inline __u8 get_rttos(struct ipcm_cookie* ipc, struct inet_sock *inet) { - return (ipc->tos != -1) ? RT_CONN_FLAGS_TOS(sk, ipc->tos) : RT_CONN_FLAGS(sk); + return (ipc->tos != -1) ? RT_TOS(ipc->tos) : RT_TOS(inet->tos); } /* datagram.c */ @@ -280,7 +288,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, const struct ip_options *sopt, __be32 daddr, __be32 saddr, const struct ip_reply_arg *arg, - unsigned int len, u64 transmit_time); + unsigned int len, u64 transmit_time, u32 txhash); #define IP_INC_STATS(net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field) #define __IP_INC_STATS(net, field) __SNMP_INC_STATS64((net)->mib.ip_statistics, field) diff --git a/include/net/kcm.h b/include/net/kcm.h index 2d704f8f4905..90279e5e09a5 100644 --- a/include/net/kcm.h +++ b/include/net/kcm.h @@ -47,9 +47,9 @@ struct kcm_stats { struct kcm_tx_msg { unsigned int sent; - unsigned int fragidx; unsigned int frag_offset; unsigned int msg_flags; + bool started_tx; struct sk_buff *frag_skb; struct sk_buff *last_skb; }; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ac0370e76874..3a8a2d2c58c3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -7,7 +7,7 @@ * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 - 2022 Intel Corporation + * Copyright (C) 2018 - 2023 Intel Corporation */ #ifndef MAC80211_H @@ -1755,12 +1755,15 @@ struct ieee80211_channel_switch { * @IEEE80211_VIF_GET_NOA_UPDATE: request to handle NOA attributes * and send P2P_PS notification to the driver if NOA changed, even * this is not pure P2P vif. + * @IEEE80211_VIF_DISABLE_SMPS_OVERRIDE: disable user configuration of + * SMPS mode via debugfs. */ enum ieee80211_vif_flags { IEEE80211_VIF_BEACON_FILTER = BIT(0), IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1), IEEE80211_VIF_SUPPORTS_UAPSD = BIT(2), IEEE80211_VIF_GET_NOA_UPDATE = BIT(3), + IEEE80211_VIF_DISABLE_SMPS_OVERRIDE = BIT(4), }; @@ -1790,6 +1793,9 @@ enum ieee80211_offload_flags { * @ps: power-save mode (STA only). This flag is NOT affected by * offchannel/dynamic_ps operations. * @aid: association ID number, valid only when @assoc is true + * @eml_cap: EML capabilities as described in P802.11be_D2.2 Figure 9-1002k. + * @eml_med_sync_delay: Medium Synchronization delay as described in + * P802.11be_D2.2 Figure 9-1002j. * @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The * may filter ARP queries targeted for other addresses than listed here. * The driver must allow ARP queries targeted for all address listed here @@ -1812,6 +1818,8 @@ struct ieee80211_vif_cfg { bool ibss_creator; bool ps; u16 aid; + u16 eml_cap; + u16 eml_med_sync_delay; __be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN]; int arp_addr_cnt; @@ -1838,6 +1846,8 @@ struct ieee80211_vif_cfg { * @active_links: The bitmap of active links, or 0 for non-MLO. * The driver shouldn't change this directly, but use the * API calls meant for that purpose. + * @dormant_links: bitmap of valid but disabled links, or 0 for non-MLO. + * Must be a subset of valid_links. * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively @@ -1875,7 +1885,7 @@ struct ieee80211_vif { struct ieee80211_vif_cfg cfg; struct ieee80211_bss_conf bss_conf; struct ieee80211_bss_conf __rcu *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; - u16 valid_links, active_links; + u16 valid_links, active_links, dormant_links; u8 addr[ETH_ALEN] __aligned(2); bool p2p; @@ -1901,6 +1911,27 @@ struct ieee80211_vif { u8 drv_priv[] __aligned(sizeof(void *)); }; +/** + * ieee80211_vif_usable_links - Return the usable links for the vif + * @vif: the vif for which the usable links are requested + * Return: the usable link bitmap + */ +static inline u16 ieee80211_vif_usable_links(const struct ieee80211_vif *vif) +{ + return vif->valid_links & ~vif->dormant_links; +} + +/** + * ieee80211_vif_is_mld - Returns true iff the vif is an MLD one + * @vif: the vif + * Return: %true if the vif is an MLD, %false otherwise. + */ +static inline bool ieee80211_vif_is_mld(const struct ieee80211_vif *vif) +{ + /* valid_links != 0 indicates this vif is an MLD */ + return vif->valid_links != 0; +} + #define for_each_vif_active_link(vif, link, link_id) \ for (link_id = 0; link_id < ARRAY_SIZE((vif)->link_conf); link_id++) \ if ((!(vif)->active_links || \ @@ -3842,7 +3873,7 @@ struct ieee80211_prep_tx_info { * * @link_sta_add_debugfs: Drivers can use this callback to add debugfs files * when a link is added to a mac80211 station. This callback - * should be within a CPTCFG_MAC80211_DEBUGFS conditional. This + * should be within a CONFIG_MAC80211_DEBUGFS conditional. This * callback can sleep. * For non-MLO the callback will be called once for the deflink with the * station's directory rather than a separate subdirectory. @@ -5251,7 +5282,8 @@ struct ieee80211_mutable_offsets { * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @offs: &struct ieee80211_mutable_offsets pointer to struct that will * receive the offsets that may be updated by the driver. - * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) + * @link_id: the link id to which the beacon belongs (or 0 for an AP STA + * that is not associated with AP MLD). * * If the driver implements beaconing modes, it must use this function to * obtain the beacon template. @@ -5348,7 +5380,8 @@ void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons); * @tim_length: pointer to variable that will receive the TIM IE length, * (including the ID and length bytes!). * Set to 0 if invalid (in non-AP modes). - * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) + * @link_id: the link id to which the beacon belongs (or 0 for an AP STA + * that is not associated with AP MLD). * * If the driver implements beaconing modes, it must use this function to * obtain the beacon frame. @@ -5371,7 +5404,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, * ieee80211_beacon_get - beacon generation function * @hw: pointer obtained from ieee80211_alloc_hw(). * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) + * @link_id: the link id to which the beacon belongs (or 0 for an AP STA + * that is not associated with AP MLD). * * See ieee80211_beacon_get_tim(). * @@ -6862,6 +6896,48 @@ ieee80211_vif_type_p2p(struct ieee80211_vif *vif) } /** + * ieee80211_get_he_iftype_cap_vif - return HE capabilities for sband/vif + * @sband: the sband to search for the iftype on + * @vif: the vif to get the iftype from + * + * Return: pointer to the struct ieee80211_sta_he_cap, or %NULL is none found + */ +static inline const struct ieee80211_sta_he_cap * +ieee80211_get_he_iftype_cap_vif(const struct ieee80211_supported_band *sband, + struct ieee80211_vif *vif) +{ + return ieee80211_get_he_iftype_cap(sband, ieee80211_vif_type_p2p(vif)); +} + +/** + * ieee80211_get_he_6ghz_capa_vif - return HE 6 GHz capabilities + * @sband: the sband to search for the STA on + * @vif: the vif to get the iftype from + * + * Return: the 6GHz capabilities + */ +static inline __le16 +ieee80211_get_he_6ghz_capa_vif(const struct ieee80211_supported_band *sband, + struct ieee80211_vif *vif) +{ + return ieee80211_get_he_6ghz_capa(sband, ieee80211_vif_type_p2p(vif)); +} + +/** + * ieee80211_get_eht_iftype_cap_vif - return ETH capabilities for sband/vif + * @sband: the sband to search for the iftype on + * @vif: the vif to get the iftype from + * + * Return: pointer to the struct ieee80211_sta_eht_cap, or %NULL is none found + */ +static inline const struct ieee80211_sta_eht_cap * +ieee80211_get_eht_iftype_cap_vif(const struct ieee80211_supported_band *sband, + struct ieee80211_vif *vif) +{ + return ieee80211_get_eht_iftype_cap(sband, ieee80211_vif_type_p2p(vif)); +} + +/** * ieee80211_update_mu_groups - set the VHT MU-MIMO groud data * * @vif: the specified virtual interface diff --git a/include/net/macsec.h b/include/net/macsec.h index 5b9c61c4d3a6..441ed8fd4b5f 100644 --- a/include/net/macsec.h +++ b/include/net/macsec.h @@ -8,6 +8,7 @@ #define _NET_MACSEC_H_ #include <linux/u64_stats_sync.h> +#include <linux/if_vlan.h> #include <uapi/linux/if_link.h> #include <uapi/linux/if_macsec.h> @@ -312,4 +313,13 @@ static inline bool macsec_send_sci(const struct macsec_secy *secy) (secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb); } +static inline void *macsec_netdev_priv(const struct net_device *dev) +{ +#if IS_ENABLED(CONFIG_VLAN_8021Q) + if (is_vlan_dev(dev)) + return netdev_priv(vlan_dev_priv(dev)->real_dev); +#endif + return netdev_priv(dev); +} + #endif /* _NET_MACSEC_H_ */ diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index cd386aa7c7cc..024ad8ddb27e 100644 --- a/include/net/mana/mana.h +++ b/include/net/mana/mana.h @@ -347,10 +347,8 @@ struct mana_tx_qp { struct mana_ethtool_stats { u64 stop_queue; u64 wake_queue; - u64 tx_cqes; u64 tx_cqe_err; u64 tx_cqe_unknown_type; - u64 rx_cqes; u64 rx_coalesced_err; u64 rx_cqe_unknown_type; }; @@ -581,7 +579,7 @@ struct mana_fence_rq_resp { }; /* HW DATA */ /* Configure vPort Rx Steering */ -struct mana_cfg_rx_steer_req { +struct mana_cfg_rx_steer_req_v2 { struct gdma_req_hdr hdr; mana_handle_t vport; u16 num_indir_entries; @@ -594,6 +592,8 @@ struct mana_cfg_rx_steer_req { u8 reserved; mana_handle_t default_rxobj; u8 hashkey[MANA_HASH_KEY_SIZE]; + u8 cqe_coalescing_enable; + u8 reserved2[7]; }; /* HW DATA */ struct mana_cfg_rx_steer_resp { diff --git a/include/net/mctp.h b/include/net/mctp.h index 82800d521c3d..da86e106c91d 100644 --- a/include/net/mctp.h +++ b/include/net/mctp.h @@ -234,9 +234,9 @@ struct mctp_flow { struct mctp_route { mctp_eid_t min, max; - struct mctp_dev *dev; - unsigned int mtu; unsigned char type; + unsigned int mtu; + struct mctp_dev *dev; int (*output)(struct mctp_route *route, struct sk_buff *skb); diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 3fa5774bddac..f6a8ecc6b1fa 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -180,7 +180,7 @@ struct pneigh_entry { netdevice_tracker dev_tracker; u32 flags; u8 protocol; - u8 key[]; + u32 key[]; }; /* diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 0855b60fba17..cf0d81be5a96 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -26,6 +26,15 @@ struct nf_conntrack_expect { struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple_mask mask; + /* Usage count. */ + refcount_t use; + + /* Flags */ + unsigned int flags; + + /* Expectation class */ + unsigned int class; + /* Function to call after setup and insertion */ void (*expectfn)(struct nf_conn *new, struct nf_conntrack_expect *this); @@ -39,15 +48,6 @@ struct nf_conntrack_expect { /* Timer function; deletes the expectation. */ struct timer_list timeout; - /* Usage count. */ - refcount_t use; - - /* Flags */ - unsigned int flags; - - /* Expectation class */ - unsigned int class; - #if IS_ENABLED(CONFIG_NF_NAT) union nf_inet_addr saved_addr; /* This is the original per-proto part, used to map the diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index ebb28ec5b6fa..d466e1a3b0b1 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -263,12 +263,12 @@ nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, up_write(&flow_table->flow_block_lock); } -int flow_offload_route_init(struct flow_offload *flow, - const struct nf_flow_route *route); +void flow_offload_route_init(struct flow_offload *flow, + const struct nf_flow_route *route); int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); void flow_offload_refresh(struct nf_flowtable *flow_table, - struct flow_offload *flow); + struct flow_offload *flow, bool force); struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, struct flow_offload_tuple *tuple); diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 2e24ea1d744c..84f2fd85fd5a 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -462,7 +462,8 @@ struct nft_set_ops { const struct nft_set *set, const struct nft_set_elem *elem, unsigned int flags); - + void (*commit)(const struct nft_set *set); + void (*abort)(const struct nft_set *set); u64 (*privsize)(const struct nlattr * const nla[], const struct nft_set_desc *desc); bool (*estimate)(const struct nft_set_desc *desc, @@ -471,7 +472,8 @@ struct nft_set_ops { int (*init)(const struct nft_set *set, const struct nft_set_desc *desc, const struct nlattr * const nla[]); - void (*destroy)(const struct nft_set *set); + void (*destroy)(const struct nft_ctx *ctx, + const struct nft_set *set); void (*gc_init)(const struct nft_set *set); unsigned int elemsize; @@ -557,6 +559,7 @@ struct nft_set { u16 policy; u16 udlen; unsigned char *udata; + struct list_head pending_update; /* runtime data below here */ const struct nft_set_ops *ops ____cacheline_aligned; u16 flags:14, @@ -807,6 +810,8 @@ int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, struct nft_expr *expr_array[]); void nft_set_elem_destroy(const struct nft_set *set, void *elem, bool destroy_expr); +void nf_tables_set_elem_destroy(const struct nft_ctx *ctx, + const struct nft_set *set, void *elem); /** * struct nft_set_gc_batch_head - nf_tables set garbage collection batch @@ -899,6 +904,7 @@ struct nft_expr_type { enum nft_trans_phase { NFT_TRANS_PREPARE, + NFT_TRANS_PREPARE_ERROR, NFT_TRANS_ABORT, NFT_TRANS_COMMIT, NFT_TRANS_RELEASE @@ -1007,7 +1013,10 @@ static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule) return (void *)&rule->data[rule->dlen]; } -void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule); +void nft_rule_expr_activate(const struct nft_ctx *ctx, struct nft_rule *rule); +void nft_rule_expr_deactivate(const struct nft_ctx *ctx, struct nft_rule *rule, + enum nft_trans_phase phase); +void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule); static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext, struct nft_regs *regs, @@ -1102,6 +1111,8 @@ int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, const struct nft_set_iter *iter, struct nft_set_elem *elem); int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set); +int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); +void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); enum nft_chain_types { NFT_CHAIN_T_DEFAULT = 0, @@ -1138,11 +1149,17 @@ int nft_chain_validate_dependency(const struct nft_chain *chain, int nft_chain_validate_hooks(const struct nft_chain *chain, unsigned int hook_flags); +static inline bool nft_chain_binding(const struct nft_chain *chain) +{ + return chain->flags & NFT_CHAIN_BINDING; +} + static inline bool nft_chain_is_bound(struct nft_chain *chain) { return (chain->flags & NFT_CHAIN_BINDING) && chain->bound; } +int nft_chain_add(struct nft_table *table, struct nft_chain *chain); void nft_chain_del(struct nft_chain *chain); void nf_tables_chain_destroy(struct nft_ctx *ctx); @@ -1556,6 +1573,7 @@ static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) * struct nft_trans - nf_tables object update in transaction * * @list: used internally + * @binding_list: list of objects with possible bindings * @msg_type: message type * @put_net: ctx->net needs to be put * @ctx: transaction context @@ -1563,6 +1581,7 @@ static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) */ struct nft_trans { struct list_head list; + struct list_head binding_list; int msg_type; bool put_net; struct nft_ctx ctx; @@ -1573,6 +1592,7 @@ struct nft_trans_rule { struct nft_rule *rule; struct nft_flow_rule *flow; u32 rule_id; + bool bound; }; #define nft_trans_rule(trans) \ @@ -1581,6 +1601,8 @@ struct nft_trans_rule { (((struct nft_trans_rule *)trans->data)->flow) #define nft_trans_rule_id(trans) \ (((struct nft_trans_rule *)trans->data)->rule_id) +#define nft_trans_rule_bound(trans) \ + (((struct nft_trans_rule *)trans->data)->bound) struct nft_trans_set { struct nft_set *set; @@ -1589,6 +1611,7 @@ struct nft_trans_set { u64 timeout; bool update; bool bound; + u32 size; }; #define nft_trans_set(trans) \ @@ -1603,17 +1626,23 @@ struct nft_trans_set { (((struct nft_trans_set *)trans->data)->timeout) #define nft_trans_set_gc_int(trans) \ (((struct nft_trans_set *)trans->data)->gc_int) +#define nft_trans_set_size(trans) \ + (((struct nft_trans_set *)trans->data)->size) struct nft_trans_chain { + struct nft_chain *chain; bool update; char *name; struct nft_stats __percpu *stats; u8 policy; + bool bound; u32 chain_id; struct nft_base_chain *basechain; struct list_head hook_list; }; +#define nft_trans_chain(trans) \ + (((struct nft_trans_chain *)trans->data)->chain) #define nft_trans_chain_update(trans) \ (((struct nft_trans_chain *)trans->data)->update) #define nft_trans_chain_name(trans) \ @@ -1622,6 +1651,8 @@ struct nft_trans_chain { (((struct nft_trans_chain *)trans->data)->stats) #define nft_trans_chain_policy(trans) \ (((struct nft_trans_chain *)trans->data)->policy) +#define nft_trans_chain_bound(trans) \ + (((struct nft_trans_chain *)trans->data)->bound) #define nft_trans_chain_id(trans) \ (((struct nft_trans_chain *)trans->data)->chain_id) #define nft_trans_basechain(trans) \ @@ -1698,6 +1729,7 @@ static inline int nft_request_module(struct net *net, const char *fmt, ...) { re struct nftables_pernet { struct list_head tables; struct list_head commit_list; + struct list_head binding_list; struct list_head module_list; struct list_head notify_list; struct mutex commit_mutex; diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index db762e35aca9..f00374718159 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -65,6 +65,7 @@ struct netns_ipv4 { #endif bool fib_has_custom_local_routes; bool fib_offload_disabled; + u8 sysctl_tcp_shrink_window; #ifdef CONFIG_IP_ROUTE_CLASSID atomic_t fib_num_tclassid_users; #endif @@ -194,6 +195,7 @@ struct netns_ipv4 { int sysctl_udp_rmem_min; u8 sysctl_fib_notify_on_flag_change; + u8 sysctl_tcp_syn_linear_timeouts; #ifdef CONFIG_NET_L3_MASTER_DEV u8 sysctl_udp_l3mdev_accept; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 3cceb3e9320b..5f2cfd84570a 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -53,7 +53,7 @@ struct netns_sysctl_ipv6 { int seg6_flowlabel; u32 ioam6_id; u64 ioam6_id_wide; - bool skip_notify_on_dev_down; + u8 skip_notify_on_dev_down; u8 fib_notify_on_flag_change; u8 icmpv6_error_anycast_as_unicast; }; diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 9fa291a04621..2b12725de9c0 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -497,29 +497,6 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) return NULL; } -/* Variant of nexthop_fib6_nh(). - * Caller should either hold rcu_read_lock(), or RTNL. - */ -static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) -{ - struct nh_info *nhi; - - if (nh->is_group) { - struct nh_group *nh_grp; - - nh_grp = rcu_dereference_rtnl(nh->nh_grp); - nh = nexthop_mpath_select(nh_grp, 0); - if (!nh) - return NULL; - } - - nhi = rcu_dereference_rtnl(nh->nh_info); - if (nhi->family == AF_INET6) - return &nhi->fib6_nh; - - return NULL; -} - static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) { struct fib6_nh *fib6_nh; diff --git a/include/net/page_pool.h b/include/net/page_pool.h index c8ec2f34722b..126f9e294389 100644 --- a/include/net/page_pool.h +++ b/include/net/page_pool.h @@ -399,22 +399,4 @@ static inline void page_pool_nid_changed(struct page_pool *pool, int new_nid) page_pool_update_nid(pool, new_nid); } -static inline void page_pool_ring_lock(struct page_pool *pool) - __acquires(&pool->ring.producer_lock) -{ - if (in_softirq()) - spin_lock(&pool->ring.producer_lock); - else - spin_lock_bh(&pool->ring.producer_lock); -} - -static inline void page_pool_ring_unlock(struct page_pool *pool) - __releases(&pool->ring.producer_lock) -{ - if (in_softirq()) - spin_unlock(&pool->ring.producer_lock); - else - spin_unlock_bh(&pool->ring.producer_lock); -} - #endif /* _NET_PAGE_POOL_H */ diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index 862f1719b523..cf5ecae4a2fc 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -109,4 +109,25 @@ void phonet_sysctl_exit(void); int isi_register(void); void isi_unregister(void); +static inline bool sk_is_phonet(struct sock *sk) +{ + return sk->sk_family == PF_PHONET; +} + +static inline int phonet_sk_ioctl(struct sock *sk, unsigned int cmd, + void __user *arg) +{ + int karg; + + switch (cmd) { + case SIOCPNADDRESOURCE: + case SIOCPNDELRESOURCE: + if (get_user(karg, (int __user *)arg)) + return -EFAULT; + + return sk->sk_prot->ioctl(sk, cmd, &karg); + } + /* A positive return value means that the ioctl was not processed */ + return 1; +} #endif diff --git a/include/net/ping.h b/include/net/ping.h index 9233ad3de0ad..bc7779262e60 100644 --- a/include/net/ping.h +++ b/include/net/ping.h @@ -16,11 +16,7 @@ #define PING_HTABLE_SIZE 64 #define PING_HTABLE_MASK (PING_HTABLE_SIZE-1) -/* - * gid_t is either uint or ushort. We want to pass it to - * proc_dointvec_minmax(), so it must not be larger than MAX_INT - */ -#define GID_T_MAX (((gid_t)~0U) >> 1) +#define GID_T_MAX (((gid_t)~0U) - 1) /* Compatibility glue so we can support IPv6 when it's compiled as a module */ struct pingv6_ops { diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index b3b5b0b62f16..a2ea45c7b53e 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -868,6 +868,7 @@ struct tc_htb_qopt_offload { u16 qid; u64 rate; u64 ceil; + u8 prio; }; #define TC_HTB_CLASSID_ROOT U32_MAX diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index f436688b6efc..e98aac9d5ad5 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -127,6 +127,8 @@ static inline void qdisc_run(struct Qdisc *q) } } +extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; + /* Calculate maximal size of packet seen by hard_start_xmit routine of this device. */ @@ -185,6 +187,32 @@ struct tc_taprio_caps { bool broken_mqprio:1; }; +enum tc_taprio_qopt_cmd { + TAPRIO_CMD_REPLACE, + TAPRIO_CMD_DESTROY, + TAPRIO_CMD_STATS, + TAPRIO_CMD_QUEUE_STATS, +}; + +/** + * struct tc_taprio_qopt_stats - IEEE 802.1Qbv statistics + * @window_drops: Frames that were dropped because they were too large to be + * transmitted in any of the allotted time windows (open gates) for their + * traffic class. + * @tx_overruns: Frames still being transmitted by the MAC after the + * transmission gate associated with their traffic class has closed. + * Equivalent to `12.29.1.1.2 TransmissionOverrun` from 802.1Q-2018. + */ +struct tc_taprio_qopt_stats { + u64 window_drops; + u64 tx_overruns; +}; + +struct tc_taprio_qopt_queue_stats { + int queue; + struct tc_taprio_qopt_stats stats; +}; + struct tc_taprio_sched_entry { u8 command; /* TC_TAPRIO_CMD_* */ @@ -194,16 +222,26 @@ struct tc_taprio_sched_entry { }; struct tc_taprio_qopt_offload { - struct tc_mqprio_qopt_offload mqprio; - struct netlink_ext_ack *extack; - u8 enable; - ktime_t base_time; - u64 cycle_time; - u64 cycle_time_extension; - u32 max_sdu[TC_MAX_QUEUE]; - - size_t num_entries; - struct tc_taprio_sched_entry entries[]; + enum tc_taprio_qopt_cmd cmd; + + union { + /* TAPRIO_CMD_STATS */ + struct tc_taprio_qopt_stats stats; + /* TAPRIO_CMD_QUEUE_STATS */ + struct tc_taprio_qopt_queue_stats queue_stats; + /* TAPRIO_CMD_REPLACE */ + struct { + struct tc_mqprio_qopt_offload mqprio; + struct netlink_ext_ack *extack; + ktime_t base_time; + u64 cycle_time; + u64 cycle_time_extension; + u32 max_sdu[TC_MAX_QUEUE]; + + size_t num_entries; + struct tc_taprio_sched_entry entries[]; + }; + }; }; #if IS_ENABLED(CONFIG_NET_SCH_TAPRIO) diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 896191f420d5..b2cb4a9eb04d 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -140,17 +140,6 @@ struct regulatory_request { * otherwise initiating radiation is not allowed. This will enable the * relaxations enabled under the CFG80211_REG_RELAX_NO_IR configuration * option - * @REGULATORY_IGNORE_STALE_KICKOFF: the regulatory core will _not_ make sure - * all interfaces on this wiphy reside on allowed channels. If this flag - * is not set, upon a regdomain change, the interfaces are given a grace - * period (currently 60 seconds) to disconnect or move to an allowed - * channel. Interfaces on forbidden channels are forcibly disconnected. - * Currently these types of interfaces are supported for enforcement: - * NL80211_IFTYPE_ADHOC, NL80211_IFTYPE_STATION, NL80211_IFTYPE_AP, - * NL80211_IFTYPE_AP_VLAN, NL80211_IFTYPE_MONITOR, - * NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, - * NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device - * includes any modes unsupported for enforcement checking. * @REGULATORY_WIPHY_SELF_MANAGED: for devices that employ wiphy-specific * regdom management. These devices will ignore all regdom changes not * originating from their own wiphy. @@ -177,7 +166,7 @@ enum ieee80211_regulatory_flags { REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3), REGULATORY_COUNTRY_IE_IGNORE = BIT(4), REGULATORY_ENABLE_RELAX_NO_IR = BIT(5), - REGULATORY_IGNORE_STALE_KICKOFF = BIT(6), + /* reuse bit 6 next time */ REGULATORY_WIPHY_SELF_MANAGED = BIT(7), }; diff --git a/include/net/route.h b/include/net/route.h index bcc367cf3aa2..5a5c726472bd 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -321,8 +321,7 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4, __be32 dst, if (IS_ERR(rt)) return rt; ip_rt_put(rt); - flowi4_update_output(fl4, oif, fl4->flowi4_tos, fl4->daddr, - fl4->saddr); + flowi4_update_output(fl4, oif, fl4->daddr, fl4->saddr); } security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); return ip_route_output_flow(net, fl4, sk); @@ -337,8 +336,7 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable fl4->fl4_dport = dport; fl4->fl4_sport = sport; ip_rt_put(rt); - flowi4_update_output(fl4, sk->sk_bound_dev_if, - RT_CONN_FLAGS(sk), fl4->daddr, + flowi4_update_output(fl4, sk->sk_bound_dev_if, fl4->daddr, fl4->saddr); security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); return ip_route_output_flow(sock_net(sk), fl4, sk); diff --git a/include/net/rpl.h b/include/net/rpl.h index 308ef0a05cae..74734191c458 100644 --- a/include/net/rpl.h +++ b/include/net/rpl.h @@ -23,12 +23,6 @@ static inline int rpl_init(void) static inline void rpl_exit(void) {} #endif -/* Worst decompression memory usage ipv6 address (16) + pad 7 */ -#define IPV6_RPL_SRH_WORST_SWAP_SIZE (sizeof(struct in6_addr) + 7) - -size_t ipv6_rpl_srh_size(unsigned char n, unsigned char cmpri, - unsigned char cmpre); - void ipv6_rpl_srh_decompress(struct ipv6_rpl_sr_hdr *outhdr, const struct ipv6_rpl_sr_hdr *inhdr, const struct in6_addr *daddr, unsigned char n); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index fab5ba3e61b7..e92f73bb3198 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -137,6 +137,13 @@ static inline void qdisc_refcount_inc(struct Qdisc *qdisc) refcount_inc(&qdisc->refcnt); } +static inline bool qdisc_refcount_dec_if_one(struct Qdisc *qdisc) +{ + if (qdisc->flags & TCQ_F_BUILTIN) + return true; + return refcount_dec_if_one(&qdisc->refcnt); +} + /* Intended to be used by unlocked users, when concurrent qdisc release is * possible. */ @@ -545,7 +552,7 @@ static inline struct Qdisc *qdisc_root_bh(const struct Qdisc *qdisc) static inline struct Qdisc *qdisc_root_sleeping(const struct Qdisc *qdisc) { - return qdisc->dev_queue->qdisc_sleeping; + return rcu_dereference_rtnl(qdisc->dev_queue->qdisc_sleeping); } static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc) @@ -652,6 +659,7 @@ void dev_deactivate_many(struct list_head *head); struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, struct Qdisc *qdisc); void qdisc_reset(struct Qdisc *qdisc); +void qdisc_destroy(struct Qdisc *qdisc); void qdisc_put(struct Qdisc *qdisc); void qdisc_put_unlocked(struct Qdisc *qdisc); void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, int n, int len); @@ -754,7 +762,9 @@ static inline bool qdisc_tx_changing(const struct net_device *dev) for (i = 0; i < dev->num_tx_queues; i++) { struct netdev_queue *txq = netdev_get_tx_queue(dev, i); - if (rcu_access_pointer(txq->qdisc) != txq->qdisc_sleeping) + + if (rcu_access_pointer(txq->qdisc) != + rcu_access_pointer(txq->qdisc_sleeping)) return true; } return false; @@ -1180,20 +1190,6 @@ static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch, return NET_XMIT_DROP; } -/* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how - long it will take to send a packet given its size. - */ -static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) -{ - int slot = pktlen + rtab->rate.cell_align + rtab->rate.overhead; - if (slot < 0) - slot = 0; - slot >>= rtab->rate.cell_log; - if (slot > 255) - return rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]; - return rtab->data[slot]; -} - struct psched_ratecfg { u64 rate_bytes_ps; /* bytes per second */ u32 mult; diff --git a/include/net/scm.h b/include/net/scm.h index 585adc1346bd..c5bcdf65f55c 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -120,15 +120,49 @@ static inline bool scm_has_secdata(struct socket *sock) } #endif /* CONFIG_SECURITY_NETWORK */ -static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, - struct scm_cookie *scm, int flags) +static __inline__ void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm) +{ + struct file *pidfd_file = NULL; + int pidfd; + + /* + * put_cmsg() doesn't return an error if CMSG is truncated, + * that's why we need to opencode these checks here. + */ + if ((msg->msg_controllen <= sizeof(struct cmsghdr)) || + (msg->msg_controllen - sizeof(struct cmsghdr)) < sizeof(int)) { + msg->msg_flags |= MSG_CTRUNC; + return; + } + + if (!scm->pid) + return; + + pidfd = pidfd_prepare(scm->pid, 0, &pidfd_file); + + if (put_cmsg(msg, SOL_SOCKET, SCM_PIDFD, sizeof(int), &pidfd)) { + if (pidfd_file) { + put_unused_fd(pidfd); + fput(pidfd_file); + } + + return; + } + + if (pidfd_file) + fd_install(pidfd, pidfd_file); +} + +static inline bool __scm_recv_common(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags) { if (!msg->msg_control) { - if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp || - scm_has_secdata(sock)) + if (test_bit(SOCK_PASSCRED, &sock->flags) || + test_bit(SOCK_PASSPIDFD, &sock->flags) || + scm->fp || scm_has_secdata(sock)) msg->msg_flags |= MSG_CTRUNC; scm_destroy(scm); - return; + return false; } if (test_bit(SOCK_PASSCRED, &sock->flags)) { @@ -141,16 +175,34 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds); } - scm_destroy_cred(scm); - scm_passec(sock, msg, scm); - if (!scm->fp) + if (scm->fp) + scm_detach_fds(msg, scm); + + return true; +} + +static inline void scm_recv(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags) +{ + if (!__scm_recv_common(sock, msg, scm, flags)) return; - - scm_detach_fds(msg, scm); + + scm_destroy_cred(scm); } +static inline void scm_recv_unix(struct socket *sock, struct msghdr *msg, + struct scm_cookie *scm, int flags) +{ + if (!__scm_recv_common(sock, msg, scm, flags)) + return; + + if (test_bit(SOCK_PASSPIDFD, &sock->flags)) + scm_pidfd_recv(msg, scm); + + scm_destroy_cred(scm); +} #endif /* __LINUX_NET_SCM_H */ diff --git a/include/net/sock.h b/include/net/sock.h index 8b7ed7167243..2eb916d1ff64 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -336,6 +336,7 @@ struct sk_filter; * @sk_cgrp_data: cgroup data for this cgroup * @sk_memcg: this socket's memory cgroup association * @sk_write_pending: a write to stream socket waits to start + * @sk_wait_pending: number of threads blocked on this socket * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed * @sk_write_space: callback to indicate there is bf sending space available @@ -428,6 +429,7 @@ struct sock { unsigned int sk_napi_id; #endif int sk_rcvbuf; + int sk_wait_pending; struct sk_filter __rcu *sk_filter; union { @@ -1150,8 +1152,12 @@ static inline void sock_rps_record_flow(const struct sock *sk) * OR an additional socket flag * [1] : sk_state and sk_prot are in the same cache line. */ - if (sk->sk_state == TCP_ESTABLISHED) - sock_rps_record_flow_hash(sk->sk_rxhash); + if (sk->sk_state == TCP_ESTABLISHED) { + /* This READ_ONCE() is paired with the WRITE_ONCE() + * from sock_rps_save_rxhash() and sock_rps_reset_rxhash(). + */ + sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash)); + } } #endif } @@ -1160,20 +1166,25 @@ static inline void sock_rps_save_rxhash(struct sock *sk, const struct sk_buff *skb) { #ifdef CONFIG_RPS - if (unlikely(sk->sk_rxhash != skb->hash)) - sk->sk_rxhash = skb->hash; + /* The following WRITE_ONCE() is paired with the READ_ONCE() + * here, and another one in sock_rps_record_flow(). + */ + if (unlikely(READ_ONCE(sk->sk_rxhash) != skb->hash)) + WRITE_ONCE(sk->sk_rxhash, skb->hash); #endif } static inline void sock_rps_reset_rxhash(struct sock *sk) { #ifdef CONFIG_RPS - sk->sk_rxhash = 0; + /* Paired with READ_ONCE() in sock_rps_record_flow() */ + WRITE_ONCE(sk->sk_rxhash, 0); #endif } #define sk_wait_event(__sk, __timeo, __condition, __wait) \ ({ int __rc; \ + __sk->sk_wait_pending++; \ release_sock(__sk); \ __rc = __condition; \ if (!__rc) { \ @@ -1183,6 +1194,7 @@ static inline void sock_rps_reset_rxhash(struct sock *sk) } \ sched_annotate_sleep(); \ lock_sock(__sk); \ + __sk->sk_wait_pending--; \ __rc = __condition; \ __rc; \ }) @@ -1246,7 +1258,7 @@ struct proto { bool kern); int (*ioctl)(struct sock *sk, int cmd, - unsigned long arg); + int *karg); int (*init)(struct sock *sk); void (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); @@ -1265,8 +1277,7 @@ struct proto { size_t len); int (*recvmsg)(struct sock *sk, struct msghdr *msg, size_t len, int flags, int *addr_len); - int (*sendpage)(struct sock *sk, struct page *page, - int offset, size_t size, int flags); + void (*splice_eof)(struct socket *sock); int (*bind)(struct sock *sk, struct sockaddr *addr, int addr_len); int (*bind_add)(struct sock *sk, @@ -1906,10 +1917,6 @@ int sock_no_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t len); int sock_no_recvmsg(struct socket *, struct msghdr *, size_t, int); int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma); -ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, - size_t size, int flags); -ssize_t sock_no_sendpage_locked(struct sock *sk, struct page *page, - int offset, size_t size, int flags); /* * Functions to fill in entries in struct proto_ops when a protocol @@ -2088,6 +2095,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) } kuid_t sock_i_uid(struct sock *sk); +unsigned long __sock_i_ino(struct sock *sk); unsigned long sock_i_ino(struct sock *sk); static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk) @@ -2718,7 +2726,7 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk, __sock_recv_cmsgs(msg, sk, skb); else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) sock_write_timestamp(sk, skb->tstamp); - else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP)) + else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP)) sock_write_timestamp(sk, 0); } @@ -2961,6 +2969,9 @@ int sock_get_timeout(long timeo, void *optval, bool old_timeval); int sock_copy_user_timeval(struct __kernel_sock_timeval *tv, sockptr_t optval, int optlen, bool old_timeval); +int sock_ioctl_inout(struct sock *sk, unsigned int cmd, + void __user *arg, void *karg, size_t size); +int sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); static inline bool sk_is_readable(struct sock *sk) { if (sk->sk_prot->sock_is_readable) diff --git a/include/net/tcp.h b/include/net/tcp.h index 04a31643cda3..226bce6d1e8c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -45,6 +45,7 @@ #include <linux/memcontrol.h> #include <linux/bpf-cgroup.h> #include <linux/siphash.h> +#include <linux/net_mm.h> extern struct inet_hashinfo tcp_hashinfo; @@ -161,8 +162,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define MAX_TCP_KEEPCNT 127 #define MAX_TCP_SYNCNT 127 -#define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ - #define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) #define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated * after this time. It should be equal @@ -329,20 +328,16 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size); int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size); int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied, size_t size, struct ubuf_info *uarg); -int tcp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, - int flags); -int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, - size_t size, int flags); -ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, - size_t size, int flags); +void tcp_splice_eof(struct socket *sock); int tcp_send_mss(struct sock *sk, int *size_goal, int flags); +int tcp_wmem_schedule(struct sock *sk, int copy); void tcp_push(struct sock *sk, int flags, int mss_now, int nonagle, int size_goal); void tcp_release_cb(struct sock *sk); void tcp_wfree(struct sk_buff *skb); void tcp_write_timer_handler(struct sock *sk); void tcp_delack_timer_handler(struct sock *sk); -int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); +int tcp_ioctl(struct sock *sk, int cmd, int *karg); int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb); void tcp_rcv_established(struct sock *sk, struct sk_buff *skb); void tcp_rcv_space_adjust(struct sock *sk); @@ -352,7 +347,7 @@ void tcp_twsk_purge(struct list_head *net_exit_list, int family); ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); -struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, +struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, gfp_t gfp, bool force_schedule); void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks); @@ -632,6 +627,7 @@ void tcp_reset(struct sock *sk, struct sk_buff *skb); void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); void tcp_fin(struct sock *sk); void tcp_check_space(struct sock *sk); +void tcp_sack_compress_send_ack(struct sock *sk); /* tcp_timer.c */ void tcp_init_xmit_timers(struct sock *); @@ -1470,6 +1466,8 @@ static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) } void tcp_cleanup_rbuf(struct sock *sk, int copied); +void __tcp_cleanup_rbuf(struct sock *sk, int copied); + /* We provision sk_rcvbuf around 200% of sk_rcvlowat. * If 87.5 % (7/8) of the space has been consumed, we want to override @@ -2043,7 +2041,7 @@ INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff)) INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)); INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff)); INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb)); -int tcp_gro_complete(struct sk_buff *skb); +void tcp_gro_complete(struct sk_buff *skb); void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr); @@ -2326,6 +2324,14 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore); void tcp_bpf_clone(const struct sock *sk, struct sock *newsk); #endif /* CONFIG_BPF_SYSCALL */ +#ifdef CONFIG_INET +void tcp_eat_skb(struct sock *sk, struct sk_buff *skb); +#else +static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb) +{ +} +#endif + int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress, struct sk_msg *msg, u32 bytes, int flags); #endif /* CONFIG_NET_SOCK_MSG */ diff --git a/include/net/tls.h b/include/net/tls.h index 6056ce5a2aa5..5e71dd3df8ca 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -126,6 +126,7 @@ struct tls_strparser { u32 mark : 8; u32 stopped : 1; u32 copy_mode : 1; + u32 mixed_decrypted : 1; u32 msg_ready : 1; struct strp_msg stm; @@ -258,7 +259,7 @@ struct tls_context { struct scatterlist *partially_sent_record; u16 partially_sent_offset; - bool in_tcp_sendpages; + bool splicing_pages; bool pending_open_record_frags; struct mutex tx_lock; /* protects partially_sent_* fields and @@ -369,10 +370,12 @@ struct sk_buff * tls_validate_xmit_skb_sw(struct sock *sk, struct net_device *dev, struct sk_buff *skb); -static inline bool tls_is_sk_tx_device_offloaded(struct sock *sk) +static inline bool tls_is_skb_tx_device_offloaded(const struct sk_buff *skb) { -#ifdef CONFIG_SOCK_VALIDATE_XMIT - return sk_fullsock(sk) && +#ifdef CONFIG_TLS_DEVICE + struct sock *sk = skb->sk; + + return sk && sk_fullsock(sk) && (smp_load_acquire(&sk->sk_validate_xmit_skb) == &tls_validate_xmit_skb); #else diff --git a/include/net/udp.h b/include/net/udp.h index de4b528522bb..4d13424f8f72 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -21,6 +21,7 @@ #include <linux/list.h> #include <linux/bug.h> #include <net/inet_sock.h> +#include <net/gso.h> #include <net/sock.h> #include <net/snmp.h> #include <net/ip.h> @@ -278,12 +279,13 @@ int udp_get_port(struct sock *sk, unsigned short snum, int udp_err(struct sk_buff *, u32); int udp_abort(struct sock *sk, int err); int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); +void udp_splice_eof(struct socket *sock); int udp_push_pending_frames(struct sock *sk); void udp_flush_pending_frames(struct sock *sk); int udp_cmsg_send(struct sock *sk, struct msghdr *msg, u16 *gso_size); void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst); int udp_rcv(struct sk_buff *skb); -int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +int udp_ioctl(struct sock *sk, int cmd, int *karg); int udp_init_sock(struct sock *sk); int udp_pre_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); int __udp_disconnect(struct sock *sk, int flags); @@ -437,7 +439,6 @@ struct udp_seq_afinfo { struct udp_iter_state { struct seq_net_private p; int bucket; - struct udp_seq_afinfo *bpf_seq_afinfo; }; void *udp_seq_start(struct seq_file *seq, loff_t *pos); diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 20bd7d893e10..0be91ca78d3a 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -328,6 +328,7 @@ struct vxlan_dev { #define VXLAN_F_TTL_INHERIT 0x10000 #define VXLAN_F_VNIFILTER 0x20000 #define VXLAN_F_MDB 0x40000 +#define VXLAN_F_LOCALBYPASS 0x80000 /* Flags that are used in the receive path. These flags must match in * order for a socket to be shareable @@ -348,7 +349,8 @@ struct vxlan_dev { VXLAN_F_UDP_ZERO_CSUM6_TX | \ VXLAN_F_UDP_ZERO_CSUM6_RX | \ VXLAN_F_COLLECT_METADATA | \ - VXLAN_F_VNIFILTER) + VXLAN_F_VNIFILTER | \ + VXLAN_F_LOCALBYPASS) struct net_device *vxlan_dev_create(struct net *net, const char *name, u8 name_assign_type, struct vxlan_config *conf); diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 9c0d860609ba..c243f906ebed 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -255,10 +255,6 @@ static inline void xsk_buff_free(struct xdp_buff *xdp) { } -static inline void xsk_buff_discard(struct xdp_buff *xdp) -{ -} - static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size) { } diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 33ee3f5936e6..151ca95dd08d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1054,6 +1054,7 @@ struct xfrm_offload { struct sec_path { int len; int olen; + int verified_cnt; struct xfrm_state *xvec[XFRM_MAX_DEPTH]; struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH]; diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h index d318c769b445..a8d7b8a3688a 100644 --- a/include/net/xsk_buff_pool.h +++ b/include/net/xsk_buff_pool.h @@ -180,7 +180,7 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool, if (likely(!cross_pg)) return false; - return pool->dma_pages_cnt && + return pool->dma_pages && !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK); } diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index d808dc3d239e..811a0f11d0db 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -194,29 +194,6 @@ static inline enum ib_mtu iboe_get_mtu(int mtu) return 0; } -static inline int iboe_get_rate(struct net_device *dev) -{ - struct ethtool_link_ksettings cmd; - int err; - - rtnl_lock(); - err = __ethtool_get_link_ksettings(dev, &cmd); - rtnl_unlock(); - if (err) - return IB_RATE_PORT_CURRENT; - - if (cmd.base.speed >= 40000) - return IB_RATE_40_GBPS; - else if (cmd.base.speed >= 30000) - return IB_RATE_30_GBPS; - else if (cmd.base.speed >= 20000) - return IB_RATE_20_GBPS; - else if (cmd.base.speed >= 10000) - return IB_RATE_10_GBPS; - else - return IB_RATE_PORT_CURRENT; -} - static inline int rdma_link_local_addr(struct in6_addr *addr) { if (addr->s6_addr32[0] == htonl(0xfe800000) && diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h index 9d45a5b20316..06287de69cd2 100644 --- a/include/rdma/uverbs_ioctl.h +++ b/include/rdma/uverbs_ioctl.h @@ -436,8 +436,10 @@ struct uapi_definition { }, \ ##__VA_ARGS__ #define UAPI_DEF_CHAIN_OBJ_TREE_NAMED(_object_enum, ...) \ - UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, &UVERBS_OBJECT(_object_enum), \ - ##__VA_ARGS__) + UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, \ + PTR_IF(IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS), \ + &UVERBS_OBJECT(_object_enum)), \ + ##__VA_ARGS__) /* * ======================================= diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index c2cb5f69635c..526def14e7fb 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -52,6 +52,11 @@ struct scsi_pointer { #define SCMD_TAGGED (1 << 0) #define SCMD_INITIALIZED (1 << 1) #define SCMD_LAST (1 << 2) +/* + * libata uses SCSI EH to fetch sense data for successful commands. + * SCSI EH should not overwrite scmd->result when SCMD_FORCE_EH_SUCCESS is set. + */ +#define SCMD_FORCE_EH_SUCCESS (1 << 3) #define SCMD_FAIL_IF_RECOVERING (1 << 4) /* flags preserved across unprep / reprep */ #define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING) diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h index 5b567b43e1b1..fb58715fac86 100644 --- a/include/scsi/scsi_common.h +++ b/include/scsi/scsi_common.h @@ -7,8 +7,21 @@ #define _SCSI_COMMON_H_ #include <linux/types.h> +#include <uapi/linux/pr.h> #include <scsi/scsi_proto.h> +enum scsi_pr_type { + SCSI_PR_WRITE_EXCLUSIVE = 0x01, + SCSI_PR_EXCLUSIVE_ACCESS = 0x03, + SCSI_PR_WRITE_EXCLUSIVE_REG_ONLY = 0x05, + SCSI_PR_EXCLUSIVE_ACCESS_REG_ONLY = 0x06, + SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS = 0x07, + SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS = 0x08, +}; + +enum scsi_pr_type block_pr_type_to_scsi(enum pr_type type); +enum pr_type scsi_pr_type_to_block(enum scsi_pr_type type); + static inline unsigned scsi_varlen_cdb_length(const void *hdr) { diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index f10a008e5bfa..75b2235b99e2 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -218,6 +218,9 @@ struct scsi_device { unsigned silence_suspend:1; /* Do not print runtime PM related messages */ unsigned no_vpd_size:1; /* No VPD size reported in header */ + unsigned cdl_supported:1; /* Command duration limits supported */ + unsigned cdl_enable:1; /* Enable/disable Command duration limits */ + unsigned int queue_stopped; /* request queue is quiesced */ bool offline_already; /* Device offline message logged */ @@ -364,6 +367,8 @@ extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh); extern void scsi_remove_device(struct scsi_device *); extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); void scsi_attach_vpd(struct scsi_device *sdev); +void scsi_cdl_check(struct scsi_device *sdev); +int scsi_cdl_enable(struct scsi_device *sdev, bool enable); extern struct scsi_device *scsi_device_from_queue(struct request_queue *q); extern int __must_check scsi_device_get(struct scsi_device *); @@ -421,10 +426,10 @@ extern int scsi_track_queue_full(struct scsi_device *, int); extern int scsi_set_medium_removal(struct scsi_device *, char); -extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, - unsigned char *buffer, int len, int timeout, - int retries, struct scsi_mode_data *data, - struct scsi_sense_hdr *); +int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, + int subpage, unsigned char *buffer, int len, int timeout, + int retries, struct scsi_mode_data *data, + struct scsi_sense_hdr *); extern int scsi_mode_select(struct scsi_device *sdev, int pf, int sp, unsigned char *buffer, int len, int timeout, int retries, struct scsi_mode_data *data, @@ -433,8 +438,9 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, struct scsi_sense_hdr *sshdr); extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, int buf_len); -extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, - unsigned int len, unsigned char opcode); +int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, + unsigned int len, unsigned char opcode, + unsigned short sa); extern int scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state); extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, @@ -450,7 +456,7 @@ extern void scsi_scan_target(struct device *parent, unsigned int channel, unsigned int id, u64 lun, enum scsi_scan_mode rescan); extern void scsi_target_reap(struct scsi_target *); -extern void scsi_target_block(struct device *); +void scsi_block_targets(struct Scsi_Host *shost, struct device *dev); extern void scsi_target_unblock(struct device *, enum scsi_device_state); extern void scsi_remove_target(struct device *); extern const char *scsi_device_state_name(enum scsi_device_state); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 0f29799efa02..70b7475dcf56 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -458,6 +458,9 @@ struct scsi_host_template { /* True if the host uses host-wide tagspace */ unsigned host_tagset:1; + /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */ + unsigned queuecommand_may_block:1; + /* * Countdown for host blocking with no commands outstanding. */ @@ -653,6 +656,9 @@ struct Scsi_Host { /* True if the host uses host-wide tagspace */ unsigned host_tagset:1; + /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */ + unsigned queuecommand_may_block:1; + /* Host responded with short (<36 bytes) INQUIRY result */ unsigned short_inquiry:1; diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index beac64e38b87..a207c07da9d2 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -45,11 +45,11 @@ typedef struct scsi_fctargaddress { int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); -int scsi_ioctl(struct scsi_device *sdev, fmode_t mode, int cmd, +int scsi_ioctl(struct scsi_device *sdev, bool open_for_write, int cmd, void __user *arg); int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp); int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp); -bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode); +bool scsi_cmd_allowed(unsigned char *cmd, bool open_for_write); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h index fbe5bdfe4d6e..07d65c1f59db 100644 --- a/include/scsi/scsi_proto.h +++ b/include/scsi/scsi_proto.h @@ -151,6 +151,11 @@ #define ZO_FINISH_ZONE 0x02 #define ZO_OPEN_ZONE 0x03 #define ZO_RESET_WRITE_POINTER 0x04 +/* values for PR in service action */ +#define READ_KEYS 0x00 +#define READ_RESERVATION 0x01 +#define REPORT_CAPABILITES 0x02 +#define READ_FULL_STATUS 0x03 /* values for variable length command */ #define XDREAD_32 0x03 #define XDWRITE_32 0x04 diff --git a/include/soc/imx/timer.h b/include/soc/imx/timer.h deleted file mode 100644 index 25f29c6bbd0b..000000000000 --- a/include/soc/imx/timer.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2015 Linaro Ltd. - */ - -#ifndef __SOC_IMX_TIMER_H__ -#define __SOC_IMX_TIMER_H__ - -enum imx_gpt_type { - GPT_TYPE_IMX1, /* i.MX1 */ - GPT_TYPE_IMX21, /* i.MX21/27 */ - GPT_TYPE_IMX31, /* i.MX31/35/25/37/51/6Q */ - GPT_TYPE_IMX6DL, /* i.MX6DL/SX/SL */ -}; - -#endif /* __SOC_IMX_TIMER_H__ */ diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index cb8fbb241879..22aae505c813 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -730,6 +730,11 @@ enum macaccess_entry_type { ENTRYTYPE_MACv6, }; +enum ocelot_proto { + OCELOT_PROTO_PTP_L2 = BIT(0), + OCELOT_PROTO_PTP_L4 = BIT(1), +}; + #define OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION BIT(0) #define OCELOT_QUIRK_QSGMII_PORTS_MUST_BE_UP BIT(1) @@ -775,6 +780,8 @@ struct ocelot_port { unsigned int ptp_skbs_in_flight; struct sk_buff_head tx_skbs; + unsigned int trap_proto; + u16 mrp_ring_id; u8 ptp_cmd; @@ -868,12 +875,9 @@ struct ocelot { u8 mm_supported:1; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_info; - struct hwtstamp_config hwtstamp_config; unsigned int ptp_skbs_in_flight; /* Protects the 2-step TX timestamp ID logic */ spinlock_t ts_id_lock; - /* Protects the PTP interface state */ - struct mutex ptp_lock; /* Protects the PTP clock */ spinlock_t ptp_clock_lock; struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM]; diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index a63de5da8124..3a513be50243 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2012-2023, NVIDIA CORPORATION. All rights reserved. */ #ifndef __SOC_TEGRA_FUSE_H__ @@ -17,6 +17,7 @@ #define TEGRA186 0x18 #define TEGRA194 0x19 #define TEGRA234 0x23 +#define TEGRA264 0x26 #define TEGRA_FUSE_SKU_CALIB_0 0xf0 #define TEGRA30_FUSE_SATA_CALIB 0x124 diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 51a2263e1bc5..fc3001483e62 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -13,6 +13,7 @@ #include <linux/irq.h> #include <linux/reset-controller.h> #include <linux/types.h> +#include <linux/tegra-icc.h> struct clk; struct device; @@ -26,6 +27,8 @@ struct tegra_mc_timing { struct tegra_mc_client { unsigned int id; + unsigned int bpmp_id; + enum tegra_icc_client_type type; const char *name; /* * For Tegra210 and earlier, this is the SWGROUP ID used for IOVA translations in the @@ -166,8 +169,10 @@ struct tegra_mc_icc_ops { int (*set)(struct icc_node *src, struct icc_node *dst); int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw, u32 peak_bw, u32 *agg_avg, u32 *agg_peak); + struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data); struct icc_node_data *(*xlate_extended)(struct of_phandle_args *spec, void *data); + int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak); }; struct tegra_mc_ops { @@ -214,6 +219,7 @@ struct tegra_mc_soc { }; struct tegra_mc { + struct tegra_bpmp *bpmp; struct device *dev; struct tegra_smmu *smmu; struct gart_device *gart; @@ -228,7 +234,9 @@ struct tegra_mc { struct tegra_mc_timing *timings; unsigned int num_timings; + unsigned int num_channels; + bool bwmgr_mrq_supported; struct reset_controller_dev reset; struct icc_provider provider; diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h index 18d4bc3ee0b7..ddbb6bf801bb 100644 --- a/include/sound/asequencer.h +++ b/include/sound/asequencer.h @@ -65,6 +65,10 @@ #define snd_seq_ev_is_abstime(ev) (snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS) #define snd_seq_ev_is_reltime(ev) (snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL) +/* check whether the given event is a UMP event */ +#define snd_seq_ev_is_ump(ev) \ + (IS_ENABLED(CONFIG_SND_SEQ_UMP) && ((ev)->flags & SNDRV_SEQ_EVENT_UMP)) + /* queue sync port */ #define snd_seq_queue_sync_port(q) ((q) + 16) diff --git a/include/sound/core.h b/include/sound/core.h index 3edc4ab08774..f6e0dd648b80 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -98,7 +98,7 @@ struct snd_card { struct device ctl_dev; /* control device */ unsigned int last_numid; /* last used numeric ID */ - struct rw_semaphore controls_rwsem; /* controls list lock */ + struct rw_semaphore controls_rwsem; /* controls lock (list and values) */ rwlock_t ctl_files_rwlock; /* ctl_files list lock */ int controls_count; /* count of all controls */ size_t user_ctl_alloc_size; // current memory allocation by user controls. @@ -232,7 +232,7 @@ static inline struct device *snd_card_get_device_link(struct snd_card *card) extern int snd_major; extern int snd_ecards_limit; -extern struct class *sound_class; +extern const struct class sound_class; #ifdef CONFIG_SND_DEBUG extern struct dentry *sound_debugfs_root; #endif diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 002042b1c73c..1f9713d7ca76 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -223,6 +223,7 @@ #define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001 #define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002 +#define CS35L56_MBOX_CMD_AUDIO_REINIT 0x0B000003 #define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001 #define CS35L56_MBOX_CMD_WAKEUP 0x02000002 #define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003 diff --git a/include/sound/da7219-aad.h b/include/sound/da7219-aad.h index 24ee7baa2589..41320522daa2 100644 --- a/include/sound/da7219-aad.h +++ b/include/sound/da7219-aad.h @@ -44,6 +44,11 @@ enum da7219_aad_jack_ins_deb { DA7219_AAD_JACK_INS_DEB_1S, }; +enum da7219_aad_jack_ins_det_pty { + DA7219_AAD_JACK_INS_DET_PTY_LOW = 0, + DA7219_AAD_JACK_INS_DET_PTY_HIGH, +}; + enum da7219_aad_jack_det_rate { DA7219_AAD_JACK_DET_RATE_32_64MS = 0, DA7219_AAD_JACK_DET_RATE_64_128MS, @@ -80,6 +85,7 @@ struct da7219_aad_pdata { enum da7219_aad_btn_cfg btn_cfg; enum da7219_aad_mic_det_thr mic_det_thr; enum da7219_aad_jack_ins_deb jack_ins_deb; + enum da7219_aad_jack_ins_det_pty jack_ins_det_pty; enum da7219_aad_jack_det_rate jack_det_rate; enum da7219_aad_jack_rem_deb jack_rem_deb; diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 8fe80dcee71b..386a5f3be3e0 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -38,6 +38,35 @@ #define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL)) +// This is used to define hardware bit-fields (sub-registers) by combining +// the bit shift and count with the actual register address. The passed +// mask must represent a single run of adjacent bits. +// The non-concatenating (_NC) variant should be used directly only for +// sub-registers that do not follow the <register>_<field> naming pattern. +#define SUB_REG_NC(reg, field, mask) \ + enum { \ + field ## _MASK = mask, \ + field = reg | \ + (__builtin_ctz(mask) << 16) | \ + (__builtin_popcount(mask) << 24), \ + }; +#define SUB_REG(reg, field, mask) SUB_REG_NC(reg, reg ## _ ## field, mask) + +// Macros for manipulating values of bit-fields declared using the above macros. +// Best used with constant register addresses, as otherwise quite some code is +// generated. The actual register read/write functions handle combined addresses +// automatically, so use of these macros conveys no advantage when accessing a +// single sub-register at a time. +#define REG_SHIFT(r) (((r) >> 16) & 0x1f) +#define REG_SIZE(r) (((r) >> 24) & 0x1f) +#define REG_MASK0(r) ((1U << REG_SIZE(r)) - 1U) +#define REG_MASK(r) (REG_MASK0(r) << REG_SHIFT(r)) +#define REG_VAL_GET(r, v) ((v & REG_MASK(r)) >> REG_SHIFT(r)) +#define REG_VAL_PUT(r, v) ((v) << REG_SHIFT(r)) + +// List terminator for snd_emu10k1_ptr_write_multiple() +#define REGLIST_END ~0 + // Audigy specify registers are prefixed with 'A_' /************************************************************************************************/ @@ -90,6 +119,10 @@ #define IPR_MIDITRANSBUFEMPTY 0x00000100 /* MIDI UART transmit buffer empty */ #define IPR_MIDIRECVBUFEMPTY 0x00000080 /* MIDI UART receive buffer empty */ #define IPR_CHANNELLOOP 0x00000040 /* Channel (half) loop interrupt(s) pending */ + /* The interrupt is triggered shortly after */ + /* CCR_READADDRESS has crossed the boundary; */ + /* due to the cache, this runs ahead of the */ + /* actual playback position. */ #define IPR_CHANNELNUMBERMASK 0x0000003f /* When IPR_CHANNELLOOP is set, indicates the */ /* highest set channel in CLIPL, CLIPH, HLIPL, */ /* or HLIPH. When IPR is written with CL set, */ @@ -148,12 +181,10 @@ #define INTE_MIDIRXENABLE 0x00000001 /* Enable MIDI receive-buffer-empty interrupts */ #define WC 0x10 /* Wall Clock register */ -#define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */ -#define WC_SAMPLECOUNTER 0x14060010 -#define WC_CURRENTCHANNEL_MASK 0x0000003F /* Channel [0..63] currently being serviced */ +SUB_REG(WC, SAMPLECOUNTER, 0x03FFFFC0) /* Sample periods elapsed since reset */ +SUB_REG(WC, CURRENTCHANNEL, 0x0000003F) /* Channel [0..63] currently being serviced */ /* NOTE: Each channel takes 1/64th of a sample */ /* period to be serviced. */ -#define WC_CURRENTCHANNEL 0x06000010 #define HCFG 0x14 /* Hardware config register */ /* NOTE: There is no reason to use the legacy */ @@ -225,9 +256,8 @@ /* async audio source */ #define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */ /* NOTE: This should generally never be used. */ -#define HCFG_LOCKTANKCACHE_MASK 0x00000004 /* 1 = Cancel bustmaster accesses to tankcache */ +SUB_REG(HCFG, LOCKTANKCACHE, 0x00000004) /* 1 = Cancel bustmaster accesses to tankcache */ /* NOTE: This should generally never be used. */ -#define HCFG_LOCKTANKCACHE 0x01020014 #define HCFG_MUTEBUTTONENABLE 0x00000002 /* 1 = Master mute button sets AUDIOENABLE = 0. */ /* NOTE: This is a 'cheap' way to implement a */ /* master mute function on the mute button, and */ @@ -381,56 +411,49 @@ // distortion), the modulation engine sets the target registers, towards // which the current registers "swerve" gradually. +// For the odd channel in a stereo pair, these registers are meaningless: +// CPF_STEREO, CPF_CURRENTPITCH, PTRX_PITCHTARGET, CCR_CACHEINVALIDSIZE, +// PSST_LOOPSTARTADDR, DSL_LOOPENDADDR, CCCA_CURRADDR +// The somewhat non-obviously still meaningful ones are: +// CPF_STOP, CPF_FRACADDRESS, CCR_READADDRESS (!), +// CCCA_INTERPROM, CCCA_8BITSELECT (!) +// (The envelope engine is ignored here, as stereo matters only for verbatim playback.) + #define CPF 0x00 /* Current pitch and fraction register */ -#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */ -#define CPF_CURRENTPITCH 0x10100000 +SUB_REG(CPF, CURRENTPITCH, 0xffff0000) /* Current pitch (linear, 0x4000 == unity pitch shift) */ #define CPF_STEREO_MASK 0x00008000 /* 1 = Even channel interleave, odd channel locked */ -#define CPF_STOP_MASK 0x00004000 /* 1 = Current pitch forced to 0 */ +SUB_REG(CPF, STOP, 0x00004000) /* 1 = Current pitch forced to 0 */ + /* Can be set only while matching bit in SOLEx is 1 */ #define CPF_FRACADDRESS_MASK 0x00003fff /* Linear fractional address of the current channel */ #define PTRX 0x01 /* Pitch target and send A/B amounts register */ -#define PTRX_PITCHTARGET_MASK 0xffff0000 /* Pitch target of specified channel */ -#define PTRX_PITCHTARGET 0x10100001 -#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00 /* Linear level of channel output sent to FX send bus A */ -#define PTRX_FXSENDAMOUNT_A 0x08080001 -#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff /* Linear level of channel output sent to FX send bus B */ -#define PTRX_FXSENDAMOUNT_B 0x08000001 +SUB_REG(PTRX, PITCHTARGET, 0xffff0000) /* Pitch target of specified channel */ +SUB_REG(PTRX, FXSENDAMOUNT_A, 0x0000ff00) /* Linear level of channel output sent to FX send bus A */ +SUB_REG(PTRX, FXSENDAMOUNT_B, 0x000000ff) /* Linear level of channel output sent to FX send bus B */ +// Note: the volumes are raw multpliers, so real 100% is impossible. #define CVCF 0x02 /* Current volume and filter cutoff register */ -#define CVCF_CURRENTVOL_MASK 0xffff0000 /* Current linear volume of specified channel */ -#define CVCF_CURRENTVOL 0x10100002 -#define CVCF_CURRENTFILTER_MASK 0x0000ffff /* Current filter cutoff frequency of specified channel */ -#define CVCF_CURRENTFILTER 0x10000002 +SUB_REG(CVCF, CURRENTVOL, 0xffff0000) /* Current linear volume of specified channel */ +SUB_REG(CVCF, CURRENTFILTER, 0x0000ffff) /* Current filter cutoff frequency of specified channel */ #define VTFT 0x03 /* Volume target and filter cutoff target register */ -#define VTFT_VOLUMETARGET_MASK 0xffff0000 /* Volume target of specified channel */ -#define VTFT_VOLUMETARGET 0x10100003 -#define VTFT_FILTERTARGET_MASK 0x0000ffff /* Filter cutoff target of specified channel */ -#define VTFT_FILTERTARGET 0x10000003 +SUB_REG(VTFT, VOLUMETARGET, 0xffff0000) /* Volume target of specified channel */ +SUB_REG(VTFT, FILTERTARGET, 0x0000ffff) /* Filter cutoff target of specified channel */ #define Z1 0x05 /* Filter delay memory 1 register */ #define Z2 0x04 /* Filter delay memory 2 register */ #define PSST 0x06 /* Send C amount and loop start address register */ -#define PSST_FXSENDAMOUNT_C_MASK 0xff000000 /* Linear level of channel output sent to FX send bus C */ - -#define PSST_FXSENDAMOUNT_C 0x08180006 - -#define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */ -#define PSST_LOOPSTARTADDR 0x18000006 +SUB_REG(PSST, FXSENDAMOUNT_C, 0xff000000) /* Linear level of channel output sent to FX send bus C */ +SUB_REG(PSST, LOOPSTARTADDR, 0x00ffffff) /* Loop start address of the specified channel */ #define DSL 0x07 /* Send D amount and loop end address register */ -#define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */ - -#define DSL_FXSENDAMOUNT_D 0x08180007 - -#define DSL_LOOPENDADDR_MASK 0x00ffffff /* Loop end address of the specified channel */ -#define DSL_LOOPENDADDR 0x18000007 +SUB_REG(DSL, FXSENDAMOUNT_D, 0xff000000) /* Linear level of channel output sent to FX send bus D */ +SUB_REG(DSL, LOOPENDADDR, 0x00ffffff) /* Loop end address of the specified channel */ #define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */ -#define CCCA_RESONANCE_MASK 0xf0000000 /* Lowpass filter resonance (Q) height */ -#define CCCA_RESONANCE 0x041c0008 +SUB_REG(CCCA, RESONANCE, 0xf0000000) /* Lowpass filter resonance (Q) height */ #define CCCA_INTERPROM_MASK 0x0e000000 /* Selects passband of interpolation ROM */ /* 1 == full band, 7 == lowpass */ /* ROM 0 is used when pitch shifting downward or less */ @@ -447,27 +470,24 @@ #define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */ #define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */ /* 8-bit samples are unsigned, 16-bit ones signed */ -#define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */ -#define CCCA_CURRADDR 0x18000008 +SUB_REG(CCCA, CURRADDR, 0x00ffffff) /* Current address of the selected channel */ #define CCR 0x09 /* Cache control register */ -#define CCR_CACHEINVALIDSIZE 0x07190009 -#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples before the read address */ +SUB_REG(CCR, CACHEINVALIDSIZE, 0xfe000000) /* Number of invalid samples before the read address */ #define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */ #define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */ /* Auto-set from CPF_STEREO_MASK */ #define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */ /* Auto-set from CCCA_8BITSELECT */ -#define CCR_READADDRESS 0x06100009 -#define CCR_READADDRESS_MASK 0x003f0000 /* Next cached sample to play */ -#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */ +SUB_REG(CCR, READADDRESS, 0x003f0000) /* Next cached sample to play */ +SUB_REG(CCR, LOOPINVALSIZE, 0x0000fe00) /* Number of invalid samples in cache prior to loop */ /* NOTE: This is valid only if CACHELOOPFLAG is set */ #define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */ -#define CCR_CACHELOOPADDRHI 0x000000ff /* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */ +SUB_REG(CCR, CACHELOOPADDRHI, 0x000000ff) /* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */ #define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */ /* NOTE: This register is normally not used */ -#define CLP_CACHELOOPADDR 0x0000ffff /* Cache loop address low word */ +SUB_REG(CLP, CACHELOOPADDR, 0x0000ffff) /* Cache loop address low word */ #define FXRT 0x0b /* Effects send routing register */ /* NOTE: It is illegal to assign the same routing to */ @@ -537,20 +557,17 @@ #define IP_UNITY 0x0000e000 /* Unity pitch shift */ #define IFATN 0x19 /* Initial filter cutoff and attenuation register */ -#define IFATN_FILTERCUTOFF_MASK 0x0000ff00 /* Initial filter cutoff frequency in exponential units */ +SUB_REG(IFATN, FILTERCUTOFF, 0x0000ff00) /* Initial filter cutoff frequency in exponential units */ /* 6 most significant bits are semitones */ /* 2 least significant bits are fractions */ -#define IFATN_FILTERCUTOFF 0x08080019 -#define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */ -#define IFATN_ATTENUATION 0x08000019 +SUB_REG(IFATN, ATTENUATION, 0x000000ff) /* Initial attenuation in 0.375dB steps */ #define PEFE 0x1a /* Pitch envelope and filter envelope amount register */ -#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */ +SUB_REG(PEFE, PITCHAMOUNT, 0x0000ff00) /* Pitch envlope amount */ /* Signed 2's complement, +/- one octave peak extremes */ -#define PEFE_PITCHAMOUNT 0x0808001a -#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */ +SUB_REG(PEFE, FILTERAMOUNT, 0x000000ff) /* Filter envlope amount */ /* Signed 2's complement, +/- six octaves peak extremes */ -#define PEFE_FILTERAMOUNT 0x0800001a + #define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */ #define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */ @@ -577,24 +594,22 @@ /* 0x1f: not used */ -#define CD0 0x20 /* Cache data 0 register */ -#define CD1 0x21 /* Cache data 1 register */ -#define CD2 0x22 /* Cache data 2 register */ -#define CD3 0x23 /* Cache data 3 register */ -#define CD4 0x24 /* Cache data 4 register */ -#define CD5 0x25 /* Cache data 5 register */ -#define CD6 0x26 /* Cache data 6 register */ -#define CD7 0x27 /* Cache data 7 register */ -#define CD8 0x28 /* Cache data 8 register */ -#define CD9 0x29 /* Cache data 9 register */ -#define CDA 0x2a /* Cache data A register */ -#define CDB 0x2b /* Cache data B register */ -#define CDC 0x2c /* Cache data C register */ -#define CDD 0x2d /* Cache data D register */ -#define CDE 0x2e /* Cache data E register */ -#define CDF 0x2f /* Cache data F register */ - -/* 0x30-3f seem to be the same as 0x20-2f */ +// 32 cache registers (== 128 bytes) per channel follow. +// In stereo mode, the two channels' caches are concatenated into one, +// and hold the interleaved frames. +// The cache holds 64 frames, so the upper half is not used in 8-bit mode. +// All registers mentioned below count in frames. +// The cache is a ring buffer; CCR_READADDRESS operates modulo 64. +// The cache is filled from (CCCA_CURRADDR - CCR_CACHEINVALIDSIZE) +// into (CCR_READADDRESS - CCR_CACHEINVALIDSIZE). +// The engine has a fetch threshold of 32 bytes, so it tries to keep +// CCR_CACHEINVALIDSIZE below 8 (16-bit stereo), 16 (16-bit mono, +// 8-bit stereo), or 32 (8-bit mono). The actual transfers are pretty +// unpredictable, especially if several voices are running. +// Frames are consumed at CCR_READADDRESS, which is incremented afterwards, +// along with CCCA_CURRADDR and CCR_CACHEINVALIDSIZE. This implies that the +// actual playback position always lags CCCA_CURRADDR by exactly 64 frames. +#define CD0 0x20 /* Cache data registers 0 .. 0x1f */ #define PTB 0x40 /* Page table base register */ #define PTB_MASK 0xfffff000 /* Physical address of the page table in host memory */ @@ -695,6 +710,8 @@ #define ADCBS_BUFSIZE_57344 0x0000001e #define ADCBS_BUFSIZE_65536 0x0000001f +// On Audigy, the FX send amounts are not applied instantly, but determine +// targets towards which the following registers swerve gradually. #define A_CSBA 0x4c /* FX send B & A current amounts */ #define A_CSDC 0x4d /* FX send D & C current amounts */ #define A_CSFE 0x4e /* FX send F & E current amounts */ @@ -755,6 +772,9 @@ #define CLIPL 0x5a /* Channel loop interrupt pending low register */ #define CLIPH 0x5b /* Channel loop interrupt pending high register */ +// These cause CPF_STOP_MASK to be set shortly after CCCA_CURRADDR passes DSL_LOOPENDADDR. +// Subsequent changes to the address registers don't resume; clearing the bit here or in CPF does. +// The registers are NOT synchronized; the next serviced channel picks up immediately. #define SOLEL 0x5c /* Stop on loop enable low register */ #define SOLEH 0x5d /* Stop on loop enable high register */ @@ -793,22 +813,19 @@ #define SRCS_SPDIFRATE_96 0x00080000 #define MICIDX 0x63 /* Microphone recording buffer index register */ -#define MICIDX_MASK 0x0000ffff /* 16-bit value */ -#define MICIDX_IDX 0x10000063 +SUB_REG(MICIDX, IDX, 0x0000ffff) #define ADCIDX 0x64 /* ADC recording buffer index register */ -#define ADCIDX_MASK 0x0000ffff /* 16 bit index field */ -#define ADCIDX_IDX 0x10000064 +SUB_REG(ADCIDX, IDX, 0x0000ffff) #define A_ADCIDX 0x63 -#define A_ADCIDX_IDX 0x10000063 +SUB_REG(A_ADCIDX, IDX, 0x0000ffff) #define A_MICIDX 0x64 -#define A_MICIDX_IDX 0x10000064 +SUB_REG(A_MICIDX, IDX, 0x0000ffff) #define FXIDX 0x65 /* FX recording buffer index register */ -#define FXIDX_MASK 0x0000ffff /* 16-bit value */ -#define FXIDX_IDX 0x10000065 +SUB_REG(FXIDX, IDX, 0x0000ffff) /* The 32-bit HLIEx and HLIPx registers all have one bit per channel control/status */ #define HLIEL 0x66 /* Channel half loop interrupt enable low register */ @@ -852,8 +869,8 @@ #define A_SPDIF_44100 0x00000080 #define A_SPDIF_MUTED 0x000000c0 -#define A_I2S_CAPTURE_RATE_MASK 0x00000e00 /* This sets the capture PCM rate, but it is */ -#define A_I2S_CAPTURE_RATE 0x03090076 /* unclear if this sets the ADC rate as well. */ +SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM rate, but it is */ + /* unclear if this sets the ADC rate as well. */ #define A_I2S_CAPTURE_48000 0x0 #define A_I2S_CAPTURE_192000 0x1 #define A_I2S_CAPTURE_96000 0x2 @@ -1093,6 +1110,9 @@ #define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */ #define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */ +// The actual code disagrees about the bit width of the registers - +// the formula used is freq = 0x1770000 / (((X_HI << 5) | X_LO) + 1) + #define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */ #define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */ @@ -1189,9 +1209,10 @@ * physical outputs of Hana, or outputs going to Alice2/Tina for capture - * 16 x EMU_DST_ALICE2_EMU32_X (2x on rev2 boards). Which data is fed into * a channel depends on the mixer control setting for each destination - see - * emumixer.c - snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[] + * the register arrays in emumixer.c. */ #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ + /* This channel is delayed by one sample. */ #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_3 0x0002 /* 16 EMU32 channels to Alice2 +0 to +0xf */ @@ -1422,24 +1443,35 @@ /* 0x600 and 0x700 no used */ + +/* ------------------- CONSTANTS -------------------- */ + +extern const char * const snd_emu10k1_fxbus[32]; +extern const char * const snd_emu10k1_sblive_ins[16]; +extern const char * const snd_emu10k1_audigy_ins[16]; +extern const char * const snd_emu10k1_sblive_outs[32]; +extern const char * const snd_emu10k1_audigy_outs[32]; +extern const s8 snd_emu10k1_sblive51_fxbus2_map[16]; + /* ------------------- STRUCTURES -------------------- */ enum { + EMU10K1_UNUSED, // This must be zero EMU10K1_EFX, + EMU10K1_EFX_IRQ, EMU10K1_PCM, + EMU10K1_PCM_IRQ, EMU10K1_SYNTH, - EMU10K1_MIDI + EMU10K1_NUM_TYPES }; struct snd_emu10k1; struct snd_emu10k1_voice { - int number; - unsigned int use: 1, - pcm: 1, - efx: 1, - synth: 1, - midi: 1; + unsigned char number; + unsigned char use; + unsigned char dirty; + unsigned char last; void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); struct snd_emu10k1_pcm *epcm; @@ -1461,7 +1493,9 @@ struct snd_emu10k1_pcm { struct snd_emu10k1_voice *extra; unsigned short running; unsigned short first_ptr; + snd_pcm_uframes_t resume_pos; struct snd_util_memblk *memblk; + unsigned int pitch_target; unsigned int start_addr; unsigned int ccca_start_addr; unsigned int capture_ipr; /* interrupt acknowledge mask */ @@ -1479,6 +1513,8 @@ struct snd_emu10k1_pcm_mixer { /* mono, left, right x 8 sends (4 on emu10k1) */ unsigned char send_routing[3][8]; unsigned char send_volume[3][8]; + // 0x8000 is neutral. The mixer code rescales it to 0xffff to maintain + // backwards compatibility with user space. unsigned short attn[3]; struct snd_emu10k1_pcm *epcm; }; @@ -1492,6 +1528,9 @@ struct snd_emu10k1_pcm_mixer { #define snd_emu10k1_compose_audigy_fxrt2(route) \ ((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24)) +#define snd_emu10k1_compose_audigy_sendamounts(vol) \ +(((unsigned int)vol[4] << 24) | ((unsigned int)vol[5] << 16) | ((unsigned int)vol[6] << 8) | (unsigned int)vol[7]) + struct snd_emu10k1_memblk { struct snd_util_memblk mem; /* private part */ @@ -1510,9 +1549,9 @@ struct snd_emu10k1_fx8010_ctl { unsigned int vcount; unsigned int count; /* count of GPR (1..16) */ unsigned short gpr[32]; /* GPR number(s) */ - unsigned int value[32]; - unsigned int min; /* minimum range */ - unsigned int max; /* maximum range */ + int value[32]; + int min; /* minimum range */ + int max; /* maximum range */ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ struct snd_kcontrol *kcontrol; }; @@ -1600,35 +1639,43 @@ struct snd_emu_chip_details { u32 device; u32 subsystem; unsigned char revision; - unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */ - /* Redundant with emu10k2_chip being unset. */ - unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */ - unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */ - /* Redundant with ca0108_chip being unset. */ - unsigned char ca0108_chip; /* Audigy 2 Value */ - unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */ - unsigned char ca0151_chip; /* P16V */ - unsigned char spk71; /* Has 7.1 speakers */ - unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */ - unsigned char spdif_bug; /* Has Spdif phasing bug */ - unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ - unsigned char ecard; /* APS EEPROM */ - unsigned char emu_model; /* EMU model type */ - unsigned char spi_dac; /* SPI interface for DAC; requires ca0108_chip */ - unsigned char i2c_adc; /* I2C interface for ADC; requires ca0108_chip */ - unsigned char adc_1361t; /* Use Philips 1361T ADC */ - unsigned char invert_shared_spdif; /* analog/digital switch inverted */ + unsigned char emu_model; /* EMU model type */ + unsigned int emu10k1_chip:1; /* Original SB Live. Not SB Live 24bit. */ + /* Redundant with emu10k2_chip being unset. */ + unsigned int emu10k2_chip:1; /* Audigy 1 or Audigy 2. */ + unsigned int ca0102_chip:1; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */ + /* Redundant with ca0108_chip being unset. */ + unsigned int ca0108_chip:1; /* Audigy 2 Value */ + unsigned int ca_cardbus_chip:1; /* Audigy 2 ZS Notebook */ + unsigned int ca0151_chip:1; /* P16V */ + unsigned int spk20:1; /* Stereo only */ + unsigned int spk71:1; /* Has 7.1 speakers */ + unsigned int no_adat:1; /* Has no ADAT, only SPDIF */ + unsigned int sblive51:1; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */ + unsigned int spdif_bug:1; /* Has Spdif phasing bug */ + unsigned int ac97_chip:2; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ + unsigned int ecard:1; /* APS EEPROM */ + unsigned int spi_dac:1; /* SPI interface for DAC; requires ca0108_chip */ + unsigned int i2c_adc:1; /* I2C interface for ADC; requires ca0108_chip */ + unsigned int adc_1361t:1; /* Use Philips 1361T ADC */ + unsigned int invert_shared_spdif:1; /* analog/digital switch inverted */ const char *driver; const char *name; const char *id; /* for backward compatibility - can be NULL if not needed */ }; +#define NUM_OUTPUT_DESTS 28 +#define NUM_INPUT_DESTS 22 + struct snd_emu1010 { - unsigned int output_source[64]; - unsigned int input_source[64]; + unsigned char output_source[NUM_OUTPUT_DESTS]; + unsigned char input_source[NUM_INPUT_DESTS]; unsigned int adc_pads; /* bit mask */ unsigned int dac_pads; /* bit mask */ - unsigned int internal_clock; /* 44100 or 48000 */ + unsigned int wclock; /* Cached register value */ + unsigned int word_clock; /* Cached effective value */ + unsigned int clock_source; + unsigned int clock_fallback; unsigned int optical_in; /* 0:SPDIF, 1:ADAT */ unsigned int optical_out; /* 0:SPDIF, 1:ADAT */ struct delayed_work firmware_work; @@ -1653,7 +1700,6 @@ struct snd_emu10k1 { unsigned int address_mode; /* address mode */ unsigned long dma_mask; /* PCI DMA mask */ bool iommu_workaround; /* IOMMU workaround needed */ - unsigned int delay_pcm_irq; /* in samples */ int max_cache_pages; /* max memory size / PAGE_SIZE */ struct snd_dma_buffer silent_page; /* silent page */ struct snd_dma_buffer ptb_pages; /* page table pages */ @@ -1775,6 +1821,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu); /* I/O functions */ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); +void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, ...); unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data); @@ -1782,6 +1829,9 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value); void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value); void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value); void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src); +u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst); +int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src); +void snd_emu1010_update_clock(struct snd_emu10k1 *emu); unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc); void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb); void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb); @@ -1791,13 +1841,17 @@ void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum); void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum); void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum); void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum); +#if 0 void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum); void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum); +#endif +void snd_emu10k1_voice_set_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices); +void snd_emu10k1_voice_clear_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices); +int snd_emu10k1_voice_clear_loop_stop_multiple_atomic(struct snd_emu10k1 *emu, u64 voices); void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait); static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; } unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg); void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data); -unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate); #ifdef CONFIG_PM_SLEEP void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu); @@ -1825,7 +1879,8 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk); /* voice allocation */ -int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, struct snd_emu10k1_voice **rvoice); +int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int channels, + struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice); int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice); /* MIDI uart */ diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h index d499b68122a3..1cc530434b97 100644 --- a/include/sound/emux_synth.h +++ b/include/sound/emux_synth.h @@ -54,6 +54,7 @@ struct snd_emux_operators { #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); #endif + int (*get_pitch_shift)(struct snd_emux *emu); }; @@ -82,7 +83,6 @@ struct snd_emux { int max_voices; /* Number of voices */ int mem_size; /* memory size (in byte) */ int num_ports; /* number of ports to be created */ - int pitch_shift; /* pitch shift value (for Emu10k1) */ struct snd_emux_operators ops; /* operators */ void *hw; /* hardware */ unsigned long flags; /* other conditions */ diff --git a/include/sound/hda-mlink.h b/include/sound/hda-mlink.h index dbc47af08135..4f44f0bd5388 100644 --- a/include/sound/hda-mlink.h +++ b/include/sound/hda-mlink.h @@ -44,6 +44,9 @@ int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink); int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num); +int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y, + int channel_mask, int stream_id, int dir); + void hda_bus_ml_put_all(struct hdac_bus *bus); void hda_bus_ml_reset_losidv(struct hdac_bus *bus); int hda_bus_ml_resume(struct hdac_bus *bus); @@ -51,6 +54,7 @@ int hda_bus_ml_suspend(struct hdac_bus *bus); struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus); struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus); +struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus); struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid); @@ -144,6 +148,13 @@ hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return static inline int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; } +static inline int +hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y, + int channel_mask, int stream_id, int dir) +{ + return 0; +} + static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { } static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { } static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; } @@ -155,6 +166,9 @@ hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; } static inline struct hdac_ext_link * hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; } +static inline struct hdac_ext_link * +hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus) { return NULL; } + static inline struct mutex * hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) { return NULL; } diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 97f09acae302..2ffdf58bd6d4 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -347,6 +347,8 @@ struct hdac_bus { bool corbrp_self_clear:1; /* CORBRP clears itself after reset */ bool polling_mode:1; bool needs_damn_long_delay:1; + bool not_use_interrupts:1; /* prohibiting the RIRB IRQ */ + bool access_sdnctl_in_dword:1; /* accessing the sdnctl register by dword */ int poll_count; diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index e1f59b2940af..b0197b1d1fe4 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -18,6 +18,7 @@ #if IS_ENABLED(CONFIG_SND_SEQUENCER) #include <sound/seq_device.h> #endif +#include <sound/info.h> /* * Raw MIDI interface @@ -47,6 +48,10 @@ struct snd_rawmidi_global_ops { int (*dev_unregister) (struct snd_rawmidi * rmidi); void (*get_port_info)(struct snd_rawmidi *rmidi, int number, struct snd_seq_port_info *info); + long (*ioctl)(struct snd_rawmidi *rmidi, unsigned int cmd, + void __user *argp); + void (*proc_read)(struct snd_info_entry *entry, + struct snd_info_buffer *buf); }; struct snd_rawmidi_runtime { @@ -61,6 +66,7 @@ struct snd_rawmidi_runtime { size_t avail_min; /* min avail for wakeup */ size_t avail; /* max used buffer for wakeup */ size_t xruns; /* over/underruns counter */ + size_t align; /* alignment (0 = byte stream, 3 = UMP) */ int buffer_ref; /* buffer reference count */ /* misc */ wait_queue_head_t sleep; @@ -146,6 +152,13 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream, const struct snd_rawmidi_ops *ops); +/* internal */ +int snd_rawmidi_init(struct snd_rawmidi *rmidi, + struct snd_card *card, char *id, int device, + int output_count, int input_count, + unsigned int info_flags); +int snd_rawmidi_free(struct snd_rawmidi *rmidi); + /* callbacks */ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, @@ -161,7 +174,7 @@ int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream); /* main midi functions */ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info); -int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, +int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice, int mode, struct snd_rawmidi_file *rfile); int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile); int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h index 8899affe9155..dead74b022f4 100644 --- a/include/sound/seq_device.h +++ b/include/sound/seq_device.h @@ -78,5 +78,6 @@ void snd_seq_driver_unregister(struct snd_seq_driver *drv); */ #define SNDRV_SEQ_DEV_ID_MIDISYNTH "seq-midi" #define SNDRV_SEQ_DEV_ID_OPL3 "opl3-synth" +#define SNDRV_SEQ_DEV_ID_UMP "seq-ump-client" #endif /* __SOUND_SEQ_DEVICE_H */ diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h index 658911926f3a..c8621671fa70 100644 --- a/include/sound/seq_kernel.h +++ b/include/sound/seq_kernel.h @@ -70,9 +70,19 @@ int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg); typedef int (*snd_seq_dump_func_t)(void *ptr, void *buf, int count); int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char *buf, int in_kernel, int size_aligned); +int snd_seq_expand_var_event_at(const struct snd_seq_event *event, int count, + char *buf, int offset); int snd_seq_dump_var_event(const struct snd_seq_event *event, snd_seq_dump_func_t func, void *private_data); +/* size of the event packet; it can be greater than snd_seq_event size */ +static inline size_t snd_seq_event_packet_size(struct snd_seq_event *ev) +{ + if (snd_seq_ev_is_ump(ev)) + return sizeof(struct snd_seq_ump_event); + return sizeof(struct snd_seq_event); +} + /* interface for OSS emulation */ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo); diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index a3f3f3aa9e6e..b450d5873227 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -59,9 +59,6 @@ struct asoc_simple_priv { struct simple_dai_props { struct asoc_simple_dai *cpu_dai; struct asoc_simple_dai *codec_dai; - struct snd_soc_dai_link_component *cpus; - struct snd_soc_dai_link_component *codecs; - struct snd_soc_dai_link_component *platforms; struct asoc_simple_data adata; struct snd_soc_codec_conf *codec_conf; struct prop_nums num; @@ -73,7 +70,6 @@ struct asoc_simple_priv { struct snd_soc_dai_link *dai_link; struct asoc_simple_dai *dais; struct snd_soc_dai_link_component *dlcs; - struct snd_soc_dai_link_component dummy; struct snd_soc_codec_conf *codec_conf; struct gpio_desc *pa_gpio; const struct snd_soc_ops *ops; @@ -196,6 +192,9 @@ int asoc_simple_remove(struct platform_device *pdev); int asoc_graph_card_probe(struct snd_soc_card *card); int asoc_graph_is_ports0(struct device_node *port); +int asoc_graph_parse_dai(struct device_node *ep, + struct snd_soc_dai_link_component *dlc, + int *is_single_link); #ifdef DEBUG static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h index 82a7db23db69..e49b97d9e3ff 100644 --- a/include/sound/soc-acpi-intel-match.h +++ b/include/sound/soc-acpi-intel-match.h @@ -31,6 +31,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[]; @@ -40,6 +41,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[]; /* * generic table used for HDA codec-based platforms, possibly with diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h index b38fd25c5729..528279056b3a 100644 --- a/include/sound/soc-acpi.h +++ b/include/sound/soc-acpi.h @@ -170,6 +170,7 @@ struct snd_soc_acpi_link_adr { /* Descriptor for SST ASoC machine driver */ struct snd_soc_acpi_mach { u8 id[ACPI_ID_LEN]; + const char *uid; const struct snd_soc_acpi_codecs *comp_ids; const u32 link_mask; const struct snd_soc_acpi_link_adr *links; diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 0814ed143864..87f248a06271 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -159,6 +159,15 @@ struct snd_soc_component_driver { int remove_order; /* + * soc_pcm_trigger() start/stop sequence. + * see also + * snd_soc_dai_link + * soc_pcm_trigger() + */ + enum snd_soc_trigger_order trigger_start; + enum snd_soc_trigger_order trigger_stop; + + /* * signal if the module handling the component should not be removed * if a pcm is open. Setting this would prevent the module * refcount being incremented in probe() but allow it be incremented @@ -190,8 +199,6 @@ struct snd_soc_component_driver { bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */ int be_pcm_base; /* base device ID for all BE PCMs */ - unsigned int start_dma_last; - #ifdef CONFIG_DEBUG_FS const char *debugfs_prefix; #endif @@ -454,6 +461,10 @@ int snd_soc_component_force_enable_pin_unlocked( struct snd_soc_component *component, const char *pin); +/* component controls */ +int snd_soc_component_notify_control(struct snd_soc_component *component, + const char * const ctl); + /* component driver ops */ int snd_soc_component_open(struct snd_soc_component *component, struct snd_pcm_substream *substream); diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h index 4d6ac7699833..ebd24753dd00 100644 --- a/include/sound/soc-dpcm.h +++ b/include/sound/soc-dpcm.h @@ -122,6 +122,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe, int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe, struct snd_soc_pcm_runtime *be, int stream); +/* can this BE perform prepare */ +int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe, + struct snd_soc_pcm_runtime *be, int stream); + /* is the current PCM operation for this FE ? */ int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream); diff --git a/include/sound/soc.h b/include/sound/soc.h index 05004c048dd5..b27f84580c5b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -607,6 +607,14 @@ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +enum snd_soc_trigger_order { + /* start stop */ + SND_SOC_TRIGGER_ORDER_DEFAULT = 0, /* Link->Component->DAI DAI->Component->Link */ + SND_SOC_TRIGGER_ORDER_LDC, /* Link->DAI->Component Component->DAI->Link */ + + SND_SOC_TRIGGER_ORDER_MAX, +}; + /* SoC PCM stream information */ struct snd_soc_pcm_stream { const char *stream_name; @@ -633,7 +641,6 @@ struct snd_soc_compr_ops { int (*startup)(struct snd_compr_stream *); void (*shutdown)(struct snd_compr_stream *); int (*set_params)(struct snd_compr_stream *); - int (*trigger)(struct snd_compr_stream *); }; struct snd_soc_component* @@ -646,6 +653,11 @@ struct snd_soc_dai_link_component { const char *dai_name; }; +struct snd_soc_dai_link_codec_ch_map { + unsigned int connected_cpu_id; + unsigned int ch_mask; +}; + struct snd_soc_dai_link { /* config - must be set by machine driver */ const char *name; /* Codec name */ @@ -674,6 +686,7 @@ struct snd_soc_dai_link { struct snd_soc_dai_link_component *codecs; unsigned int num_codecs; + struct snd_soc_dai_link_codec_ch_map *codec_ch_maps; /* * You MAY specify the link's platform/PCM/DMA driver, either by * device name, or by DT/OF node, but not both. Some forms of link @@ -708,6 +721,15 @@ struct snd_soc_dai_link { const struct snd_soc_ops *ops; const struct snd_soc_compr_ops *compr_ops; + /* + * soc_pcm_trigger() start/stop sequence. + * see also + * snd_soc_component_driver + * soc_pcm_trigger() + */ + enum snd_soc_trigger_order trigger_start; + enum snd_soc_trigger_order trigger_stop; + /* Mark this pcm with non atomic ops */ unsigned int nonatomic:1; @@ -746,12 +768,6 @@ struct snd_soc_dai_link { /* Do not create a PCM for this DAI link (Backend link) */ unsigned int ignore:1; - /* This flag will reorder stop sequence. By enabling this flag - * DMA controller stop sequence will be invoked first followed by - * CPU DAI driver stop sequence - */ - unsigned int stop_dma_first:1; - #ifdef CONFIG_SND_SOC_TOPOLOGY struct snd_soc_dobj dobj; /* For topology */ #endif @@ -878,6 +894,7 @@ asoc_link_to_platform(struct snd_soc_dai_link *link, int n) { #define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } extern struct snd_soc_dai_link_component null_dailink_component[0]; +extern struct snd_soc_dai_link_component asoc_dummy_dlc; struct snd_soc_codec_conf { @@ -1291,11 +1308,18 @@ unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np, snd_soc_daifmt_clock_provider_from_bitmap( \ snd_soc_daifmt_parse_clock_provider_as_bitmap(np, prefix)) +int snd_soc_get_stream_cpu(struct snd_soc_dai_link *dai_link, int stream); +int snd_soc_get_dlc(const struct of_phandle_args *args, + struct snd_soc_dai_link_component *dlc); +int snd_soc_of_get_dlc(struct device_node *of_node, + struct of_phandle_args *args, + struct snd_soc_dai_link_component *dlc, + int index); int snd_soc_get_dai_id(struct device_node *ep); int snd_soc_get_dai_name(const struct of_phandle_args *args, const char **dai_name); int snd_soc_of_get_dai_name(struct device_node *of_node, - const char **dai_name); + const char **dai_name, int index); int snd_soc_of_get_dai_link_codecs(struct device *dev, struct device_node *of_node, struct snd_soc_dai_link *dai_link); diff --git a/include/sound/tas2781-dsp.h b/include/sound/tas2781-dsp.h new file mode 100644 index 000000000000..bd1b72bf47a5 --- /dev/null +++ b/include/sound/tas2781-dsp.h @@ -0,0 +1,183 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// +// Copyright (C) 2022 - 2023 Texas Instruments Incorporated +// https://www.ti.com +// +// The TAS2781 driver implements a flexible and configurable +// algo coefficient setting for one, two, or even multiple +// TAS2781 chips. +// +// Author: Shenghao Ding <shenghao-ding@ti.com> +// Author: Kevin Lu <kevin-lu@ti.com> +// + +#ifndef __TASDEVICE_DSP_H__ +#define __TASDEVICE_DSP_H__ + +#define MAIN_ALL_DEVICES 0x0d +#define MAIN_DEVICE_A 0x01 +#define MAIN_DEVICE_B 0x08 +#define MAIN_DEVICE_C 0x10 +#define MAIN_DEVICE_D 0x14 +#define COEFF_DEVICE_A 0x03 +#define COEFF_DEVICE_B 0x0a +#define COEFF_DEVICE_C 0x11 +#define COEFF_DEVICE_D 0x15 +#define PRE_DEVICE_A 0x04 +#define PRE_DEVICE_B 0x0b +#define PRE_DEVICE_C 0x12 +#define PRE_DEVICE_D 0x16 + +#define PPC3_VERSION 0x4100 +#define PPC3_VERSION_TAS2781 0x14600 +#define TASDEVICE_DEVICE_SUM 8 +#define TASDEVICE_CONFIG_SUM 64 + +#define TASDEVICE_MAX_CHANNELS 8 + +enum tasdevice_dsp_dev_idx { + TASDEVICE_DSP_TAS_2555 = 0, + TASDEVICE_DSP_TAS_2555_STEREO, + TASDEVICE_DSP_TAS_2557_MONO, + TASDEVICE_DSP_TAS_2557_DUAL_MONO, + TASDEVICE_DSP_TAS_2559, + TASDEVICE_DSP_TAS_2563, + TASDEVICE_DSP_TAS_2563_DUAL_MONO = 7, + TASDEVICE_DSP_TAS_2563_QUAD, + TASDEVICE_DSP_TAS_2563_21, + TASDEVICE_DSP_TAS_2781, + TASDEVICE_DSP_TAS_2781_DUAL_MONO, + TASDEVICE_DSP_TAS_2781_21, + TASDEVICE_DSP_TAS_2781_QUAD, + TASDEVICE_DSP_TAS_MAX_DEVICE +}; + +struct tasdevice_fw_fixed_hdr { + unsigned int fwsize; + unsigned int ppcver; + unsigned int drv_ver; +}; + +struct tasdevice_dspfw_hdr { + struct tasdevice_fw_fixed_hdr fixed_hdr; + unsigned short device_family; + unsigned short device; + unsigned char ndev; +}; + +struct tasdev_blk { + int nr_retry; + unsigned int type; + unsigned char is_pchksum_present; + unsigned char pchksum; + unsigned char is_ychksum_present; + unsigned char ychksum; + unsigned int nr_cmds; + unsigned int blk_size; + unsigned int nr_subblocks; + unsigned char *data; +}; + +struct tasdevice_data { + char name[64]; + unsigned int nr_blk; + struct tasdev_blk *dev_blks; +}; + +struct tasdevice_prog { + unsigned int prog_size; + struct tasdevice_data dev_data; +}; + +struct tasdevice_config { + unsigned int cfg_size; + char name[64]; + struct tasdevice_data dev_data; +}; + +struct tasdevice_calibration { + struct tasdevice_data dev_data; +}; + +struct tasdevice_fw { + struct tasdevice_dspfw_hdr fw_hdr; + unsigned short nr_programs; + struct tasdevice_prog *programs; + unsigned short nr_configurations; + struct tasdevice_config *configs; + unsigned short nr_calibrations; + struct tasdevice_calibration *calibrations; + struct device *dev; +}; + +enum tasdevice_dsp_fw_state { + TASDEVICE_DSP_FW_NONE = 0, + TASDEVICE_DSP_FW_PENDING, + TASDEVICE_DSP_FW_FAIL, + TASDEVICE_DSP_FW_ALL_OK, +}; + +enum tasdevice_bin_blk_type { + TASDEVICE_BIN_BLK_COEFF = 1, + TASDEVICE_BIN_BLK_POST_POWER_UP, + TASDEVICE_BIN_BLK_PRE_SHUTDOWN, + TASDEVICE_BIN_BLK_PRE_POWER_UP, + TASDEVICE_BIN_BLK_POST_SHUTDOWN +}; + +struct tasdevice_rca_hdr { + unsigned int img_sz; + unsigned int checksum; + unsigned int binary_version_num; + unsigned int drv_fw_version; + unsigned char plat_type; + unsigned char dev_family; + unsigned char reserve; + unsigned char ndev; + unsigned char devs[TASDEVICE_DEVICE_SUM]; + unsigned int nconfig; + unsigned int config_size[TASDEVICE_CONFIG_SUM]; +}; + +struct tasdev_blk_data { + unsigned char dev_idx; + unsigned char block_type; + unsigned short yram_checksum; + unsigned int block_size; + unsigned int n_subblks; + unsigned char *regdata; +}; + +struct tasdevice_config_info { + unsigned int nblocks; + unsigned int real_nblocks; + unsigned char active_dev; + struct tasdev_blk_data **blk_data; +}; + +struct tasdevice_rca { + struct tasdevice_rca_hdr fw_hdr; + int ncfgs; + struct tasdevice_config_info **cfg_info; + int profile_cfg_id; +}; + +void tasdevice_select_cfg_blk(void *context, int conf_no, + unsigned char block_type); +void tasdevice_config_info_remove(void *context); +void tasdevice_dsp_remove(void *context); +int tasdevice_dsp_parser(void *context); +int tasdevice_rca_parser(void *context, const struct firmware *fmw); +void tasdevice_dsp_remove(void *context); +void tasdevice_calbin_remove(void *context); +int tasdevice_select_tuningprm_cfg(void *context, int prm, + int cfg_no, int rca_conf_no); +int tasdevice_prmg_load(void *context, int prm_no); +int tasdevice_prmg_calibdata_load(void *context, int prm_no); +void tasdevice_tuning_switch(void *context, int state); +int tas2781_load_calibration(void *context, char *file_name, + unsigned short i); + +#endif diff --git a/include/sound/tas2781-tlv.h b/include/sound/tas2781-tlv.h new file mode 100644 index 000000000000..4038dd421150 --- /dev/null +++ b/include/sound/tas2781-tlv.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// +// Copyright (C) 2022 - 2023 Texas Instruments Incorporated +// https://www.ti.com +// +// The TAS2781 driver implements a flexible and configurable +// algo coefficient setting for one, two, or even multiple +// TAS2781 chips. +// +// Author: Shenghao Ding <shenghao-ding@ti.com> +// + +#ifndef __TAS2781_TLV_H__ +#define __TAS2781_TLV_H__ + +static const DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0); +static const DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); + +#endif diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h new file mode 100644 index 000000000000..a6c808b22318 --- /dev/null +++ b/include/sound/tas2781.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// +// ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier +// +// Copyright (C) 2022 - 2023 Texas Instruments Incorporated +// https://www.ti.com +// +// The TAS2781 driver implements a flexible and configurable +// algo coefficient setting for one, two, or even multiple +// TAS2781 chips. +// +// Author: Shenghao Ding <shenghao-ding@ti.com> +// Author: Kevin Lu <kevin-lu@ti.com> +// + +#ifndef __TAS2781_H__ +#define __TAS2781_H__ + +#include "tas2781-dsp.h" + +/* version number */ +#define TAS2781_DRV_VER 1 +#define SMARTAMP_MODULE_NAME "tas2781" +#define TAS2781_GLOBAL_ADDR 0x40 +#define TASDEVICE_RATES (SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_88200) + +#define TASDEVICE_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +/*PAGE Control Register (available in page0 of each book) */ +#define TASDEVICE_PAGE_SELECT 0x00 +#define TASDEVICE_BOOKCTL_PAGE 0x00 +#define TASDEVICE_BOOKCTL_REG 127 +#define TASDEVICE_BOOK_ID(reg) (reg / (256 * 128)) +#define TASDEVICE_PAGE_ID(reg) ((reg % (256 * 128)) / 128) +#define TASDEVICE_PAGE_REG(reg) ((reg % (256 * 128)) % 128) +#define TASDEVICE_PGRG(reg) (reg % (256 * 128)) +#define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \ + (page * 128)) + reg) + +/*Software Reset */ +#define TAS2781_REG_SWRESET TASDEVICE_REG(0x0, 0X0, 0x01) +#define TAS2781_REG_SWRESET_RESET BIT(0) + +/*I2C Checksum */ +#define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E) + +/* Volume control */ +#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A) +#define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03) +#define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1) + +#define TASDEVICE_CMD_SING_W 0x1 +#define TASDEVICE_CMD_BURST 0x2 +#define TASDEVICE_CMD_DELAY 0x3 +#define TASDEVICE_CMD_FIELD_W 0x4 + +enum audio_device { + TAS2781 = 0, +}; + +enum device_catlog_id { + LENOVO = 0, + OTHERS +}; + +struct tasdevice { + struct tasdevice_fw *cali_data_fmw; + unsigned int dev_addr; + unsigned int err_code; + unsigned char cur_book; + short cur_prog; + short cur_conf; + bool is_loading; + bool is_loaderr; +}; + +struct tasdevice_irqinfo { + int irq_gpio; + int irq; +}; + +struct calidata { + unsigned char *data; + unsigned long total_sz; +}; + +struct tasdevice_priv { + struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS]; + struct tasdevice_irqinfo irq_info; + struct tasdevice_rca rcabin; + struct calidata cali_data; + struct tasdevice_fw *fmw; + struct gpio_desc *reset; + struct mutex codec_lock; + struct regmap *regmap; + struct device *dev; + struct tm tm; + + enum device_catlog_id catlog_id; + const char *acpi_subsystem_id; + unsigned char cal_binaryname[TASDEVICE_MAX_CHANNELS][64]; + unsigned char crc8_lkp_tbl[CRC8_TABLE_SIZE]; + unsigned char coef_binaryname[64]; + unsigned char rca_binaryname[64]; + unsigned char dev_name[32]; + unsigned char ndev; + unsigned int magic_num; + unsigned int chip_id; + unsigned int sysclk; + + int cur_prog; + int cur_conf; + int fw_state; + int index; + void *client; + void *codec; + bool force_fwload_status; + bool playback_started; + bool isacpi; + int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv, + const struct firmware *fmw, int offset); + int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv, + struct tasdevice_fw *tas_fmw, + const struct firmware *fmw, int offset); + int (*fw_parse_configuration_data)(struct tasdevice_priv *tas_priv, + struct tasdevice_fw *tas_fmw, + const struct firmware *fmw, int offset); + int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv, + struct tasdev_blk *block); +}; + +void tas2781_reset(struct tasdevice_priv *tas_dev); +int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, + void (*cont)(const struct firmware *fw, void *context)); +struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c); +int tasdevice_init(struct tasdevice_priv *tas_priv); +void tasdevice_remove(struct tasdevice_priv *tas_priv); +int tasdevice_dev_read(struct tasdevice_priv *tas_priv, + unsigned short chn, unsigned int reg, unsigned int *value); +int tasdevice_dev_write(struct tasdevice_priv *tas_priv, + unsigned short chn, unsigned int reg, unsigned int value); +int tasdevice_dev_bulk_write( + struct tasdevice_priv *tas_priv, unsigned short chn, + unsigned int reg, unsigned char *p_data, unsigned int n_length); +int tasdevice_dev_bulk_read(struct tasdevice_priv *tas_priv, + unsigned short chn, unsigned int reg, unsigned char *p_data, + unsigned int n_length); +int tasdevice_dev_update_bits( + struct tasdevice_priv *tasdevice, unsigned short chn, + unsigned int reg, unsigned int mask, unsigned int value); +int tasdevice_amp_putvol(struct tasdevice_priv *tas_priv, + struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); +int tasdevice_amp_getvol(struct tasdevice_priv *tas_priv, + struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); +int tasdevice_digital_putvol(struct tasdevice_priv *tas_priv, + struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); +int tasdevice_digital_getvol(struct tasdevice_priv *tas_priv, + struct snd_ctl_elem_value *ucontrol, struct soc_mixer_control *mc); + +#endif /* __TAS2781_H__ */ diff --git a/include/sound/ump.h b/include/sound/ump.h new file mode 100644 index 000000000000..44d2c2fd021d --- /dev/null +++ b/include/sound/ump.h @@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Universal MIDI Packet (UMP) Support + */ +#ifndef __SOUND_UMP_H +#define __SOUND_UMP_H + +#include <sound/rawmidi.h> + +struct snd_ump_endpoint; +struct snd_ump_block; +struct snd_ump_ops; +struct ump_cvt_to_ump; +struct snd_seq_ump_ops; + +struct snd_ump_endpoint { + struct snd_rawmidi core; /* raw UMP access */ + + struct snd_ump_endpoint_info info; + + const struct snd_ump_ops *ops; /* UMP ops set by the driver */ + struct snd_rawmidi_substream *substreams[2]; /* opened substreams */ + + void *private_data; + void (*private_free)(struct snd_ump_endpoint *ump); + + /* UMP Stream message processing */ + u32 stream_wait_for; /* expected stream message status */ + bool stream_finished; /* set when message has been processed */ + bool parsed; /* UMP / FB parse finished? */ + bool no_process_stream; /* suppress UMP stream messages handling */ + wait_queue_head_t stream_wait; + struct snd_rawmidi_file stream_rfile; + + struct list_head block_list; /* list of snd_ump_block objects */ + + /* intermediate buffer for UMP input */ + u32 input_buf[4]; + int input_buf_head; + int input_pending; + + struct mutex open_mutex; + +#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI) + spinlock_t legacy_locks[2]; + struct snd_rawmidi *legacy_rmidi; + struct snd_rawmidi_substream *legacy_substreams[2][SNDRV_UMP_MAX_GROUPS]; + + /* for legacy output; need to open the actual substream unlike input */ + int legacy_out_opens; + struct snd_rawmidi_file legacy_out_rfile; + struct ump_cvt_to_ump *out_cvts; +#endif + +#if IS_ENABLED(CONFIG_SND_SEQUENCER) + struct snd_seq_device *seq_dev; + const struct snd_seq_ump_ops *seq_ops; + void *seq_client; +#endif +}; + +/* ops filled by UMP drivers */ +struct snd_ump_ops { + int (*open)(struct snd_ump_endpoint *ump, int dir); + void (*close)(struct snd_ump_endpoint *ump, int dir); + void (*trigger)(struct snd_ump_endpoint *ump, int dir, int up); + void (*drain)(struct snd_ump_endpoint *ump, int dir); +}; + +/* ops filled by sequencer binding */ +struct snd_seq_ump_ops { + void (*input_receive)(struct snd_ump_endpoint *ump, + const u32 *data, int words); + int (*notify_fb_change)(struct snd_ump_endpoint *ump, + struct snd_ump_block *fb); + int (*switch_protocol)(struct snd_ump_endpoint *ump); +}; + +struct snd_ump_block { + struct snd_ump_block_info info; + struct snd_ump_endpoint *ump; + + void *private_data; + void (*private_free)(struct snd_ump_block *blk); + + struct list_head list; +}; + +#define rawmidi_to_ump(rmidi) container_of(rmidi, struct snd_ump_endpoint, core) + +int snd_ump_endpoint_new(struct snd_card *card, char *id, int device, + int output, int input, + struct snd_ump_endpoint **ump_ret); +int snd_ump_parse_endpoint(struct snd_ump_endpoint *ump); +int snd_ump_block_new(struct snd_ump_endpoint *ump, unsigned int blk, + unsigned int direction, unsigned int first_group, + unsigned int num_groups, struct snd_ump_block **blk_ret); +int snd_ump_receive(struct snd_ump_endpoint *ump, const u32 *buffer, int count); +int snd_ump_transmit(struct snd_ump_endpoint *ump, u32 *buffer, int count); + +#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI) +int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + char *id, int device); +#else +static inline int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + char *id, int device) +{ + return 0; +} +#endif + +int snd_ump_receive_ump_val(struct snd_ump_endpoint *ump, u32 val); +int snd_ump_switch_protocol(struct snd_ump_endpoint *ump, unsigned int protocol); + +/* + * Some definitions for UMP + */ + +/* MIDI 2.0 Message Type */ +enum { + UMP_MSG_TYPE_UTILITY = 0x00, + UMP_MSG_TYPE_SYSTEM = 0x01, + UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE = 0x02, + UMP_MSG_TYPE_DATA = 0x03, + UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE = 0x04, + UMP_MSG_TYPE_EXTENDED_DATA = 0x05, + UMP_MSG_TYPE_FLEX_DATA = 0x0d, + UMP_MSG_TYPE_STREAM = 0x0f, +}; + +/* MIDI 2.0 SysEx / Data Status; same values for both 7-bit and 8-bit SysEx */ +enum { + UMP_SYSEX_STATUS_SINGLE = 0, + UMP_SYSEX_STATUS_START = 1, + UMP_SYSEX_STATUS_CONTINUE = 2, + UMP_SYSEX_STATUS_END = 3, +}; + +/* UMP Utility Type Status (type 0x0) */ +enum { + UMP_UTILITY_MSG_STATUS_NOOP = 0x00, + UMP_UTILITY_MSG_STATUS_JR_CLOCK = 0x01, + UMP_UTILITY_MSG_STATUS_JR_TSTAMP = 0x02, + UMP_UTILITY_MSG_STATUS_DCTPQ = 0x03, + UMP_UTILITY_MSG_STATUS_DC = 0x04, +}; + +/* UMP Stream Message Status (type 0xf) */ +enum { + UMP_STREAM_MSG_STATUS_EP_DISCOVERY = 0x00, + UMP_STREAM_MSG_STATUS_EP_INFO = 0x01, + UMP_STREAM_MSG_STATUS_DEVICE_INFO = 0x02, + UMP_STREAM_MSG_STATUS_EP_NAME = 0x03, + UMP_STREAM_MSG_STATUS_PRODUCT_ID = 0x04, + UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST = 0x05, + UMP_STREAM_MSG_STATUS_STREAM_CFG = 0x06, + UMP_STREAM_MSG_STATUS_FB_DISCOVERY = 0x10, + UMP_STREAM_MSG_STATUS_FB_INFO = 0x11, + UMP_STREAM_MSG_STATUS_FB_NAME = 0x12, + UMP_STREAM_MSG_STATUS_START_CLIP = 0x20, + UMP_STREAM_MSG_STATUS_END_CLIP = 0x21, +}; + +/* UMP Endpoint Discovery filter bitmap */ +enum { + UMP_STREAM_MSG_REQUEST_EP_INFO = (1U << 0), + UMP_STREAM_MSG_REQUEST_DEVICE_INFO = (1U << 1), + UMP_STREAM_MSG_REQUEST_EP_NAME = (1U << 2), + UMP_STREAM_MSG_REQUEST_PRODUCT_ID = (1U << 3), + UMP_STREAM_MSG_REQUEST_STREAM_CFG = (1U << 4), +}; + +/* UMP Function Block Discovery filter bitmap */ +enum { + UMP_STREAM_MSG_REQUEST_FB_INFO = (1U << 0), + UMP_STREAM_MSG_REQUEST_FB_NAME = (1U << 1), +}; + +/* UMP Endpoint Info capability bits (used for protocol request/notify, too) */ +enum { + UMP_STREAM_MSG_EP_INFO_CAP_TXJR = (1U << 0), /* Sending JRTS */ + UMP_STREAM_MSG_EP_INFO_CAP_RXJR = (1U << 1), /* Receiving JRTS */ + UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 = (1U << 8), /* MIDI 1.0 */ + UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 = (1U << 9), /* MIDI 2.0 */ +}; + +/* UMP EP / FB name string format; same as SysEx string handling */ +enum { + UMP_STREAM_MSG_FORMAT_SINGLE = 0, + UMP_STREAM_MSG_FORMAT_START = 1, + UMP_STREAM_MSG_FORMAT_CONTINUE = 2, + UMP_STREAM_MSG_FORMAT_END = 3, +}; + +/* + * Helpers for retrieving / filling bits from UMP + */ +/* get the message type (4bit) from a UMP packet (header) */ +static inline unsigned char ump_message_type(u32 data) +{ + return data >> 28; +} + +/* get the group number (0-based, 4bit) from a UMP packet (header) */ +static inline unsigned char ump_message_group(u32 data) +{ + return (data >> 24) & 0x0f; +} + +/* get the MIDI status code (4bit) from a UMP packet (header) */ +static inline unsigned char ump_message_status_code(u32 data) +{ + return (data >> 20) & 0x0f; +} + +/* get the MIDI channel number (0-based, 4bit) from a UMP packet (header) */ +static inline unsigned char ump_message_channel(u32 data) +{ + return (data >> 16) & 0x0f; +} + +/* get the MIDI status + channel combo byte (8bit) from a UMP packet (header) */ +static inline unsigned char ump_message_status_channel(u32 data) +{ + return (data >> 16) & 0xff; +} + +/* compose a UMP packet (header) from type, group and status values */ +static inline u32 ump_compose(unsigned char type, unsigned char group, + unsigned char status, unsigned char channel) +{ + return ((u32)type << 28) | ((u32)group << 24) | ((u32)status << 20) | + ((u32)channel << 16); +} + +/* get SysEx message status (for both 7 and 8bits) from a UMP packet (header) */ +static inline unsigned char ump_sysex_message_status(u32 data) +{ + return (data >> 20) & 0xf; +} + +/* get SysEx message length (for both 7 and 8bits) from a UMP packet (header) */ +static inline unsigned char ump_sysex_message_length(u32 data) +{ + return (data >> 16) & 0xf; +} + +/* For Stream Messages */ +static inline unsigned char ump_stream_message_format(u32 data) +{ + return (data >> 26) & 0x03; +} + +static inline unsigned int ump_stream_message_status(u32 data) +{ + return (data >> 16) & 0x3ff; +} + +static inline u32 ump_stream_compose(unsigned char status, unsigned short form) +{ + return (UMP_MSG_TYPE_STREAM << 28) | ((u32)form << 26) | + ((u32)status << 16); +} + +#define ump_is_groupless_msg(type) \ + ((type) == UMP_MSG_TYPE_UTILITY || (type) == UMP_MSG_TYPE_STREAM) + +#endif /* __SOUND_UMP_H */ diff --git a/include/sound/ump_convert.h b/include/sound/ump_convert.h new file mode 100644 index 000000000000..28c364c63245 --- /dev/null +++ b/include/sound/ump_convert.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef __SOUND_UMP_CONVERT_H +#define __SOUND_UMP_CONVERT_H + +#include <sound/ump_msg.h> + +/* context for converting from legacy control messages to UMP packet */ +struct ump_cvt_to_ump_bank { + bool rpn_set; + bool nrpn_set; + bool bank_set; + unsigned char cc_rpn_msb, cc_rpn_lsb; + unsigned char cc_nrpn_msb, cc_nrpn_lsb; + unsigned char cc_data_msb, cc_data_lsb; + unsigned char cc_bank_msb, cc_bank_lsb; +}; + +/* context for converting from MIDI1 byte stream to UMP packet */ +struct ump_cvt_to_ump { + /* MIDI1 intermediate buffer */ + unsigned char buf[4]; + int len; + int cmd_bytes; + + /* UMP output packet */ + u32 ump[4]; + int ump_bytes; + + /* various status */ + unsigned int in_sysex; + struct ump_cvt_to_ump_bank bank[16]; /* per channel */ +}; + +int snd_ump_convert_from_ump(const u32 *data, unsigned char *dst, + unsigned char *group_ret); +void snd_ump_convert_to_ump(struct ump_cvt_to_ump *cvt, unsigned char group, + unsigned int protocol, unsigned char c); + +/* reset the converter context, called at each open to ump */ +static inline void snd_ump_convert_reset(struct ump_cvt_to_ump *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); + +} + +#endif /* __SOUND_UMP_CONVERT_H */ diff --git a/include/sound/ump_msg.h b/include/sound/ump_msg.h new file mode 100644 index 000000000000..72f60ddfea75 --- /dev/null +++ b/include/sound/ump_msg.h @@ -0,0 +1,765 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Universal MIDI Packet (UMP): Message Definitions + */ +#ifndef __SOUND_UMP_MSG_H +#define __SOUND_UMP_MSG_H + +/* MIDI 1.0 / 2.0 Status Code (4bit) */ +enum { + UMP_MSG_STATUS_PER_NOTE_RCC = 0x0, + UMP_MSG_STATUS_PER_NOTE_ACC = 0x1, + UMP_MSG_STATUS_RPN = 0x2, + UMP_MSG_STATUS_NRPN = 0x3, + UMP_MSG_STATUS_RELATIVE_RPN = 0x4, + UMP_MSG_STATUS_RELATIVE_NRPN = 0x5, + UMP_MSG_STATUS_PER_NOTE_PITCH_BEND = 0x6, + UMP_MSG_STATUS_NOTE_OFF = 0x8, + UMP_MSG_STATUS_NOTE_ON = 0x9, + UMP_MSG_STATUS_POLY_PRESSURE = 0xa, + UMP_MSG_STATUS_CC = 0xb, + UMP_MSG_STATUS_PROGRAM = 0xc, + UMP_MSG_STATUS_CHANNEL_PRESSURE = 0xd, + UMP_MSG_STATUS_PITCH_BEND = 0xe, + UMP_MSG_STATUS_PER_NOTE_MGMT = 0xf, +}; + +/* MIDI 1.0 Channel Control (7bit) */ +enum { + UMP_CC_BANK_SELECT = 0, + UMP_CC_MODULATION = 1, + UMP_CC_BREATH = 2, + UMP_CC_FOOT = 4, + UMP_CC_PORTAMENTO_TIME = 5, + UMP_CC_DATA = 6, + UMP_CC_VOLUME = 7, + UMP_CC_BALANCE = 8, + UMP_CC_PAN = 10, + UMP_CC_EXPRESSION = 11, + UMP_CC_EFFECT_CONTROL_1 = 12, + UMP_CC_EFFECT_CONTROL_2 = 13, + UMP_CC_GP_1 = 16, + UMP_CC_GP_2 = 17, + UMP_CC_GP_3 = 18, + UMP_CC_GP_4 = 19, + UMP_CC_BANK_SELECT_LSB = 32, + UMP_CC_MODULATION_LSB = 33, + UMP_CC_BREATH_LSB = 34, + UMP_CC_FOOT_LSB = 36, + UMP_CC_PORTAMENTO_TIME_LSB = 37, + UMP_CC_DATA_LSB = 38, + UMP_CC_VOLUME_LSB = 39, + UMP_CC_BALANCE_LSB = 40, + UMP_CC_PAN_LSB = 42, + UMP_CC_EXPRESSION_LSB = 43, + UMP_CC_EFFECT1_LSB = 44, + UMP_CC_EFFECT2_LSB = 45, + UMP_CC_GP_1_LSB = 48, + UMP_CC_GP_2_LSB = 49, + UMP_CC_GP_3_LSB = 50, + UMP_CC_GP_4_LSB = 51, + UMP_CC_SUSTAIN = 64, + UMP_CC_PORTAMENTO_SWITCH = 65, + UMP_CC_SOSTENUTO = 66, + UMP_CC_SOFT_PEDAL = 67, + UMP_CC_LEGATO = 68, + UMP_CC_HOLD_2 = 69, + UMP_CC_SOUND_CONTROLLER_1 = 70, + UMP_CC_SOUND_CONTROLLER_2 = 71, + UMP_CC_SOUND_CONTROLLER_3 = 72, + UMP_CC_SOUND_CONTROLLER_4 = 73, + UMP_CC_SOUND_CONTROLLER_5 = 74, + UMP_CC_SOUND_CONTROLLER_6 = 75, + UMP_CC_SOUND_CONTROLLER_7 = 76, + UMP_CC_SOUND_CONTROLLER_8 = 77, + UMP_CC_SOUND_CONTROLLER_9 = 78, + UMP_CC_SOUND_CONTROLLER_10 = 79, + UMP_CC_GP_5 = 80, + UMP_CC_GP_6 = 81, + UMP_CC_GP_7 = 82, + UMP_CC_GP_8 = 83, + UMP_CC_PORTAMENTO_CONTROL = 84, + UMP_CC_EFFECT_1 = 91, + UMP_CC_EFFECT_2 = 92, + UMP_CC_EFFECT_3 = 93, + UMP_CC_EFFECT_4 = 94, + UMP_CC_EFFECT_5 = 95, + UMP_CC_DATA_INC = 96, + UMP_CC_DATA_DEC = 97, + UMP_CC_NRPN_LSB = 98, + UMP_CC_NRPN_MSB = 99, + UMP_CC_RPN_LSB = 100, + UMP_CC_RPN_MSB = 101, + UMP_CC_ALL_SOUND_OFF = 120, + UMP_CC_RESET_ALL = 121, + UMP_CC_LOCAL_CONTROL = 122, + UMP_CC_ALL_NOTES_OFF = 123, + UMP_CC_OMNI_OFF = 124, + UMP_CC_OMNI_ON = 125, + UMP_CC_POLY_OFF = 126, + UMP_CC_POLY_ON = 127, +}; + +/* MIDI 1.0 / 2.0 System Messages (0xfx) */ +enum { + UMP_SYSTEM_STATUS_MIDI_TIME_CODE = 0xf1, + UMP_SYSTEM_STATUS_SONG_POSITION = 0xf2, + UMP_SYSTEM_STATUS_SONG_SELECT = 0xf3, + UMP_SYSTEM_STATUS_TUNE_REQUEST = 0xf6, + UMP_SYSTEM_STATUS_TIMING_CLOCK = 0xf8, + UMP_SYSTEM_STATUS_START = 0xfa, + UMP_SYSTEM_STATUS_CONTINUE = 0xfb, + UMP_SYSTEM_STATUS_STOP = 0xfc, + UMP_SYSTEM_STATUS_ACTIVE_SENSING = 0xfe, + UMP_SYSTEM_STATUS_RESET = 0xff, +}; + +/* MIDI 1.0 Realtime and SysEx status messages (0xfx) */ +enum { + UMP_MIDI1_MSG_REALTIME = 0xf0, /* mask */ + UMP_MIDI1_MSG_SYSEX_START = 0xf0, + UMP_MIDI1_MSG_SYSEX_END = 0xf7, +}; + +/* + * UMP Message Definitions + */ + +/* MIDI 1.0 Note Off / Note On (32bit) */ +struct snd_ump_midi1_msg_note { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 velocity:8; +#else + u32 velocity:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 Poly Pressure (32bit) */ +struct snd_ump_midi1_msg_paf { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 data:8; +#else + u32 data:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 Control Change (32bit) */ +struct snd_ump_midi1_msg_cc { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 index:8; + u32 data:8; +#else + u32 data:8; + u32 index:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 Program Change (32bit) */ +struct snd_ump_midi1_msg_program { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 program:8; + u32 reserved:8; +#else + u32 reserved:8; + u32 program:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 Channel Pressure (32bit) */ +struct snd_ump_midi1_msg_caf { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 data:8; + u32 reserved:8; +#else + u32 reserved:8; + u32 data:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 Pitch Bend (32bit) */ +struct snd_ump_midi1_msg_pitchbend { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 data_lsb:8; + u32 data_msb:8; +#else + u32 data_msb:8; + u32 data_lsb:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* System Common and Real Time messages (32bit); no channel field */ +struct snd_ump_system_msg { +#ifdef __BIG_ENDIAN_BITFIELD + u32 type:4; + u32 group:4; + u32 status:8; + u32 parm1:8; + u32 parm2:8; +#else + u32 parm2:8; + u32 parm1:8; + u32 status:8; + u32 group:4; + u32 type:4; +#endif +} __packed; + +/* MIDI 1.0 UMP CVM (32bit) */ +union snd_ump_midi1_msg { + struct snd_ump_midi1_msg_note note; + struct snd_ump_midi1_msg_paf paf; + struct snd_ump_midi1_msg_cc cc; + struct snd_ump_midi1_msg_program pg; + struct snd_ump_midi1_msg_caf caf; + struct snd_ump_midi1_msg_pitchbend pb; + struct snd_ump_system_msg system; + u32 raw; +}; + +/* MIDI 2.0 Note Off / Note On (64bit) */ +struct snd_ump_midi2_msg_note { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 attribute_type:8; + /* 1 */ + u32 velocity:16; + u32 attribute_data:16; +#else + /* 0 */ + u32 attribute_type:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 attribute_data:16; + u32 velocity:16; +#endif +} __packed; + +/* MIDI 2.0 Poly Pressure (64bit) */ +struct snd_ump_midi2_msg_paf { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 reserved:8; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 reserved:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Per-Note Controller (64bit) */ +struct snd_ump_midi2_msg_pernote_cc { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 index:8; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 index:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Per-Note Management (64bit) */ +struct snd_ump_midi2_msg_pernote_mgmt { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 flags:8; + /* 1 */ + u32 reserved; +#else + /* 0 */ + u32 flags:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 reserved; +#endif +} __packed; + +/* MIDI 2.0 Control Change (64bit) */ +struct snd_ump_midi2_msg_cc { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 index:8; + u32 reserved:8; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 reserved:8; + u32 index:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Registered Controller (RPN) / Assignable Controller (NRPN) (64bit) */ +struct snd_ump_midi2_msg_rpn { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 bank:8; + u32 index:8; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 index:8; + u32 bank:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Program Change (64bit) */ +struct snd_ump_midi2_msg_program { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 reserved:15; + u32 bank_valid:1; + /* 1 */ + u32 program:8; + u32 reserved2:8; + u32 bank_msb:8; + u32 bank_lsb:8; +#else + /* 0 */ + u32 bank_valid:1; + u32 reserved:15; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 bank_lsb:8; + u32 bank_msb:8; + u32 reserved2:8; + u32 program:8; +#endif +} __packed; + +/* MIDI 2.0 Channel Pressure (64bit) */ +struct snd_ump_midi2_msg_caf { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 reserved:16; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 reserved:16; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Pitch Bend (64bit) */ +struct snd_ump_midi2_msg_pitchbend { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 reserved:16; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 reserved:16; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 Per-Note Pitch Bend (64bit) */ +struct snd_ump_midi2_msg_pernote_pitchbend { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 group:4; + u32 status:4; + u32 channel:4; + u32 note:8; + u32 reserved:8; + /* 1 */ + u32 data; +#else + /* 0 */ + u32 reserved:8; + u32 note:8; + u32 channel:4; + u32 status:4; + u32 group:4; + u32 type:4; + /* 1 */ + u32 data; +#endif +} __packed; + +/* MIDI 2.0 UMP CVM (64bit) */ +union snd_ump_midi2_msg { + struct snd_ump_midi2_msg_note note; + struct snd_ump_midi2_msg_paf paf; + struct snd_ump_midi2_msg_pernote_cc pernote_cc; + struct snd_ump_midi2_msg_pernote_mgmt pernote_mgmt; + struct snd_ump_midi2_msg_cc cc; + struct snd_ump_midi2_msg_rpn rpn; + struct snd_ump_midi2_msg_program pg; + struct snd_ump_midi2_msg_caf caf; + struct snd_ump_midi2_msg_pitchbend pb; + struct snd_ump_midi2_msg_pernote_pitchbend pernote_pb; + u32 raw[2]; +}; + +/* UMP Stream Message: Endpoint Discovery (128bit) */ +struct snd_ump_stream_msg_ep_discovery { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 ump_version_major:8; + u32 ump_version_minor:8; + /* 1 */ + u32 reserved:24; + u32 filter_bitmap:8; + /* 2-3 */ + u32 reserved2[2]; +#else + /* 0 */ + u32 ump_version_minor:8; + u32 ump_version_major:8; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1 */ + u32 filter_bitmap:8; + u32 reserved:24; + /* 2-3 */ + u32 reserved2[2]; +#endif +} __packed; + +/* UMP Stream Message: Endpoint Info Notification (128bit) */ +struct snd_ump_stream_msg_ep_info { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 ump_version_major:8; + u32 ump_version_minor:8; + /* 1 */ + u32 static_function_block:1; + u32 num_function_blocks:7; + u32 reserved:8; + u32 protocol:8; + u32 reserved2:6; + u32 jrts:2; + /* 2-3 */ + u32 reserved3[2]; +#else + /* 0 */ + u32 ump_version_minor:8; + u32 ump_version_major:8; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1 */ + u32 jrts:2; + u32 reserved2:6; + u32 protocol:8; + u32 reserved:8; + u32 num_function_blocks:7; + u32 static_function_block:1; + /* 2-3 */ + u32 reserved3[2]; +#endif +} __packed; + +/* UMP Stream Message: Device Info Notification (128bit) */ +struct snd_ump_stream_msg_devince_info { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 reserved:16; + /* 1 */ + u32 manufacture_id; + /* 2 */ + u8 family_lsb; + u8 family_msb; + u8 model_lsb; + u8 model_msb; + /* 3 */ + u32 sw_revision; +#else + /* 0 */ + u32 reserved:16; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1 */ + u32 manufacture_id; + /* 2 */ + u8 model_msb; + u8 model_lsb; + u8 family_msb; + u8 family_lsb; + /* 3 */ + u32 sw_revision; +#endif +} __packed; + +/* UMP Stream Message: Stream Config Request / Notification (128bit) */ +struct snd_ump_stream_msg_stream_cfg { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 protocol:8; + u32 reserved:6; + u32 jrts:2; + /* 1-3 */ + u32 reserved2[3]; +#else + /* 0 */ + u32 jrts:2; + u32 reserved:6; + u32 protocol:8; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1-3 */ + u32 reserved2[3]; +#endif +} __packed; + +/* UMP Stream Message: Function Block Discovery (128bit) */ +struct snd_ump_stream_msg_fb_discovery { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 function_block_id:8; + u32 filter:8; + /* 1-3 */ + u32 reserved[3]; +#else + /* 0 */ + u32 filter:8; + u32 function_block_id:8; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1-3 */ + u32 reserved[3]; +#endif +} __packed; + +/* UMP Stream Message: Function Block Info Notification (128bit) */ +struct snd_ump_stream_msg_fb_info { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u32 type:4; + u32 format:2; + u32 status:10; + u32 active:1; + u32 function_block_id:7; + u32 reserved:2; + u32 ui_hint:2; + u32 midi_10:2; + u32 direction:2; + /* 1 */ + u32 first_group:8; + u32 num_groups:8; + u32 midi_ci_version:8; + u32 sysex8_streams:8; + /* 2-3 */ + u32 reserved2[2]; +#else + /* 0 */ + u32 direction:2; + u32 midi_10:2; + u32 ui_hint:2; + u32 reserved:2; + u32 function_block_id:7; + u32 active:1; + u32 status:10; + u32 format:2; + u32 type:4; + /* 1 */ + u32 sysex8_streams:8; + u32 midi_ci_version:8; + u32 num_groups:8; + u32 first_group:8; + /* 2-3 */ + u32 reserved2[2]; +#endif +} __packed; + +/* UMP Stream Message: Function Block Name Notification (128bit) */ +struct snd_ump_stream_msg_fb_name { +#ifdef __BIG_ENDIAN_BITFIELD + /* 0 */ + u16 type:4; + u16 format:2; + u16 status:10; + u8 function_block_id; + u8 name0; + /* 1-3 */ + u8 name[12]; +#else + /* 0 */ + u8 name0; + u8 function_block_id; + u16 status:10; + u16 format:2; + u16 type:4; + /* 1-3 */ + u8 name[12]; // FIXME: byte order +#endif +} __packed; + +/* MIDI 2.0 Stream Messages (128bit) */ +union snd_ump_stream_msg { + struct snd_ump_stream_msg_ep_discovery ep_discovery; + struct snd_ump_stream_msg_ep_info ep_info; + struct snd_ump_stream_msg_devince_info device_info; + struct snd_ump_stream_msg_stream_cfg stream_cfg; + struct snd_ump_stream_msg_fb_discovery fb_discovery; + struct snd_ump_stream_msg_fb_info fb_info; + struct snd_ump_stream_msg_fb_name fb_name; + u32 raw[4]; +}; + +#endif /* __SOUND_UMP_MSG_H */ diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 229118156a1f..4c15420e8965 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -562,12 +562,13 @@ struct iscsit_conn { #define LOGIN_FLAGS_READ_ACTIVE 2 #define LOGIN_FLAGS_WRITE_ACTIVE 3 #define LOGIN_FLAGS_CLOSED 4 +#define LOGIN_FLAGS_WORKER_RUNNING 5 unsigned long login_flags; struct delayed_work login_work; struct iscsi_login *login; struct timer_list nopin_timer; struct timer_list nopin_response_timer; - struct timer_list transport_timer; + struct timer_list login_timer; struct task_struct *login_kworker; /* Spinlock used for add/deleting cmd's from conn_cmd_list */ spinlock_t cmd_lock; @@ -576,6 +577,8 @@ struct iscsit_conn { spinlock_t nopin_timer_lock; spinlock_t response_queue_lock; spinlock_t state_lock; + spinlock_t login_timer_lock; + spinlock_t login_worker_lock; /* libcrypto RX and TX contexts for crc32c */ struct ahash_request *conn_rx_hash; struct ahash_request *conn_tx_hash; @@ -792,7 +795,6 @@ struct iscsi_np { enum np_thread_state_table np_thread_state; bool enabled; atomic_t np_reset_count; - enum iscsi_timer_flags_table np_login_timer_flags; u32 np_exports; enum np_flags_table np_flags; spinlock_t np_thread_lock; @@ -800,7 +802,6 @@ struct iscsi_np { struct socket *np_socket; struct sockaddr_storage np_sockaddr; struct task_struct *np_thread; - struct timer_list np_login_timer; void *np_context; struct iscsit_transport *np_transport; struct list_head np_list; diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index a3c193df25b3..739df993aa5e 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -62,13 +62,17 @@ struct target_backend_ops { struct configfs_attribute **tb_dev_action_attrs; }; -struct sbc_ops { +struct exec_cmd_ops { sense_reason_t (*execute_rw)(struct se_cmd *cmd, struct scatterlist *, u32, enum dma_data_direction); sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd); sense_reason_t (*execute_write_same)(struct se_cmd *cmd); sense_reason_t (*execute_unmap)(struct se_cmd *cmd, sector_t lba, sector_t nolb); + sense_reason_t (*execute_pr_out)(struct se_cmd *cmd, u8 sa, u64 key, + u64 sa_key, u8 type, bool aptpl); + sense_reason_t (*execute_pr_in)(struct se_cmd *cmd, u8 sa, + unsigned char *param_data); }; int transport_backend_register(const struct target_backend_ops *); @@ -86,7 +90,7 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); sense_reason_t spc_emulate_inquiry_std(struct se_cmd *, unsigned char *); sense_reason_t spc_emulate_evpd_83(struct se_cmd *, unsigned char *); -sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops); +sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct exec_cmd_ops *ops); u32 sbc_get_device_rev(struct se_device *dev); u32 sbc_get_device_type(struct se_device *dev); sector_t sbc_get_write_same_sectors(struct se_cmd *cmd); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 5f8e96f1516f..159567359bbb 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -880,7 +880,8 @@ struct target_opcode_descriptor { u8 specific_timeout; u16 nominal_timeout; u16 recommended_timeout; - bool (*enabled)(struct se_cmd *cmd); + bool (*enabled)(struct target_opcode_descriptor *descr, + struct se_cmd *cmd); void (*update_usage_bits)(u8 *usage_bits, struct se_device *dev); u8 usage_bits[]; diff --git a/include/trace/events/block.h b/include/trace/events/block.h index 7f4dfbdf12a6..40e60c33cc6f 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -246,6 +246,32 @@ DEFINE_EVENT(block_rq, block_rq_merge, ); /** + * block_io_start - insert a request for execution + * @rq: block IO operation request + * + * Called when block operation request @rq is queued for execution + */ +DEFINE_EVENT(block_rq, block_io_start, + + TP_PROTO(struct request *rq), + + TP_ARGS(rq) +); + +/** + * block_io_done - block IO operation request completed + * @rq: block IO operation request + * + * Called when block operation request @rq is completed + */ +DEFINE_EVENT(block_rq, block_io_done, + + TP_PROTO(struct request *rq), + + TP_ARGS(rq) +); + +/** * block_bio_complete - completed all work on the block operation * @q: queue holding the block operation * @bio: block operation completed diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 8ea9cea9bfeb..a8206f5332e9 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -661,6 +661,35 @@ DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_mark_finished, TP_ARGS(inode, ordered) ); +TRACE_EVENT(btrfs_finish_ordered_extent, + + TP_PROTO(const struct btrfs_inode *inode, u64 start, u64 len, + bool uptodate), + + TP_ARGS(inode, start, len, uptodate), + + TP_STRUCT__entry_btrfs( + __field( u64, ino ) + __field( u64, start ) + __field( u64, len ) + __field( bool, uptodate ) + __field( u64, root_objectid ) + ), + + TP_fast_assign_btrfs(inode->root->fs_info, + __entry->ino = btrfs_ino(inode); + __entry->start = start; + __entry->len = len; + __entry->uptodate = uptodate; + __entry->root_objectid = inode->root->root_key.objectid; + ), + + TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu len=%llu uptodate=%d", + show_root_type(__entry->root_objectid), + __entry->ino, __entry->start, + __entry->len, !!__entry->uptodate) +); + DECLARE_EVENT_CLASS(btrfs__writepage, TP_PROTO(const struct page *page, const struct inode *inode, @@ -1982,25 +2011,27 @@ DEFINE_EVENT(btrfs__prelim_ref, btrfs_prelim_ref_insert, ); TRACE_EVENT(btrfs_inode_mod_outstanding_extents, - TP_PROTO(const struct btrfs_root *root, u64 ino, int mod), + TP_PROTO(const struct btrfs_root *root, u64 ino, int mod, unsigned outstanding), - TP_ARGS(root, ino, mod), + TP_ARGS(root, ino, mod, outstanding), TP_STRUCT__entry_btrfs( __field( u64, root_objectid ) __field( u64, ino ) __field( int, mod ) + __field( unsigned, outstanding ) ), TP_fast_assign_btrfs(root->fs_info, __entry->root_objectid = root->root_key.objectid; __entry->ino = ino; __entry->mod = mod; + __entry->outstanding = outstanding; ), - TP_printk_btrfs("root=%llu(%s) ino=%llu mod=%d", + TP_printk_btrfs("root=%llu(%s) ino=%llu mod=%d outstanding=%u", show_root_type(__entry->root_objectid), - __entry->ino, __entry->mod) + __entry->ino, __entry->mod, __entry->outstanding) ); DECLARE_EVENT_CLASS(btrfs__block_group, diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h index 3313eb83c117..2b2a975efd20 100644 --- a/include/trace/events/compaction.h +++ b/include/trace/events/compaction.h @@ -64,6 +64,17 @@ DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_isolate_freepages, TP_ARGS(start_pfn, end_pfn, nr_scanned, nr_taken) ); +DEFINE_EVENT(mm_compaction_isolate_template, mm_compaction_fast_isolate_freepages, + + TP_PROTO( + unsigned long start_pfn, + unsigned long end_pfn, + unsigned long nr_scanned, + unsigned long nr_taken), + + TP_ARGS(start_pfn, end_pfn, nr_scanned, nr_taken) +); + #ifdef CONFIG_COMPACTION TRACE_EVENT(mm_compaction_migratepages, diff --git a/include/trace/events/csd.h b/include/trace/events/csd.h new file mode 100644 index 000000000000..67e9d01f80c2 --- /dev/null +++ b/include/trace/events/csd.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM csd + +#if !defined(_TRACE_CSD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_CSD_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(csd_queue_cpu, + + TP_PROTO(const unsigned int cpu, + unsigned long callsite, + smp_call_func_t func, + struct __call_single_data *csd), + + TP_ARGS(cpu, callsite, func, csd), + + TP_STRUCT__entry( + __field(unsigned int, cpu) + __field(void *, callsite) + __field(void *, func) + __field(void *, csd) + ), + + TP_fast_assign( + __entry->cpu = cpu; + __entry->callsite = (void *)callsite; + __entry->func = func; + __entry->csd = csd; + ), + + TP_printk("cpu=%u callsite=%pS func=%ps csd=%p", + __entry->cpu, __entry->callsite, __entry->func, __entry->csd) + ); + +/* + * Tracepoints for a function which is called as an effect of smp_call_function.* + */ +DECLARE_EVENT_CLASS(csd_function, + + TP_PROTO(smp_call_func_t func, struct __call_single_data *csd), + + TP_ARGS(func, csd), + + TP_STRUCT__entry( + __field(void *, func) + __field(void *, csd) + ), + + TP_fast_assign( + __entry->func = func; + __entry->csd = csd; + ), + + TP_printk("func=%ps, csd=%p", __entry->func, __entry->csd) +); + +DEFINE_EVENT(csd_function, csd_function_entry, + TP_PROTO(smp_call_func_t func, struct __call_single_data *csd), + TP_ARGS(func, csd) +); + +DEFINE_EVENT(csd_function, csd_function_exit, + TP_PROTO(smp_call_func_t func, struct __call_single_data *csd), + TP_ARGS(func, csd) +); + +#endif /* _TRACE_CSD_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index ebccf6a6aa1b..65029dfb92fb 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -120,6 +120,20 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX); { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}, \ { EXT4_FC_REASON_ENCRYPTED_FILENAME, "ENCRYPTED_FILENAME"}) +TRACE_DEFINE_ENUM(CR_POWER2_ALIGNED); +TRACE_DEFINE_ENUM(CR_GOAL_LEN_FAST); +TRACE_DEFINE_ENUM(CR_BEST_AVAIL_LEN); +TRACE_DEFINE_ENUM(CR_GOAL_LEN_SLOW); +TRACE_DEFINE_ENUM(CR_ANY_FREE); + +#define show_criteria(cr) \ + __print_symbolic(cr, \ + { CR_POWER2_ALIGNED, "CR_POWER2_ALIGNED" }, \ + { CR_GOAL_LEN_FAST, "CR_GOAL_LEN_FAST" }, \ + { CR_BEST_AVAIL_LEN, "CR_BEST_AVAIL_LEN" }, \ + { CR_GOAL_LEN_SLOW, "CR_GOAL_LEN_SLOW" }, \ + { CR_ANY_FREE, "CR_ANY_FREE" }) + TRACE_EVENT(ext4_other_inode_update_time, TP_PROTO(struct inode *inode, ino_t orig_ino), @@ -560,10 +574,10 @@ TRACE_EVENT(ext4_writepages_result, (unsigned long) __entry->writeback_index) ); -DECLARE_EVENT_CLASS(ext4__page_op, - TP_PROTO(struct page *page), +DECLARE_EVENT_CLASS(ext4__folio_op, + TP_PROTO(struct inode *inode, struct folio *folio), - TP_ARGS(page), + TP_ARGS(inode, folio), TP_STRUCT__entry( __field( dev_t, dev ) @@ -573,29 +587,29 @@ DECLARE_EVENT_CLASS(ext4__page_op, ), TP_fast_assign( - __entry->dev = page->mapping->host->i_sb->s_dev; - __entry->ino = page->mapping->host->i_ino; - __entry->index = page->index; + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->index = folio->index; ), - TP_printk("dev %d,%d ino %lu page_index %lu", + TP_printk("dev %d,%d ino %lu folio_index %lu", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, (unsigned long) __entry->index) ); -DEFINE_EVENT(ext4__page_op, ext4_readpage, +DEFINE_EVENT(ext4__folio_op, ext4_read_folio, - TP_PROTO(struct page *page), + TP_PROTO(struct inode *inode, struct folio *folio), - TP_ARGS(page) + TP_ARGS(inode, folio) ); -DEFINE_EVENT(ext4__page_op, ext4_releasepage, +DEFINE_EVENT(ext4__folio_op, ext4_release_folio, - TP_PROTO(struct page *page), + TP_PROTO(struct inode *inode, struct folio *folio), - TP_ARGS(page) + TP_ARGS(inode, folio) ); DECLARE_EVENT_CLASS(ext4_invalidate_folio_op, @@ -1063,7 +1077,7 @@ TRACE_EVENT(ext4_mballoc_alloc, ), TP_printk("dev %d,%d inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u " - "result %u/%d/%u@%u blks %u grps %u cr %u flags %s " + "result %u/%d/%u@%u blks %u grps %u cr %s flags %s " "tail %u broken %u", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long) __entry->ino, @@ -1073,7 +1087,7 @@ TRACE_EVENT(ext4_mballoc_alloc, __entry->goal_len, __entry->goal_logical, __entry->result_group, __entry->result_start, __entry->result_len, __entry->result_logical, - __entry->found, __entry->groups, __entry->cr, + __entry->found, __entry->groups, show_criteria(__entry->cr), show_mballoc_flags(__entry->flags), __entry->tail, __entry->buddy ? 1 << __entry->buddy : 0) ); diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 99cbc5949e3c..793f82cc1515 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1512,7 +1512,7 @@ DEFINE_EVENT(f2fs_discard, f2fs_remove_discard, TP_ARGS(dev, blkstart, blklen) ); -TRACE_EVENT(f2fs_issue_reset_zone, +DECLARE_EVENT_CLASS(f2fs_reset_zone, TP_PROTO(struct block_device *dev, block_t blkstart), @@ -1528,11 +1528,25 @@ TRACE_EVENT(f2fs_issue_reset_zone, __entry->blkstart = blkstart; ), - TP_printk("dev = (%d,%d), reset zone at block = 0x%llx", + TP_printk("dev = (%d,%d), zone at block = 0x%llx", show_dev(__entry->dev), (unsigned long long)__entry->blkstart) ); +DEFINE_EVENT(f2fs_reset_zone, f2fs_queue_reset_zone, + + TP_PROTO(struct block_device *dev, block_t blkstart), + + TP_ARGS(dev, blkstart) +); + +DEFINE_EVENT(f2fs_reset_zone, f2fs_issue_reset_zone, + + TP_PROTO(struct block_device *dev, block_t blkstart), + + TP_ARGS(dev, blkstart) +); + TRACE_EVENT(f2fs_issue_flush, TP_PROTO(struct block_device *dev, unsigned int nobarrier, @@ -1979,6 +1993,7 @@ TRACE_EVENT(f2fs_iostat, __field(unsigned long long, fs_nrio) __field(unsigned long long, fs_mrio) __field(unsigned long long, fs_discard) + __field(unsigned long long, fs_reset_zone) ), TP_fast_assign( @@ -2010,12 +2025,14 @@ TRACE_EVENT(f2fs_iostat, __entry->fs_nrio = iostat[FS_NODE_READ_IO]; __entry->fs_mrio = iostat[FS_META_READ_IO]; __entry->fs_discard = iostat[FS_DISCARD_IO]; + __entry->fs_reset_zone = iostat[FS_ZONE_RESET_IO]; ), TP_printk("dev = (%d,%d), " "app [write=%llu (direct=%llu, buffered=%llu), mapped=%llu, " "compr(buffered=%llu, mapped=%llu)], " - "fs [data=%llu, cdata=%llu, node=%llu, meta=%llu, discard=%llu], " + "fs [data=%llu, cdata=%llu, node=%llu, meta=%llu, discard=%llu, " + "reset_zone=%llu], " "gc [data=%llu, node=%llu], " "cp [data=%llu, node=%llu, meta=%llu], " "app [read=%llu (direct=%llu, buffered=%llu), mapped=%llu], " @@ -2026,6 +2043,7 @@ TRACE_EVENT(f2fs_iostat, __entry->app_bio, __entry->app_mio, __entry->app_bcdio, __entry->app_mcdio, __entry->fs_dio, __entry->fs_cdio, __entry->fs_nio, __entry->fs_mio, __entry->fs_discard, + __entry->fs_reset_zone, __entry->fs_gc_dio, __entry->fs_gc_nio, __entry->fs_cp_dio, __entry->fs_cp_nio, __entry->fs_cp_mio, __entry->app_rio, __entry->app_drio, __entry->app_brio, diff --git a/include/trace/events/fib.h b/include/trace/events/fib.h index 76297ecd4935..20b914250ce9 100644 --- a/include/trace/events/fib.h +++ b/include/trace/events/fib.h @@ -65,7 +65,7 @@ TRACE_EVENT(fib_table_lookup, } dev = nhc ? nhc->nhc_dev : NULL; - strlcpy(__entry->name, dev ? dev->name : "-", IFNAMSIZ); + strscpy(__entry->name, dev ? dev->name : "-", IFNAMSIZ); if (nhc) { if (nhc->nhc_gw_family == AF_INET) { diff --git a/include/trace/events/fib6.h b/include/trace/events/fib6.h index 4d3e607b3cde..5d7ee2610728 100644 --- a/include/trace/events/fib6.h +++ b/include/trace/events/fib6.h @@ -63,7 +63,7 @@ TRACE_EVENT(fib6_table_lookup, } if (res->nh && res->nh->fib_nh_dev) { - strlcpy(__entry->name, res->nh->fib_nh_dev->name, IFNAMSIZ); + strscpy(__entry->name, res->nh->fib_nh_dev->name, IFNAMSIZ); } else { strcpy(__entry->name, "-"); } diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index b63e7c0fbbe5..1478b9dd05fa 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -223,8 +223,8 @@ IF_HAVE_VM_SOFTDIRTY(VM_SOFTDIRTY, "softdirty" ) \ #define compact_result_to_feedback(result) \ ({ \ enum compact_result __result = result; \ - (compaction_failed(__result)) ? COMPACTION_FAILED : \ - (compaction_withdrawn(__result)) ? COMPACTION_WITHDRAWN : COMPACTION_PROGRESS; \ + (__result == COMPACT_COMPLETE) ? COMPACTION_FAILED : \ + (__result == COMPACT_SUCCESS) ? COMPACTION_PROGRESS : COMPACTION_WITHDRAWN; \ }) #define COMPACTION_FEEDBACK \ diff --git a/include/trace/events/net.h b/include/trace/events/net.h index da611a7aaf97..f667c76a3b02 100644 --- a/include/trace/events/net.h +++ b/include/trace/events/net.h @@ -51,7 +51,8 @@ TRACE_EVENT(net_dev_start_xmit, __entry->network_offset = skb_network_offset(skb); __entry->transport_offset_valid = skb_transport_header_was_set(skb); - __entry->transport_offset = skb_transport_offset(skb); + __entry->transport_offset = skb_transport_header_was_set(skb) ? + skb_transport_offset(skb) : 0; __entry->tx_flags = skb_shinfo(skb)->tx_flags; __entry->gso_size = skb_shinfo(skb)->gso_size; __entry->gso_segs = skb_shinfo(skb)->gso_segs; diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index 8f461e04e5f0..f8069ef2ee0f 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -2112,6 +2112,14 @@ DEFINE_POST_CHUNK_EVENT(read); DEFINE_POST_CHUNK_EVENT(write); DEFINE_POST_CHUNK_EVENT(reply); +DEFINE_EVENT(svcrdma_post_chunk_class, svcrdma_cc_release, + TP_PROTO( + const struct rpc_rdma_cid *cid, + int sqecount + ), + TP_ARGS(cid, sqecount) +); + TRACE_EVENT(svcrdma_wc_read, TP_PROTO( const struct ib_wc *wc, diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index a2c7befd451a..8e2d9b1b0e77 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -269,9 +269,14 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, __field( unsigned int, prot_sglen ) __field( unsigned char, prot_op ) __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + __field( u8, sense_key ) + __field( u8, asc ) + __field( u8, ascq ) ), TP_fast_assign( + struct scsi_sense_hdr sshdr; + __entry->host_no = cmd->device->host->host_no; __entry->channel = cmd->device->channel; __entry->id = cmd->device->id; @@ -285,11 +290,22 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, __entry->prot_sglen = scsi_prot_sg_count(cmd); __entry->prot_op = scsi_get_prot_op(cmd); memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + if (cmd->sense_buffer && SCSI_SENSE_VALID(cmd) && + scsi_command_normalize_sense(cmd, &sshdr)) { + __entry->sense_key = sshdr.sense_key; + __entry->asc = sshdr.asc; + __entry->ascq = sshdr.ascq; + } else { + __entry->sense_key = 0; + __entry->asc = 0; + __entry->ascq = 0; + } ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u " \ "prot_op=%s driver_tag=%d scheduler_tag=%d cmnd=(%s %s raw=%s) " \ - "result=(driver=%s host=%s message=%s status=%s)", + "result=(driver=%s host=%s message=%s status=%s) " + "sense=(key=%#x asc=%#x ascq=%#x)", __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, show_prot_op_name(__entry->prot_op), __entry->driver_tag, @@ -299,7 +315,8 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, "DRIVER_OK", show_hostbyte_name(((__entry->result) >> 16) & 0xff), "COMMAND_COMPLETE", - show_statusbyte_name(__entry->result & 0xff)) + show_statusbyte_name(__entry->result & 0xff), + __entry->sense_key, __entry->asc, __entry->ascq) ); DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 31bc7025cb44..43711753616a 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -139,36 +139,68 @@ DEFINE_RPC_CLNT_EVENT(release); DEFINE_RPC_CLNT_EVENT(replace_xprt); DEFINE_RPC_CLNT_EVENT(replace_xprt_err); +TRACE_DEFINE_ENUM(RPC_XPRTSEC_NONE); +TRACE_DEFINE_ENUM(RPC_XPRTSEC_TLS_X509); + +#define rpc_show_xprtsec_policy(policy) \ + __print_symbolic(policy, \ + { RPC_XPRTSEC_NONE, "none" }, \ + { RPC_XPRTSEC_TLS_ANON, "tls-anon" }, \ + { RPC_XPRTSEC_TLS_X509, "tls-x509" }) + +#define rpc_show_create_flags(flags) \ + __print_flags(flags, "|", \ + { RPC_CLNT_CREATE_HARDRTRY, "HARDRTRY" }, \ + { RPC_CLNT_CREATE_AUTOBIND, "AUTOBIND" }, \ + { RPC_CLNT_CREATE_NONPRIVPORT, "NONPRIVPORT" }, \ + { RPC_CLNT_CREATE_NOPING, "NOPING" }, \ + { RPC_CLNT_CREATE_DISCRTRY, "DISCRTRY" }, \ + { RPC_CLNT_CREATE_QUIET, "QUIET" }, \ + { RPC_CLNT_CREATE_INFINITE_SLOTS, \ + "INFINITE_SLOTS" }, \ + { RPC_CLNT_CREATE_NO_IDLE_TIMEOUT, \ + "NO_IDLE_TIMEOUT" }, \ + { RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT, \ + "NO_RETRANS_TIMEOUT" }, \ + { RPC_CLNT_CREATE_SOFTERR, "SOFTERR" }, \ + { RPC_CLNT_CREATE_REUSEPORT, "REUSEPORT" }) + TRACE_EVENT(rpc_clnt_new, TP_PROTO( const struct rpc_clnt *clnt, const struct rpc_xprt *xprt, - const char *program, - const char *server + const struct rpc_create_args *args ), - TP_ARGS(clnt, xprt, program, server), + TP_ARGS(clnt, xprt, args), TP_STRUCT__entry( __field(unsigned int, client_id) + __field(unsigned long, xprtsec) + __field(unsigned long, flags) + __string(program, clnt->cl_program->name) + __string(server, xprt->servername) __string(addr, xprt->address_strings[RPC_DISPLAY_ADDR]) __string(port, xprt->address_strings[RPC_DISPLAY_PORT]) - __string(program, program) - __string(server, server) ), TP_fast_assign( __entry->client_id = clnt->cl_clid; + __entry->xprtsec = args->xprtsec.policy; + __entry->flags = args->flags; + __assign_str(program, clnt->cl_program->name); + __assign_str(server, xprt->servername); __assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]); __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]); - __assign_str(program, program); - __assign_str(server, server); ), - TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER - " peer=[%s]:%s program=%s server=%s", + TP_printk("client=" SUNRPC_TRACE_CLID_SPECIFIER " peer=[%s]:%s" + " program=%s server=%s xprtsec=%s flags=%s", __entry->client_id, __get_str(addr), __get_str(port), - __get_str(program), __get_str(server)) + __get_str(program), __get_str(server), + rpc_show_xprtsec_policy(__entry->xprtsec), + rpc_show_create_flags(__entry->flags) + ) ); TRACE_EVENT(rpc_clnt_new_err, @@ -1493,6 +1525,50 @@ TRACE_EVENT(rpcb_unregister, ) ); +/** + ** RPC-over-TLS tracepoints + **/ + +DECLARE_EVENT_CLASS(rpc_tls_class, + TP_PROTO( + const struct rpc_clnt *clnt, + const struct rpc_xprt *xprt + ), + + TP_ARGS(clnt, xprt), + + TP_STRUCT__entry( + __field(unsigned long, requested_policy) + __field(u32, version) + __string(servername, xprt->servername) + __string(progname, clnt->cl_program->name) + ), + + TP_fast_assign( + __entry->requested_policy = clnt->cl_xprtsec.policy; + __entry->version = clnt->cl_vers; + __assign_str(servername, xprt->servername); + __assign_str(progname, clnt->cl_program->name) + ), + + TP_printk("server=%s %sv%u requested_policy=%s", + __get_str(servername), __get_str(progname), __entry->version, + rpc_show_xprtsec_policy(__entry->requested_policy) + ) +); + +#define DEFINE_RPC_TLS_EVENT(name) \ + DEFINE_EVENT(rpc_tls_class, rpc_tls_##name, \ + TP_PROTO( \ + const struct rpc_clnt *clnt, \ + const struct rpc_xprt *xprt \ + ), \ + TP_ARGS(clnt, xprt)) + +DEFINE_RPC_TLS_EVENT(unavailable); +DEFINE_RPC_TLS_EVENT(not_started); + + /* Record an xdr_buf containing a fully-formed RPC message */ DECLARE_EVENT_CLASS(svc_xdr_msg_class, TP_PROTO( @@ -2104,31 +2180,46 @@ DEFINE_SVC_DEFERRED_EVENT(drop); DEFINE_SVC_DEFERRED_EVENT(queue); DEFINE_SVC_DEFERRED_EVENT(recv); -TRACE_EVENT(svcsock_new_socket, +DECLARE_EVENT_CLASS(svcsock_lifetime_class, TP_PROTO( + const void *svsk, const struct socket *socket ), - - TP_ARGS(socket), - + TP_ARGS(svsk, socket), TP_STRUCT__entry( + __field(unsigned int, netns_ino) + __field(const void *, svsk) + __field(const void *, sk) __field(unsigned long, type) __field(unsigned long, family) - __field(bool, listener) + __field(unsigned long, state) ), - TP_fast_assign( + struct sock *sk = socket->sk; + + __entry->netns_ino = sock_net(sk)->ns.inum; + __entry->svsk = svsk; + __entry->sk = sk; __entry->type = socket->type; - __entry->family = socket->sk->sk_family; - __entry->listener = (socket->sk->sk_state == TCP_LISTEN); + __entry->family = sk->sk_family; + __entry->state = sk->sk_state; ), - - TP_printk("type=%s family=%s%s", - show_socket_type(__entry->type), + TP_printk("svsk=%p type=%s family=%s%s", + __entry->svsk, show_socket_type(__entry->type), rpc_show_address_family(__entry->family), - __entry->listener ? " (listener)" : "" + __entry->state == TCP_LISTEN ? " (listener)" : "" ) ); +#define DEFINE_SVCSOCK_LIFETIME_EVENT(name) \ + DEFINE_EVENT(svcsock_lifetime_class, name, \ + TP_PROTO( \ + const void *svsk, \ + const struct socket *socket \ + ), \ + TP_ARGS(svsk, socket)) + +DEFINE_SVCSOCK_LIFETIME_EVENT(svcsock_new); +DEFINE_SVCSOCK_LIFETIME_EVENT(svcsock_free); TRACE_EVENT(svcsock_marker, TP_PROTO( diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 3e8619c72f77..b4bc2828fa09 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -158,7 +158,11 @@ DEFINE_EVENT(timer_class, timer_cancel, { HRTIMER_MODE_ABS_SOFT, "ABS|SOFT" }, \ { HRTIMER_MODE_REL_SOFT, "REL|SOFT" }, \ { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" }, \ - { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }) + { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" }, \ + { HRTIMER_MODE_ABS_HARD, "ABS|HARD" }, \ + { HRTIMER_MODE_REL_HARD, "REL|HARD" }, \ + { HRTIMER_MODE_ABS_PINNED_HARD, "ABS|PINNED|HARD" }, \ + { HRTIMER_MODE_REL_PINNED_HARD, "REL|PINNED|HARD" }) /** * hrtimer_init - called when the hrtimer is initialized diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 86b2a82da546..54e353c9f919 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h @@ -68,7 +68,7 @@ DECLARE_EVENT_CLASS(writeback_folio_template, strscpy_pad(__entry->name, bdi_dev_name(mapping ? inode_to_bdi(mapping->host) : NULL), 32); - __entry->ino = mapping ? mapping->host->i_ino : 0; + __entry->ino = (mapping && mapping->host) ? mapping->host->i_ino : 0; __entry->index = folio->index; ), diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 638230899e98..8ce8a39a1e5f 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -132,6 +132,9 @@ #define SO_RCVMARK 75 +#define SO_PASSPIDFD 76 +#define SO_PEERPIDFD 77 + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index 45fa180cc56a..cd639fae9086 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -886,8 +886,11 @@ __SYSCALL(__NR_futex_waitv, sys_futex_waitv) #define __NR_set_mempolicy_home_node 450 __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) +#define __NR_cachestat 451 +__SYSCALL(__NR_cachestat, sys_cachestat) + #undef __NR_syscalls -#define __NR_syscalls 451 +#define __NR_syscalls 452 /* * 32 bit systems traditionally used different diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index b6eb90df5d05..79b14828d542 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -245,6 +245,8 @@ union drm_amdgpu_bo_list { /* indicate some errors are detected by RAS */ #define AMDGPU_CTX_QUERY2_FLAGS_RAS_CE (1<<3) #define AMDGPU_CTX_QUERY2_FLAGS_RAS_UE (1<<4) +/* indicate that the reset hasn't completed yet */ +#define AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS (1<<5) /* Context priority level */ #define AMDGPU_CTX_PRIORITY_UNSET -2048 @@ -592,6 +594,7 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07 #define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08 #define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09 +#define AMDGPU_CHUNK_ID_CP_GFX_SHADOW 0x0a struct drm_amdgpu_cs_chunk { __u32 chunk_id; @@ -708,6 +711,15 @@ struct drm_amdgpu_cs_chunk_data { }; }; +#define AMDGPU_CS_CHUNK_CP_GFX_SHADOW_FLAGS_INIT_SHADOW 0x1 + +struct drm_amdgpu_cs_chunk_cp_gfx_shadow { + __u64 shadow_va; + __u64 csa_va; + __u64 gds_va; + __u64 flags; +}; + /* * Query h/w info: Flag that this is integrated (a.h.a. fusion) GPU * @@ -876,6 +888,8 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_VIDEO_CAPS_DECODE 0 /* Subquery id: Encode */ #define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1 +/* Query the max number of IBs per gang per submission */ +#define AMDGPU_INFO_MAX_IBS 0x22 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff @@ -1126,6 +1140,14 @@ struct drm_amdgpu_info_device { __u64 mall_size; /* AKA infinity cache */ /* high 32 bits of the rb pipes mask */ __u32 enabled_rb_pipes_mask_hi; + /* shadow area size for gfx11 */ + __u32 shadow_size; + /* shadow area base virtual alignment for gfx11 */ + __u32 shadow_alignment; + /* context save area size for gfx11 */ + __u32 csa_size; + /* context save area base virtual alignment for gfx11 */ + __u32 csa_alignment; }; struct drm_amdgpu_info_hw_ip { diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index de703c6be969..8db7fd3f743e 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -658,6 +658,49 @@ extern "C" { #define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC fourcc_mod_code(INTEL, 12) /* + * Intel Color Control Surfaces (CCS) for display ver. 14 render compression. + * + * The main surface is tile4 and at plane index 0, the CCS is linear and + * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in + * main surface. In other words, 4 bits in CCS map to a main surface cache + * line pair. The main surface pitch is required to be a multiple of four + * tile4 widths. + */ +#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13) + +/* + * Intel Color Control Surfaces (CCS) for display ver. 14 media compression + * + * The main surface is tile4 and at plane index 0, the CCS is linear and + * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in + * main surface. In other words, 4 bits in CCS map to a main surface cache + * line pair. The main surface pitch is required to be a multiple of four + * tile4 widths. For semi-planar formats like NV12, CCS planes follow the + * Y and UV planes i.e., planes 0 and 1 are used for Y and UV surfaces, + * planes 2 and 3 for the respective CCS. + */ +#define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14) + +/* + * Intel Color Control Surface with Clear Color (CCS) for display ver. 14 render + * compression. + * + * The main surface is tile4 and is at plane index 0 whereas CCS is linear + * and at index 1. The clear color is stored at index 2, and the pitch should + * be ignored. The clear color structure is 256 bits. The first 128 bits + * represents Raw Clear Color Red, Green, Blue and Alpha color each represented + * by 32 bits. The raw clear color is consumed by the 3d engine and generates + * the converted clear color of size 64 bits. The first 32 bits store the Lower + * Converted Clear Color value and the next 32 bits store the Higher Converted + * Clear Color value when applicable. The Converted Clear Color values are + * consumed by the DE. The last 64 bits are used to store Color Discard Enable + * and Depth Clear Value Valid which are ignored by the DE. A CCS cache line + * corresponds to an area of 4x1 tiles in the main surface. The main surface + * pitch is required to be a multiple of 4 tile widths. + */ +#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) + +/* * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks * * Macroblocks are laid in a Z-shape, and each pixel data is following the diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 46becedf5b2f..43691058d28f 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -834,6 +834,11 @@ struct drm_color_ctm { /* * Conversion matrix in S31.32 sign-magnitude * (not two's complement!) format. + * + * out matrix in + * |R| |0 1 2| |R| + * |G| = |3 4 5| x |G| + * |B| |6 7 8| |B| */ __u64 matrix[9]; }; diff --git a/include/uapi/drm/habanalabs_accel.h b/include/uapi/drm/habanalabs_accel.h index d9ef1b151d04..e6436f3e8ea6 100644 --- a/include/uapi/drm/habanalabs_accel.h +++ b/include/uapi/drm/habanalabs_accel.h @@ -787,18 +787,28 @@ enum hl_server_type { * The address which accessing it caused the razwi. * Razwi initiator. * Razwi cause, was it a page fault or MMU access error. + * May return 0 even though no new data is available, in that case + * timestamp will be 0. * HL_INFO_DEV_MEM_ALLOC_PAGE_SIZES - Retrieve valid page sizes for device memory allocation * HL_INFO_SECURED_ATTESTATION - Retrieve attestation report of the boot. * HL_INFO_REGISTER_EVENTFD - Register eventfd for event notifications. * HL_INFO_UNREGISTER_EVENTFD - Unregister eventfd * HL_INFO_GET_EVENTS - Retrieve the last occurred events * HL_INFO_UNDEFINED_OPCODE_EVENT - Retrieve last undefined opcode error information. + * May return 0 even though no new data is available, in that case + * timestamp will be 0. * HL_INFO_ENGINE_STATUS - Retrieve the status of all the h/w engines in the asic. * HL_INFO_PAGE_FAULT_EVENT - Retrieve parameters of captured page fault. + * May return 0 even though no new data is available, in that case + * timestamp will be 0. * HL_INFO_USER_MAPPINGS - Retrieve user mappings, captured after page fault event. * HL_INFO_FW_GENERIC_REQ - Send generic request to FW. * HL_INFO_HW_ERR_EVENT - Retrieve information on the reported HW error. + * May return 0 even though no new data is available, in that case + * timestamp will be 0. * HL_INFO_FW_ERR_EVENT - Retrieve information on the reported FW error. + * May return 0 even though no new data is available, in that case + * timestamp will be 0. */ #define HL_INFO_HW_IP_INFO 0 #define HL_INFO_HW_EVENTS 1 diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index dba7c5a5b25e..7000e5910a1d 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -280,7 +280,16 @@ enum drm_i915_pmu_engine_sample { #define I915_PMU_ENGINE_SEMA(class, instance) \ __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA) -#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x)) +/* + * Top 4 bits of every non-engine counter are GT id. + */ +#define __I915_PMU_GT_SHIFT (60) + +#define ___I915_PMU_OTHER(gt, x) \ + (((__u64)__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x)) | \ + ((__u64)(gt) << __I915_PMU_GT_SHIFT)) + +#define __I915_PMU_OTHER(x) ___I915_PMU_OTHER(0, x) #define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0) #define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1) @@ -290,6 +299,12 @@ enum drm_i915_pmu_engine_sample { #define I915_PMU_LAST /* Deprecated - do not use */ I915_PMU_RC6_RESIDENCY +#define __I915_PMU_ACTUAL_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 0) +#define __I915_PMU_REQUESTED_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 1) +#define __I915_PMU_INTERRUPTS(gt) ___I915_PMU_OTHER(gt, 2) +#define __I915_PMU_RC6_RESIDENCY(gt) ___I915_PMU_OTHER(gt, 3) +#define __I915_PMU_SOFTWARE_GT_AWAKE_TIME(gt) ___I915_PMU_OTHER(gt, 4) + /* Each region is a minimum of 16k, and there are at most 255 of them. */ #define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use @@ -659,7 +674,8 @@ typedef struct drm_i915_irq_wait { * If the IOCTL is successful, the returned parameter will be set to one of the * following values: * * 0 if HuC firmware load is not complete, - * * 1 if HuC firmware is authenticated and running. + * * 1 if HuC firmware is loaded and fully authenticated, + * * 2 if HuC firmware is loaded and authenticated for clear media only */ #define I915_PARAM_HUC_STATUS 42 @@ -771,6 +787,25 @@ typedef struct drm_i915_irq_wait { */ #define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57 +/* + * Query the status of PXP support in i915. + * + * The query can fail in the following scenarios with the listed error codes: + * -ENODEV = PXP support is not available on the GPU device or in the + * kernel due to missing component drivers or kernel configs. + * + * If the IOCTL is successful, the returned parameter will be set to one of + * the following values: + * 1 = PXP feature is supported and is ready for use. + * 2 = PXP feature is supported but should be ready soon (pending + * initialization of non-i915 system dependencies). + * + * NOTE: When param is supported (positive return values), user space should + * still refer to the GEM PXP context-creation UAPI header specs to be + * aware of possible failure due to system state machine at the time. + */ +#define I915_PARAM_PXP_STATUS 58 + /* Must be kept compact -- no holes and well documented */ /** @@ -2096,6 +2131,21 @@ struct drm_i915_gem_context_param { * * -ENODEV: feature not available * -EPERM: trying to mark a recoverable or not bannable context as protected + * -ENXIO: A dependency such as a component driver or firmware is not yet + * loaded so user space may need to attempt again. Depending on the + * device, this error may be reported if protected context creation is + * attempted very early after kernel start because the internal timeout + * waiting for such dependencies is not guaranteed to be larger than + * required (numbers differ depending on system and kernel config): + * - ADL/RPL: dependencies may take up to 3 seconds from kernel start + * while context creation internal timeout is 250 milisecs + * - MTL: dependencies may take up to 8 seconds from kernel start + * while context creation internal timeout is 250 milisecs + * NOTE: such dependencies happen once, so a subsequent call to create a + * protected context after a prior successful call will not experience + * such timeouts and will not return -ENXIO (unless the driver is reloaded, + * or, depending on the device, resumes from a suspended state). + * -EIO: The firmware did not succeed in creating the protected context. */ #define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd /* Must be kept compact -- no holes and well documented */ @@ -3630,9 +3680,13 @@ struct drm_i915_gem_create_ext { * * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see * struct drm_i915_gem_create_ext_protected_content. + * + * For I915_GEM_CREATE_EXT_SET_PAT usage see + * struct drm_i915_gem_create_ext_set_pat. */ #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0 #define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1 +#define I915_GEM_CREATE_EXT_SET_PAT 2 __u64 extensions; }; @@ -3747,6 +3801,43 @@ struct drm_i915_gem_create_ext_protected_content { __u32 flags; }; +/** + * struct drm_i915_gem_create_ext_set_pat - The + * I915_GEM_CREATE_EXT_SET_PAT extension. + * + * If this extension is provided, the specified caching policy (PAT index) is + * applied to the buffer object. + * + * Below is an example on how to create an object with specific caching policy: + * + * .. code-block:: C + * + * struct drm_i915_gem_create_ext_set_pat set_pat_ext = { + * .base = { .name = I915_GEM_CREATE_EXT_SET_PAT }, + * .pat_index = 0, + * }; + * struct drm_i915_gem_create_ext create_ext = { + * .size = PAGE_SIZE, + * .extensions = (uintptr_t)&set_pat_ext, + * }; + * + * int err = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext); + * if (err) ... + */ +struct drm_i915_gem_create_ext_set_pat { + /** @base: Extension link. See struct i915_user_extension. */ + struct i915_user_extension base; + /** + * @pat_index: PAT index to be set + * PAT index is a bit field in Page Table Entry to control caching + * behaviors for GPU accesses. The definition of PAT index is + * platform dependent and can be found in hardware specifications, + */ + __u32 pat_index; + /** @rsvd: reserved for future use */ + __u32 rsvd; +}; + /* ID of the protected content session managed by i915 when PXP is active */ #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf diff --git a/include/uapi/linux/affs_hardblocks.h b/include/uapi/linux/affs_hardblocks.h index 5e2fb8481252..a5aff2eb5f70 100644 --- a/include/uapi/linux/affs_hardblocks.h +++ b/include/uapi/linux/affs_hardblocks.h @@ -7,42 +7,42 @@ /* Just the needed definitions for the RDB of an Amiga HD. */ struct RigidDiskBlock { - __u32 rdb_ID; + __be32 rdb_ID; __be32 rdb_SummedLongs; - __s32 rdb_ChkSum; - __u32 rdb_HostID; + __be32 rdb_ChkSum; + __be32 rdb_HostID; __be32 rdb_BlockBytes; - __u32 rdb_Flags; - __u32 rdb_BadBlockList; + __be32 rdb_Flags; + __be32 rdb_BadBlockList; __be32 rdb_PartitionList; - __u32 rdb_FileSysHeaderList; - __u32 rdb_DriveInit; - __u32 rdb_Reserved1[6]; - __u32 rdb_Cylinders; - __u32 rdb_Sectors; - __u32 rdb_Heads; - __u32 rdb_Interleave; - __u32 rdb_Park; - __u32 rdb_Reserved2[3]; - __u32 rdb_WritePreComp; - __u32 rdb_ReducedWrite; - __u32 rdb_StepRate; - __u32 rdb_Reserved3[5]; - __u32 rdb_RDBBlocksLo; - __u32 rdb_RDBBlocksHi; - __u32 rdb_LoCylinder; - __u32 rdb_HiCylinder; - __u32 rdb_CylBlocks; - __u32 rdb_AutoParkSeconds; - __u32 rdb_HighRDSKBlock; - __u32 rdb_Reserved4; + __be32 rdb_FileSysHeaderList; + __be32 rdb_DriveInit; + __be32 rdb_Reserved1[6]; + __be32 rdb_Cylinders; + __be32 rdb_Sectors; + __be32 rdb_Heads; + __be32 rdb_Interleave; + __be32 rdb_Park; + __be32 rdb_Reserved2[3]; + __be32 rdb_WritePreComp; + __be32 rdb_ReducedWrite; + __be32 rdb_StepRate; + __be32 rdb_Reserved3[5]; + __be32 rdb_RDBBlocksLo; + __be32 rdb_RDBBlocksHi; + __be32 rdb_LoCylinder; + __be32 rdb_HiCylinder; + __be32 rdb_CylBlocks; + __be32 rdb_AutoParkSeconds; + __be32 rdb_HighRDSKBlock; + __be32 rdb_Reserved4; char rdb_DiskVendor[8]; char rdb_DiskProduct[16]; char rdb_DiskRevision[4]; char rdb_ControllerVendor[8]; char rdb_ControllerProduct[16]; char rdb_ControllerRevision[4]; - __u32 rdb_Reserved5[10]; + __be32 rdb_Reserved5[10]; }; #define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ @@ -50,16 +50,16 @@ struct RigidDiskBlock { struct PartitionBlock { __be32 pb_ID; __be32 pb_SummedLongs; - __s32 pb_ChkSum; - __u32 pb_HostID; + __be32 pb_ChkSum; + __be32 pb_HostID; __be32 pb_Next; - __u32 pb_Flags; - __u32 pb_Reserved1[2]; - __u32 pb_DevFlags; + __be32 pb_Flags; + __be32 pb_Reserved1[2]; + __be32 pb_DevFlags; __u8 pb_DriveName[32]; - __u32 pb_Reserved2[15]; + __be32 pb_Reserved2[15]; __be32 pb_Environment[17]; - __u32 pb_EReserved[15]; + __be32 pb_EReserved[15]; }; #define IDNAME_PARTITION 0x50415254 /* "PART" */ diff --git a/include/uapi/linux/auto_dev-ioctl.h b/include/uapi/linux/auto_dev-ioctl.h index 62e625356dc8..08be539605fc 100644 --- a/include/uapi/linux/auto_dev-ioctl.h +++ b/include/uapi/linux/auto_dev-ioctl.h @@ -109,7 +109,7 @@ struct autofs_dev_ioctl { struct args_ismountpoint ismountpoint; }; - char path[0]; + char path[]; }; static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 1bb11a6ee667..60a9d59beeab 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1035,6 +1035,7 @@ enum bpf_attach_type { BPF_TRACE_KPROBE_MULTI, BPF_LSM_CGROUP, BPF_STRUCT_OPS, + BPF_NETFILTER, __MAX_BPF_ATTACH_TYPE }; @@ -1272,6 +1273,9 @@ enum { /* Create a map that will be registered/unregesitered by the backed bpf_link */ BPF_F_LINK = (1U << 13), + +/* Get path from provided FD in BPF_OBJ_PIN/BPF_OBJ_GET commands */ + BPF_F_PATH_FD = (1U << 14), }; /* Flags for BPF_PROG_QUERY. */ @@ -1420,6 +1424,13 @@ union bpf_attr { __aligned_u64 pathname; __u32 bpf_fd; __u32 file_flags; + /* Same as dirfd in openat() syscall; see openat(2) + * manpage for details of path FD and pathname semantics; + * path_fd should accompanied by BPF_F_PATH_FD flag set in + * file_flags field, otherwise it should be set to zero; + * if BPF_F_PATH_FD flag is not set, AT_FDCWD is assumed. + */ + __s32 path_fd; }; struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */ @@ -3167,6 +3178,10 @@ union bpf_attr { * **BPF_FIB_LOOKUP_DIRECT** * Do a direct table lookup vs full lookup using FIB * rules. + * **BPF_FIB_LOOKUP_TBID** + * Used with BPF_FIB_LOOKUP_DIRECT. + * Use the routing table ID present in *params*->tbid + * for the fib lookup. * **BPF_FIB_LOOKUP_OUTPUT** * Perform lookup from an egress perspective (default is * ingress). @@ -6821,6 +6836,7 @@ enum { BPF_FIB_LOOKUP_DIRECT = (1U << 0), BPF_FIB_LOOKUP_OUTPUT = (1U << 1), BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), + BPF_FIB_LOOKUP_TBID = (1U << 3), }; enum { @@ -6881,9 +6897,19 @@ struct bpf_fib_lookup { __u32 ipv6_dst[4]; /* in6_addr; network order */ }; - /* output */ - __be16 h_vlan_proto; - __be16 h_vlan_TCI; + union { + struct { + /* output */ + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + }; + /* input: when accompanied with the + * 'BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID` flags, a + * specific routing table to use for the fib lookup. + */ + __u32 tbid; + }; + __u8 smac[6]; /* ETH_ALEN */ __u8 dmac[6]; /* ETH_ALEN */ }; diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h index dd645ea72306..939db2388208 100644 --- a/include/uapi/linux/can.h +++ b/include/uapi/linux/can.h @@ -285,6 +285,5 @@ struct can_filter { }; #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */ -#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */ #endif /* !_UAPI_CAN_H */ diff --git a/include/uapi/linux/can/raw.h b/include/uapi/linux/can/raw.h index ff12f525c37c..31622c9b7988 100644 --- a/include/uapi/linux/can/raw.h +++ b/include/uapi/linux/can/raw.h @@ -49,6 +49,8 @@ #include <linux/can.h> #define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW) +#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */ + enum { SCM_CAN_RAW_ERRQUEUE = 1, }; diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h index 3d61a0ae055d..5bb906098697 100644 --- a/include/uapi/linux/capability.h +++ b/include/uapi/linux/capability.h @@ -41,11 +41,12 @@ typedef struct __user_cap_header_struct { int pid; } __user *cap_user_header_t; -typedef struct __user_cap_data_struct { +struct __user_cap_data_struct { __u32 effective; __u32 permitted; __u32 inheritable; -} __user *cap_user_data_t; +}; +typedef struct __user_cap_data_struct __user *cap_user_data_t; #define VFS_CAP_REVISION_MASK 0xFF000000 diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h index 8ab12d731e3b..fc248ef00e86 100644 --- a/include/uapi/linux/counter.h +++ b/include/uapi/linux/counter.h @@ -127,6 +127,12 @@ enum counter_count_mode { COUNTER_COUNT_MODE_RANGE_LIMIT, COUNTER_COUNT_MODE_NON_RECYCLE, COUNTER_COUNT_MODE_MODULO_N, + COUNTER_COUNT_MODE_INTERRUPT_ON_TERMINAL_COUNT, + COUNTER_COUNT_MODE_HARDWARE_RETRIGGERABLE_ONESHOT, + COUNTER_COUNT_MODE_RATE_GENERATOR, + COUNTER_COUNT_MODE_SQUARE_WAVE_MODE, + COUNTER_COUNT_MODE_SOFTWARE_TRIGGERED_STROBE, + COUNTER_COUNT_MODE_HARDWARE_TRIGGERED_STROBE, }; /* Count function values */ diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 326f6a53f1f2..7e0983b987c2 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -296,6 +296,10 @@ enum fe_spectral_inversion { * @FEC_28_45: Forward Error Correction Code 28/45 * @FEC_32_45: Forward Error Correction Code 32/45 * @FEC_77_90: Forward Error Correction Code 77/90 + * @FEC_11_45: Forward Error Correction Code 11/45 + * @FEC_4_15: Forward Error Correction Code 4/15 + * @FEC_14_45: Forward Error Correction Code 14/45 + * @FEC_7_15: Forward Error Correction Code 7/15 * * Please note that not all FEC types are supported by a given standard. */ @@ -329,6 +333,10 @@ enum fe_code_rate { FEC_28_45, FEC_32_45, FEC_77_90, + FEC_11_45, + FEC_4_15, + FEC_14_45, + FEC_7_15, }; /** diff --git a/include/uapi/linux/dvb/version.h b/include/uapi/linux/dvb/version.h index 1a8cd038aa0b..20bc874de321 100644 --- a/include/uapi/linux/dvb/version.h +++ b/include/uapi/linux/dvb/version.h @@ -10,6 +10,6 @@ #define _DVBVERSION_H_ #define DVB_API_VERSION 5 -#define DVB_API_VERSION_MINOR 11 +#define DVB_API_VERSION_MINOR 12 #endif /*_DVBVERSION_H_*/ diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index ac3da855fb19..0c8cf359ea5b 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -372,7 +372,8 @@ typedef struct elf64_shdr { * Notes used in ET_CORE. Architectures export some of the arch register sets * using the corresponding note types via the PTRACE_GETREGSET and * PTRACE_SETREGSET requests. - * The note name for all these is "LINUX". + * The note name for these types is "LINUX", except NT_PRFPREG that is named + * "CORE". */ #define NT_PRSTATUS 1 #define NT_PRFPREG 2 @@ -403,6 +404,8 @@ typedef struct elf64_shdr { #define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */ #define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */ #define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */ +#define NT_PPC_DEXCR 0x111 /* PowerPC DEXCR registers */ +#define NT_PPC_HASHKEYR 0x112 /* PowerPC HASHKEYR register */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ @@ -440,6 +443,7 @@ typedef struct elf64_shdr { #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ #define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode */ #define NT_MIPS_MSA 0x802 /* MIPS SIMD registers */ +#define NT_RISCV_VECTOR 0x900 /* RISC-V vector registers */ #define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers */ #define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and status registers */ #define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD Extension registers */ diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 1ebf8d455f07..73e2c10dc2cc 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -783,7 +783,7 @@ enum { /* add new constants above here */ __ETHTOOL_A_STATS_GRP_CNT, - ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1) + ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1) }; enum { diff --git a/include/uapi/linux/eventfd.h b/include/uapi/linux/eventfd.h new file mode 100644 index 000000000000..2eb9ab6c32f3 --- /dev/null +++ b/include/uapi/linux/eventfd.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_EVENTFD_H +#define _UAPI_LINUX_EVENTFD_H + +#include <linux/fcntl.h> + +#define EFD_SEMAPHORE (1 << 0) +#define EFD_CLOEXEC O_CLOEXEC +#define EFD_NONBLOCK O_NONBLOCK + +#endif /* _UAPI_LINUX_EVENTFD_H */ diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index e8c07da58c9f..6c80f96049bd 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -112,4 +112,9 @@ #define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ +/* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits... */ +#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to + compare object identity and may not + be usable to open_by_handle_at(2) */ + #endif /* _UAPI_LINUX_FCNTL_H */ diff --git a/include/uapi/linux/firewire-cdev.h b/include/uapi/linux/firewire-cdev.h index 92be3ea3c6e0..1f2c9469f921 100644 --- a/include/uapi/linux/firewire-cdev.h +++ b/include/uapi/linux/firewire-cdev.h @@ -46,6 +46,12 @@ #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08 #define FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL 0x09 +/* available since kernel version 6.5 */ +#define FW_CDEV_EVENT_REQUEST3 0x0a +#define FW_CDEV_EVENT_RESPONSE2 0x0b +#define FW_CDEV_EVENT_PHY_PACKET_SENT2 0x0c +#define FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 0x0d + /** * struct fw_cdev_event_common - Common part of all fw_cdev_event_* types * @closure: For arbitrary use by userspace @@ -103,6 +109,32 @@ struct fw_cdev_event_bus_reset { * @length: Data length, i.e. the response's payload size in bytes * @data: Payload data, if any * + * This event is sent instead of &fw_cdev_event_response if the kernel or the client implements + * ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_response2. + */ +struct fw_cdev_event_response { + __u64 closure; + __u32 type; + __u32 rcode; + __u32 length; + __u32 data[]; +}; + +/** + * struct fw_cdev_event_response2 - Sent when a response packet was received + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_SEND_REQUEST + * or %FW_CDEV_IOC_SEND_BROADCAST_REQUEST + * or %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE + * @rcode: Response code returned by the remote node + * @length: Data length, i.e. the response's payload size in bytes + * @request_tstamp: The time stamp of isochronous cycle at which the request was sent. + * @response_tstamp: The time stamp of isochronous cycle at which the response was sent. + * @padding: Padding to keep the size of structure as multiples of 8 in various architectures + * since 4 byte alignment is used for 8 byte of object type in System V ABI for i386 + * architecture. + * @data: Payload data, if any + * * This event is sent when the stack receives a response to an outgoing request * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses * carrying data (read and lock responses) follows immediately and can be @@ -112,12 +144,21 @@ struct fw_cdev_event_bus_reset { * involve response packets. This includes unified write transactions, * broadcast write transactions, and transmission of asynchronous stream * packets. @rcode indicates success or failure of such transmissions. + * + * The value of @request_tstamp expresses the isochronous cycle at which the request was sent to + * initiate the transaction. The value of @response_tstamp expresses the isochronous cycle at which + * the response arrived to complete the transaction. Each value is unsigned 16 bit integer + * containing three low order bits of second field and all 13 bits of cycle field in format of + * CYCLE_TIMER register. */ -struct fw_cdev_event_response { +struct fw_cdev_event_response2 { __u64 closure; __u32 type; __u32 rcode; __u32 length; + __u32 request_tstamp; + __u32 response_tstamp; + __u32 padding; __u32 data[]; }; @@ -159,6 +200,41 @@ struct fw_cdev_event_request { * @length: Data length, i.e. the request's payload size in bytes * @data: Incoming data, if any * + * This event is sent instead of &fw_cdev_event_request3 if the kernel or the client implements + * ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_request3. + */ +struct fw_cdev_event_request2 { + __u64 closure; + __u32 type; + __u32 tcode; + __u64 offset; + __u32 source_node_id; + __u32 destination_node_id; + __u32 card; + __u32 generation; + __u32 handle; + __u32 length; + __u32 data[]; +}; + +/** + * struct fw_cdev_event_request3 - Sent on incoming request to an address region + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST2 + * @tcode: Transaction code of the incoming request + * @offset: The offset into the 48-bit per-node address space + * @source_node_id: Sender node ID + * @destination_node_id: Destination node ID + * @card: The index of the card from which the request came + * @generation: Bus generation in which the request is valid + * @handle: Reference to the kernel-side pending request + * @length: Data length, i.e. the request's payload size in bytes + * @tstamp: The time stamp of isochronous cycle at which the request arrived. + * @padding: Padding to keep the size of structure as multiples of 8 in various architectures + * since 4 byte alignment is used for 8 byte of object type in System V ABI for i386 + * architecture. + * @data: Incoming data, if any + * * This event is sent when the stack receives an incoming request to an address * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is * guaranteed to be completely contained in the specified region. Userspace is @@ -191,10 +267,14 @@ struct fw_cdev_event_request { * sent. * * If the client subsequently needs to initiate requests to the sender node of - * an &fw_cdev_event_request2, it needs to use a device file with matching + * an &fw_cdev_event_request3, it needs to use a device file with matching * card index, node ID, and generation for outbound requests. + * + * @tstamp is isochronous cycle at which the request arrived. It is 16 bit integer value and the + * higher 3 bits expresses three low order bits of second field in the format of CYCLE_TIME + * register and the rest 13 bits expresses cycle field. */ -struct fw_cdev_event_request2 { +struct fw_cdev_event_request3 { __u64 closure; __u32 type; __u32 tcode; @@ -205,6 +285,8 @@ struct fw_cdev_event_request2 { __u32 generation; __u32 handle; __u32 length; + __u32 tstamp; + __u32 padding; __u32 data[]; }; @@ -341,20 +423,59 @@ struct fw_cdev_event_iso_resource { * @type: %FW_CDEV_EVENT_PHY_PACKET_SENT or %..._RECEIVED * @rcode: %RCODE_..., indicates success or failure of transmission * @length: Data length in bytes + * @data: Incoming data for %FW_CDEV_IOC_RECEIVE_PHY_PACKETS. For %FW_CDEV_IOC_SEND_PHY_PACKET + * the field has the same data in the request, thus the length of 8 bytes. + * + * This event is sent instead of &fw_cdev_event_phy_packet2 if the kernel or + * the client implements ABI version <= 5. It has the lack of time stamp field comparing to + * &fw_cdev_event_phy_packet2. + */ +struct fw_cdev_event_phy_packet { + __u64 closure; + __u32 type; + __u32 rcode; + __u32 length; + __u32 data[]; +}; + +/** + * struct fw_cdev_event_phy_packet2 - A PHY packet was transmitted or received with time stamp. + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_SEND_PHY_PACKET + * or %FW_CDEV_IOC_RECEIVE_PHY_PACKETS ioctl + * @type: %FW_CDEV_EVENT_PHY_PACKET_SENT2 or %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 + * @rcode: %RCODE_..., indicates success or failure of transmission + * @length: Data length in bytes + * @tstamp: For %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, the time stamp of isochronous cycle at + * which the packet arrived. For %FW_CDEV_EVENT_PHY_PACKET_SENT2 and non-ping packet, + * the time stamp of isochronous cycle at which the packet was sent. For ping packet, + * the tick count for round-trip time measured by 1394 OHCI controller. + * The time stamp of isochronous cycle at which either the response was sent for + * %FW_CDEV_EVENT_PHY_PACKET_SENT2 or the request arrived for + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2. * @data: Incoming data * - * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty, - * except in case of a ping packet: Then, @length is 4, and @data[0] is the - * ping time in 49.152MHz clocks if @rcode is %RCODE_COMPLETE. + * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT2, @length is 8 and @data consists of the two PHY + * packet quadlets to be sent, in host byte order, * - * If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED, @length is 8 and @data - * consists of the two PHY packet quadlets, in host byte order. + * If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, @length is 8 and @data consists of the two PHY + * packet quadlets, in host byte order. + * + * For %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, the @tstamp is the isochronous cycle at which the + * packet arrived. It is 16 bit integer value and the higher 3 bits expresses three low order bits + * of second field and the rest 13 bits expresses cycle field in the format of CYCLE_TIME register. + * + * For %FW_CDEV_EVENT_PHY_PACKET_SENT2, the @tstamp has different meanings whether to sent the + * packet for ping or not. If it's not for ping, the @tstamp is the isochronous cycle at which the + * packet was sent, and use the same format as the case of %FW_CDEV_EVENT_PHY_PACKET_SENT2. If it's + * for ping, the @tstamp is for round-trip time measured by 1394 OHCI controller with 42.195 MHz + * resolution. */ -struct fw_cdev_event_phy_packet { +struct fw_cdev_event_phy_packet2 { __u64 closure; __u32 type; __u32 rcode; __u32 length; + __u32 tstamp; __u32 data[]; }; @@ -375,6 +496,11 @@ struct fw_cdev_event_phy_packet { * %FW_CDEV_EVENT_PHY_PACKET_SENT or * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED * + * @request3: Valid if @common.type == %FW_CDEV_EVENT_REQUEST3 + * @response2: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE2 + * @phy_packet2: Valid if @common.type == %FW_CDEV_EVENT_PHY_PACKET_SENT2 or + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 + * * Convenience union for userspace use. Events could be read(2) into an * appropriately aligned char buffer and then cast to this union for further * processing. Note that for a request, response or iso_interrupt event, @@ -393,6 +519,9 @@ union fw_cdev_event { struct fw_cdev_event_iso_interrupt_mc iso_interrupt_mc; /* added in 2.6.36 */ struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */ struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */ + struct fw_cdev_event_request3 request3; /* added in 6.5 */ + struct fw_cdev_event_response2 response2; /* added in 6.5 */ + struct fw_cdev_event_phy_packet2 phy_packet2; /* added in 6.5 */ }; /* available since kernel version 2.6.22 */ @@ -457,6 +586,11 @@ union fw_cdev_event { * 5 (3.4) - send %FW_CDEV_EVENT_ISO_INTERRUPT events when needed to * avoid dropping data * - added %FW_CDEV_IOC_FLUSH_ISO + * 6 (6.5) - added some event for subactions of asynchronous transaction with time stamp + * - %FW_CDEV_EVENT_REQUEST3 + * - %FW_CDEV_EVENT_RESPONSE2 + * - %FW_CDEV_EVENT_PHY_PACKET_SENT2 + * - %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 */ /** @@ -502,11 +636,11 @@ struct fw_cdev_get_info { * @data: Userspace pointer to payload * @generation: The bus generation where packet is valid * - * Send a request to the device. This ioctl implements all outgoing requests. - * Both quadlet and block request specify the payload as a pointer to the data - * in the @data field. Once the transaction completes, the kernel writes an - * &fw_cdev_event_response event back. The @closure field is passed back to - * user space in the response event. + * Send a request to the device. This ioctl implements all outgoing requests. Both quadlet and + * block request specify the payload as a pointer to the data in the @data field. Once the + * transaction completes, the kernel writes either &fw_cdev_event_response event or + * &fw_cdev_event_response event back. The @closure field is passed back to user space in the + * response event. */ struct fw_cdev_send_request { __u32 tcode; @@ -989,10 +1123,9 @@ struct fw_cdev_allocate_iso_resource { * @generation: The bus generation where packet is valid * @speed: Speed to transmit at * - * The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet - * to every device which is listening to the specified channel. The kernel - * writes an &fw_cdev_event_response event which indicates success or failure of - * the transmission. + * The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet to every device + * which is listening to the specified channel. The kernel writes either &fw_cdev_event_response + * event or &fw_cdev_event_response2 event which indicates success or failure of the transmission. */ struct fw_cdev_send_stream_packet { __u32 length; @@ -1011,8 +1144,8 @@ struct fw_cdev_send_stream_packet { * @data: First and second quadlet of the PHY packet * @generation: The bus generation where packet is valid * - * The %FW_CDEV_IOC_SEND_PHY_PACKET ioctl sends a PHY packet to all nodes - * on the same card as this device. After transmission, an + * The %FW_CDEV_IOC_SEND_PHY_PACKET ioctl sends a PHY packet to all nodes on the same card as this + * device. After transmission, either %FW_CDEV_EVENT_PHY_PACKET_SENT event or * %FW_CDEV_EVENT_PHY_PACKET_SENT event is generated. * * The payload @data\[\] shall be specified in host byte order. Usually, @@ -1031,8 +1164,9 @@ struct fw_cdev_send_phy_packet { * struct fw_cdev_receive_phy_packets - start reception of PHY packets * @closure: Passed back to userspace in phy packet events * - * This ioctl activates issuing of %FW_CDEV_EVENT_PHY_PACKET_RECEIVED due to - * incoming PHY packets from any node on the same bus as the device. + * This ioctl activates issuing of either %FW_CDEV_EVENT_PHY_PACKET_RECEIVED or + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 due to incoming PHY packets from any node on the same bus + * as the device. * * The ioctl is only permitted on device files which represent a local node. */ diff --git a/include/uapi/linux/handshake.h b/include/uapi/linux/handshake.h index 1de4d0b95325..3d7ea58778c9 100644 --- a/include/uapi/linux/handshake.h +++ b/include/uapi/linux/handshake.h @@ -44,6 +44,7 @@ enum { HANDSHAKE_A_ACCEPT_AUTH_MODE, HANDSHAKE_A_ACCEPT_PEER_IDENTITY, HANDSHAKE_A_ACCEPT_CERTIFICATE, + HANDSHAKE_A_ACCEPT_PEERNAME, __HANDSHAKE_A_ACCEPT_MAX, HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 4ac1000b0ef2..0f6a0fe09bdb 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -828,6 +828,7 @@ enum { IFLA_VXLAN_TTL_INHERIT, IFLA_VXLAN_DF, IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */ + IFLA_VXLAN_LOCALBYPASS, __IFLA_VXLAN_MAX }; #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h index 4b7f2df66b99..e682ab628dfa 100644 --- a/include/uapi/linux/in.h +++ b/include/uapi/linux/in.h @@ -163,6 +163,7 @@ struct in_addr { #define IP_MULTICAST_ALL 49 #define IP_UNICAST_IF 50 #define IP_LOCAL_PORT_RANGE 51 +#define IP_PROTOCOL 52 #define MCAST_EXCLUDE 0 #define MCAST_INCLUDE 1 diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 0716cb17e436..08720c7bd92f 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -173,6 +173,18 @@ enum { */ #define IORING_SETUP_DEFER_TASKRUN (1U << 13) +/* + * Application provides the memory for the rings + */ +#define IORING_SETUP_NO_MMAP (1U << 14) + +/* + * Register the ring fd in itself for use with + * IORING_REGISTER_USE_REGISTERED_RING; return a registered fd index rather + * than an fd. + */ +#define IORING_SETUP_REGISTERED_FD_ONLY (1U << 15) + enum io_uring_op { IORING_OP_NOP, IORING_OP_READV, @@ -232,8 +244,10 @@ enum io_uring_op { * sqe->uring_cmd_flags * IORING_URING_CMD_FIXED use registered buffer; pass this flag * along with setting sqe->buf_index. + * IORING_URING_CMD_POLLED driver use only */ #define IORING_URING_CMD_FIXED (1U << 0) +#define IORING_URING_CMD_POLLED (1U << 31) /* @@ -406,7 +420,7 @@ struct io_sqring_offsets { __u32 dropped; __u32 array; __u32 resv1; - __u64 resv2; + __u64 user_addr; }; /* @@ -425,7 +439,7 @@ struct io_cqring_offsets { __u32 cqes; __u32 flags; __u32 resv1; - __u64 resv2; + __u64 user_addr; }; /* diff --git a/include/uapi/linux/ioprio.h b/include/uapi/linux/ioprio.h index f70f2596a6bf..99440b2e8c35 100644 --- a/include/uapi/linux/ioprio.h +++ b/include/uapi/linux/ioprio.h @@ -2,22 +2,23 @@ #ifndef _UAPI_LINUX_IOPRIO_H #define _UAPI_LINUX_IOPRIO_H +#include <linux/stddef.h> +#include <linux/types.h> + /* * Gives us 8 prio classes with 13-bits of data for each class */ #define IOPRIO_CLASS_SHIFT 13 -#define IOPRIO_CLASS_MASK 0x07 +#define IOPRIO_NR_CLASSES 8 +#define IOPRIO_CLASS_MASK (IOPRIO_NR_CLASSES - 1) #define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1) #define IOPRIO_PRIO_CLASS(ioprio) \ (((ioprio) >> IOPRIO_CLASS_SHIFT) & IOPRIO_CLASS_MASK) #define IOPRIO_PRIO_DATA(ioprio) ((ioprio) & IOPRIO_PRIO_MASK) -#define IOPRIO_PRIO_VALUE(class, data) \ - ((((class) & IOPRIO_CLASS_MASK) << IOPRIO_CLASS_SHIFT) | \ - ((data) & IOPRIO_PRIO_MASK)) /* - * These are the io priority groups as implemented by the BFQ and mq-deadline + * These are the io priority classes as implemented by the BFQ and mq-deadline * schedulers. RT is the realtime class, it always gets premium service. For * ATA disks supporting NCQ IO priority, RT class IOs will be processed using * high priority NCQ commands. BE is the best-effort scheduling class, the @@ -25,18 +26,30 @@ * served when no one else is using the disk. */ enum { - IOPRIO_CLASS_NONE, - IOPRIO_CLASS_RT, - IOPRIO_CLASS_BE, - IOPRIO_CLASS_IDLE, + IOPRIO_CLASS_NONE = 0, + IOPRIO_CLASS_RT = 1, + IOPRIO_CLASS_BE = 2, + IOPRIO_CLASS_IDLE = 3, + + /* Special class to indicate an invalid ioprio value */ + IOPRIO_CLASS_INVALID = 7, }; /* - * The RT and BE priority classes both support up to 8 priority levels. + * The RT and BE priority classes both support up to 8 priority levels that + * can be specified using the lower 3-bits of the priority data. */ -#define IOPRIO_NR_LEVELS 8 -#define IOPRIO_BE_NR IOPRIO_NR_LEVELS +#define IOPRIO_LEVEL_NR_BITS 3 +#define IOPRIO_NR_LEVELS (1 << IOPRIO_LEVEL_NR_BITS) +#define IOPRIO_LEVEL_MASK (IOPRIO_NR_LEVELS - 1) +#define IOPRIO_PRIO_LEVEL(ioprio) ((ioprio) & IOPRIO_LEVEL_MASK) + +#define IOPRIO_BE_NR IOPRIO_NR_LEVELS +/* + * Possible values for the "which" argument of the ioprio_get() and + * ioprio_set() system calls (see "man ioprio_set"). + */ enum { IOPRIO_WHO_PROCESS = 1, IOPRIO_WHO_PGRP, @@ -44,9 +57,70 @@ enum { }; /* - * Fallback BE priority level. + * Fallback BE class priority level. */ #define IOPRIO_NORM 4 #define IOPRIO_BE_NORM IOPRIO_NORM +/* + * The 10 bits between the priority class and the priority level are used to + * optionally define I/O hints for any combination of I/O priority class and + * level. Depending on the kernel configuration, I/O scheduler being used and + * the target I/O device being used, hints can influence how I/Os are processed + * without affecting the I/O scheduling ordering defined by the I/O priority + * class and level. + */ +#define IOPRIO_HINT_SHIFT IOPRIO_LEVEL_NR_BITS +#define IOPRIO_HINT_NR_BITS 10 +#define IOPRIO_NR_HINTS (1 << IOPRIO_HINT_NR_BITS) +#define IOPRIO_HINT_MASK (IOPRIO_NR_HINTS - 1) +#define IOPRIO_PRIO_HINT(ioprio) \ + (((ioprio) >> IOPRIO_HINT_SHIFT) & IOPRIO_HINT_MASK) + +/* + * I/O hints. + */ +enum { + /* No hint */ + IOPRIO_HINT_NONE = 0, + + /* + * Device command duration limits: indicate to the device a desired + * duration limit for the commands that will be used to process an I/O. + * These will currently only be effective for SCSI and ATA devices that + * support the command duration limits feature. If this feature is + * enabled, then the commands issued to the device to process an I/O with + * one of these hints set will have the duration limit index (dld field) + * set to the value of the hint. + */ + IOPRIO_HINT_DEV_DURATION_LIMIT_1 = 1, + IOPRIO_HINT_DEV_DURATION_LIMIT_2 = 2, + IOPRIO_HINT_DEV_DURATION_LIMIT_3 = 3, + IOPRIO_HINT_DEV_DURATION_LIMIT_4 = 4, + IOPRIO_HINT_DEV_DURATION_LIMIT_5 = 5, + IOPRIO_HINT_DEV_DURATION_LIMIT_6 = 6, + IOPRIO_HINT_DEV_DURATION_LIMIT_7 = 7, +}; + +#define IOPRIO_BAD_VALUE(val, max) ((val) < 0 || (val) >= (max)) + +/* + * Return an I/O priority value based on a class, a level and a hint. + */ +static __always_inline __u16 ioprio_value(int class, int level, int hint) +{ + if (IOPRIO_BAD_VALUE(class, IOPRIO_NR_CLASSES) || + IOPRIO_BAD_VALUE(level, IOPRIO_NR_LEVELS) || + IOPRIO_BAD_VALUE(hint, IOPRIO_NR_HINTS)) + return IOPRIO_CLASS_INVALID << IOPRIO_CLASS_SHIFT; + + return (class << IOPRIO_CLASS_SHIFT) | + (hint << IOPRIO_HINT_SHIFT) | level; +} + +#define IOPRIO_PRIO_VALUE(class, level) \ + ioprio_value(class, level, IOPRIO_HINT_NONE) +#define IOPRIO_PRIO_VALUE_HINT(class, level, hint) \ + ioprio_value(class, level, hint) + #endif /* _UAPI_LINUX_IOPRIO_H */ diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 2da5c3ad71bd..eeb2fdcbdcb7 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -38,9 +38,11 @@ * - 1.10 - Add SMI profiler event log * - 1.11 - Add unified memory for ctx save/restore area * - 1.12 - Add DMA buf export ioctl + * - 1.13 - Add debugger API + * - 1.14 - Update kfd_event_data */ #define KFD_IOCTL_MAJOR_VERSION 1 -#define KFD_IOCTL_MINOR_VERSION 12 +#define KFD_IOCTL_MINOR_VERSION 14 struct kfd_ioctl_get_version_args { __u32 major_version; /* from KFD */ @@ -110,6 +112,32 @@ struct kfd_ioctl_get_available_memory_args { __u32 pad; }; +struct kfd_dbg_device_info_entry { + __u64 exception_status; + __u64 lds_base; + __u64 lds_limit; + __u64 scratch_base; + __u64 scratch_limit; + __u64 gpuvm_base; + __u64 gpuvm_limit; + __u32 gpu_id; + __u32 location_id; + __u32 vendor_id; + __u32 device_id; + __u32 revision_id; + __u32 subsystem_vendor_id; + __u32 subsystem_device_id; + __u32 fw_version; + __u32 gfx_target_version; + __u32 simd_count; + __u32 max_waves_per_simd; + __u32 array_count; + __u32 simd_arrays_per_engine; + __u32 num_xcc; + __u32 capability; + __u32 debug_prop; +}; + /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */ #define KFD_IOC_CACHE_POLICY_COHERENT 0 #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1 @@ -293,12 +321,20 @@ struct kfd_hsa_hw_exception_data { __u32 gpu_id; }; +/* hsa signal event data */ +struct kfd_hsa_signal_event_data { + __u64 last_event_age; /* to and from KFD */ +}; + /* Event data */ struct kfd_event_data { union { + /* From KFD */ struct kfd_hsa_memory_exception_data memory_exception_data; struct kfd_hsa_hw_exception_data hw_exception_data; - }; /* From KFD */ + /* To and From KFD */ + struct kfd_hsa_signal_event_data signal_event_data; + }; __u64 kfd_event_data_ext; /* pointer to an extension structure for future exception types */ __u32 event_id; /* to KFD */ @@ -773,6 +809,640 @@ struct kfd_ioctl_set_xnack_mode_args { __s32 xnack_enabled; }; +/* Wave launch override modes */ +enum kfd_dbg_trap_override_mode { + KFD_DBG_TRAP_OVERRIDE_OR = 0, + KFD_DBG_TRAP_OVERRIDE_REPLACE = 1 +}; + +/* Wave launch overrides */ +enum kfd_dbg_trap_mask { + KFD_DBG_TRAP_MASK_FP_INVALID = 1, + KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL = 2, + KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO = 4, + KFD_DBG_TRAP_MASK_FP_OVERFLOW = 8, + KFD_DBG_TRAP_MASK_FP_UNDERFLOW = 16, + KFD_DBG_TRAP_MASK_FP_INEXACT = 32, + KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO = 64, + KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH = 128, + KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION = 256, + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START = (1 << 30), + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END = (1 << 31) +}; + +/* Wave launch modes */ +enum kfd_dbg_trap_wave_launch_mode { + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_NORMAL = 0, + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_HALT = 1, + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_DEBUG = 3 +}; + +/* Address watch modes */ +enum kfd_dbg_trap_address_watch_mode { + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ = 0, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_NONREAD = 1, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ATOMIC = 2, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ALL = 3 +}; + +/* Additional wave settings */ +enum kfd_dbg_trap_flags { + KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1, +}; + +/* Trap exceptions */ +enum kfd_dbg_trap_exception_code { + EC_NONE = 0, + /* per queue */ + EC_QUEUE_WAVE_ABORT = 1, + EC_QUEUE_WAVE_TRAP = 2, + EC_QUEUE_WAVE_MATH_ERROR = 3, + EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION = 4, + EC_QUEUE_WAVE_MEMORY_VIOLATION = 5, + EC_QUEUE_WAVE_APERTURE_VIOLATION = 6, + EC_QUEUE_PACKET_DISPATCH_DIM_INVALID = 16, + EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID = 17, + EC_QUEUE_PACKET_DISPATCH_CODE_INVALID = 18, + EC_QUEUE_PACKET_RESERVED = 19, + EC_QUEUE_PACKET_UNSUPPORTED = 20, + EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID = 21, + EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID = 22, + EC_QUEUE_PACKET_VENDOR_UNSUPPORTED = 23, + EC_QUEUE_PREEMPTION_ERROR = 30, + EC_QUEUE_NEW = 31, + /* per device */ + EC_DEVICE_QUEUE_DELETE = 32, + EC_DEVICE_MEMORY_VIOLATION = 33, + EC_DEVICE_RAS_ERROR = 34, + EC_DEVICE_FATAL_HALT = 35, + EC_DEVICE_NEW = 36, + /* per process */ + EC_PROCESS_RUNTIME = 48, + EC_PROCESS_DEVICE_REMOVE = 49, + EC_MAX +}; + +/* Mask generated by ecode in kfd_dbg_trap_exception_code */ +#define KFD_EC_MASK(ecode) (1ULL << (ecode - 1)) + +/* Masks for exception code type checks below */ +#define KFD_EC_MASK_QUEUE (KFD_EC_MASK(EC_QUEUE_WAVE_ABORT) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_MATH_ERROR) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_MEMORY_VIOLATION) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_APERTURE_VIOLATION) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED) | \ + KFD_EC_MASK(EC_QUEUE_PREEMPTION_ERROR) | \ + KFD_EC_MASK(EC_QUEUE_NEW)) +#define KFD_EC_MASK_DEVICE (KFD_EC_MASK(EC_DEVICE_QUEUE_DELETE) | \ + KFD_EC_MASK(EC_DEVICE_RAS_ERROR) | \ + KFD_EC_MASK(EC_DEVICE_FATAL_HALT) | \ + KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION) | \ + KFD_EC_MASK(EC_DEVICE_NEW)) +#define KFD_EC_MASK_PROCESS (KFD_EC_MASK(EC_PROCESS_RUNTIME) | \ + KFD_EC_MASK(EC_PROCESS_DEVICE_REMOVE)) + +/* Checks for exception code types for KFD search */ +#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode) \ + (!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE)) +#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode) \ + (!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE)) +#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode) \ + (!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS)) + + +/* Runtime enable states */ +enum kfd_dbg_runtime_state { + DEBUG_RUNTIME_STATE_DISABLED = 0, + DEBUG_RUNTIME_STATE_ENABLED = 1, + DEBUG_RUNTIME_STATE_ENABLED_BUSY = 2, + DEBUG_RUNTIME_STATE_ENABLED_ERROR = 3 +}; + +/* Runtime enable status */ +struct kfd_runtime_info { + __u64 r_debug; + __u32 runtime_state; + __u32 ttmp_setup; +}; + +/* Enable modes for runtime enable */ +#define KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK 1 +#define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK 2 + +/** + * kfd_ioctl_runtime_enable_args - Arguments for runtime enable + * + * Coordinates debug exception signalling and debug device enablement with runtime. + * + * @r_debug - pointer to user struct for sharing information between ROCr and the debuggger + * @mode_mask - mask to set mode + * KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK - enable runtime for debugging, otherwise disable + * KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK - enable trap temporary setup (ignore on disable) + * @capabilities_mask - mask to notify runtime on what KFD supports + * + * Return - 0 on SUCCESS. + * - EBUSY if runtime enable call already pending. + * - EEXIST if user queues already active prior to call. + * If process is debug enabled, runtime enable will enable debug devices and + * wait for debugger process to send runtime exception EC_PROCESS_RUNTIME + * to unblock - see kfd_ioctl_dbg_trap_args. + * + */ +struct kfd_ioctl_runtime_enable_args { + __u64 r_debug; + __u32 mode_mask; + __u32 capabilities_mask; +}; + +/* Queue information */ +struct kfd_queue_snapshot_entry { + __u64 exception_status; + __u64 ring_base_address; + __u64 write_pointer_address; + __u64 read_pointer_address; + __u64 ctx_save_restore_address; + __u32 queue_id; + __u32 gpu_id; + __u32 ring_size; + __u32 queue_type; + __u32 ctx_save_restore_area_size; + __u32 reserved; +}; + +/* Queue status return for suspend/resume */ +#define KFD_DBG_QUEUE_ERROR_BIT 30 +#define KFD_DBG_QUEUE_INVALID_BIT 31 +#define KFD_DBG_QUEUE_ERROR_MASK (1 << KFD_DBG_QUEUE_ERROR_BIT) +#define KFD_DBG_QUEUE_INVALID_MASK (1 << KFD_DBG_QUEUE_INVALID_BIT) + +/* Context save area header information */ +struct kfd_context_save_area_header { + struct { + __u32 control_stack_offset; + __u32 control_stack_size; + __u32 wave_state_offset; + __u32 wave_state_size; + } wave_state; + __u32 debug_offset; + __u32 debug_size; + __u64 err_payload_addr; + __u32 err_event_id; + __u32 reserved1; +}; + +/* + * Debug operations + * + * For specifics on usage and return values, see documentation per operation + * below. Otherwise, generic error returns apply: + * - ESRCH if the process to debug does not exist. + * + * - EINVAL (with KFD_IOC_DBG_TRAP_ENABLE exempt) if operation + * KFD_IOC_DBG_TRAP_ENABLE has not succeeded prior. + * Also returns this error if GPU hardware scheduling is not supported. + * + * - EPERM (with KFD_IOC_DBG_TRAP_DISABLE exempt) if target process is not + * PTRACE_ATTACHED. KFD_IOC_DBG_TRAP_DISABLE is exempt to allow + * clean up of debug mode as long as process is debug enabled. + * + * - EACCES if any DBG_HW_OP (debug hardware operation) is requested when + * AMDKFD_IOC_RUNTIME_ENABLE has not succeeded prior. + * + * - ENODEV if any GPU does not support debugging on a DBG_HW_OP call. + * + * - Other errors may be returned when a DBG_HW_OP occurs while the GPU + * is in a fatal state. + * + */ +enum kfd_dbg_trap_operations { + KFD_IOC_DBG_TRAP_ENABLE = 0, + KFD_IOC_DBG_TRAP_DISABLE = 1, + KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT = 2, + KFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED = 3, + KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE = 4, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE = 5, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SUSPEND_QUEUES = 6, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_RESUME_QUEUES = 7, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH = 8, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH = 9, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_FLAGS = 10, + KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT = 11, + KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO = 12, + KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT = 13, + KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT = 14 +}; + +/** + * kfd_ioctl_dbg_trap_enable_args + * + * Arguments for KFD_IOC_DBG_TRAP_ENABLE. + * + * Enables debug session for target process. Call @op KFD_IOC_DBG_TRAP_DISABLE in + * kfd_ioctl_dbg_trap_args to disable debug session. + * + * @exception_mask (IN) - exceptions to raise to the debugger + * @rinfo_ptr (IN) - pointer to runtime info buffer (see kfd_runtime_info) + * @rinfo_size (IN/OUT) - size of runtime info buffer in bytes + * @dbg_fd (IN) - fd the KFD will nofify the debugger with of raised + * exceptions set in exception_mask. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies KFD saved kfd_runtime_info to @rinfo_ptr on enable. + * Size of kfd_runtime saved by the KFD returned to @rinfo_size. + * - EBADF if KFD cannot get a reference to dbg_fd. + * - EFAULT if KFD cannot copy runtime info to rinfo_ptr. + * - EINVAL if target process is already debug enabled. + * + */ +struct kfd_ioctl_dbg_trap_enable_args { + __u64 exception_mask; + __u64 rinfo_ptr; + __u32 rinfo_size; + __u32 dbg_fd; +}; + +/** + * kfd_ioctl_dbg_trap_send_runtime_event_args + * + * + * Arguments for KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT. + * Raises exceptions to runtime. + * + * @exception_mask (IN) - exceptions to raise to runtime + * @gpu_id (IN) - target device id + * @queue_id (IN) - target queue id + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - ENODEV if gpu_id not found. + * If exception_mask contains EC_PROCESS_RUNTIME, unblocks pending + * AMDKFD_IOC_RUNTIME_ENABLE call - see kfd_ioctl_runtime_enable_args. + * All other exceptions are raised to runtime through err_payload_addr. + * See kfd_context_save_area_header. + */ +struct kfd_ioctl_dbg_trap_send_runtime_event_args { + __u64 exception_mask; + __u32 gpu_id; + __u32 queue_id; +}; + +/** + * kfd_ioctl_dbg_trap_set_exceptions_enabled_args + * + * Arguments for KFD_IOC_SET_EXCEPTIONS_ENABLED + * Set new exceptions to be raised to the debugger. + * + * @exception_mask (IN) - new exceptions to raise the debugger + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + */ +struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args { + __u64 exception_mask; +}; + +/** + * kfd_ioctl_dbg_trap_set_wave_launch_override_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE + * Enable HW exceptions to raise trap. + * + * @override_mode (IN) - see kfd_dbg_trap_override_mode + * @enable_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * IN is the override modes requested to be enabled. + * OUT is referenced in Return below. + * @support_request_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * IN is the override modes requested for support check. + * OUT is referenced in Return below. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Previous enablement is returned in @enable_mask. + * Actual override support is returned in @support_request_mask. + * - EINVAL if override mode is not supported. + * - EACCES if trap support requested is not actually supported. + * i.e. enable_mask (IN) is not a subset of support_request_mask (OUT). + * Otherwise it is considered a generic error (see kfd_dbg_trap_operations). + */ +struct kfd_ioctl_dbg_trap_set_wave_launch_override_args { + __u32 override_mode; + __u32 enable_mask; + __u32 support_request_mask; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_set_wave_launch_mode_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE + * Set wave launch mode. + * + * @mode (IN) - see kfd_dbg_trap_wave_launch_mode + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + */ +struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args { + __u32 launch_mode; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_suspend_queues_ags + * + * Arguments for KFD_IOC_DBG_TRAP_SUSPEND_QUEUES + * Suspend queues. + * + * @exception_mask (IN) - raised exceptions to clear + * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * to suspend + * @num_queues (IN) - number of queues to suspend in @queue_array_ptr + * @grace_period (IN) - wave time allowance before preemption + * per 1K GPU clock cycle unit + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Destruction of a suspended queue is blocked until the queue is + * resumed. This allows the debugger to access queue information and + * the its context save area without running into a race condition on + * queue destruction. + * Automatically copies per queue context save area header information + * into the save area base + * (see kfd_queue_snapshot_entry and kfd_context_save_area_header). + * + * Return - Number of queues suspended on SUCCESS. + * . KFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK masked + * for each queue id in @queue_array_ptr array reports unsuccessful + * suspend reason. + * KFD_DBG_QUEUE_ERROR_MASK = HW failure. + * KFD_DBG_QUEUE_INVALID_MASK = queue does not exist, is new or + * is being destroyed. + */ +struct kfd_ioctl_dbg_trap_suspend_queues_args { + __u64 exception_mask; + __u64 queue_array_ptr; + __u32 num_queues; + __u32 grace_period; +}; + +/** + * kfd_ioctl_dbg_trap_resume_queues_args + * + * Arguments for KFD_IOC_DBG_TRAP_RESUME_QUEUES + * Resume queues. + * + * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * to resume + * @num_queues (IN) - number of queues to resume in @queue_array_ptr + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - Number of queues resumed on SUCCESS. + * KFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK mask + * for each queue id in @queue_array_ptr array reports unsuccessful + * resume reason. + * KFD_DBG_QUEUE_ERROR_MASK = HW failure. + * KFD_DBG_QUEUE_INVALID_MASK = queue does not exist. + */ +struct kfd_ioctl_dbg_trap_resume_queues_args { + __u64 queue_array_ptr; + __u32 num_queues; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_set_node_address_watch_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH + * Sets address watch for device. + * + * @address (IN) - watch address to set + * @mode (IN) - see kfd_dbg_trap_address_watch_mode + * @mask (IN) - watch address mask + * @gpu_id (IN) - target gpu to set watch point + * @id (OUT) - watch id allocated + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Allocated watch ID returned to @id. + * - ENODEV if gpu_id not found. + * - ENOMEM if watch IDs can be allocated + */ +struct kfd_ioctl_dbg_trap_set_node_address_watch_args { + __u64 address; + __u32 mode; + __u32 mask; + __u32 gpu_id; + __u32 id; +}; + +/** + * kfd_ioctl_dbg_trap_clear_node_address_watch_args + * + * Arguments for KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH + * Clear address watch for device. + * + * @gpu_id (IN) - target device to clear watch point + * @id (IN) - allocated watch id to clear + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - ENODEV if gpu_id not found. + * - EINVAL if watch ID has not been allocated. + */ +struct kfd_ioctl_dbg_trap_clear_node_address_watch_args { + __u32 gpu_id; + __u32 id; +}; + +/** + * kfd_ioctl_dbg_trap_set_flags_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_FLAGS + * Sets flags for wave behaviour. + * + * @flags (IN/OUT) - IN = flags to enable, OUT = flags previously enabled + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - EACCESS if any debug device does not allow flag options. + */ +struct kfd_ioctl_dbg_trap_set_flags_args { + __u32 flags; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_query_debug_event_args + * + * Arguments for KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT + * + * Find one or more raised exceptions. This function can return multiple + * exceptions from a single queue or a single device with one call. To find + * all raised exceptions, this function must be called repeatedly until it + * returns -EAGAIN. Returned exceptions can optionally be cleared by + * setting the corresponding bit in the @exception_mask input parameter. + * However, clearing an exception prevents retrieving further information + * about it with KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO. + * + * @exception_mask (IN/OUT) - exception to clear (IN) and raised (OUT) + * @gpu_id (OUT) - gpu id of exceptions raised + * @queue_id (OUT) - queue id of exceptions raised + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on raised exception found + * Raised exceptions found are returned in @exception mask + * with reported source id returned in @gpu_id or @queue_id. + * - EAGAIN if no raised exception has been found + */ +struct kfd_ioctl_dbg_trap_query_debug_event_args { + __u64 exception_mask; + __u32 gpu_id; + __u32 queue_id; +}; + +/** + * kfd_ioctl_dbg_trap_query_exception_info_args + * + * Arguments KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO + * Get additional info on raised exception. + * + * @info_ptr (IN) - pointer to exception info buffer to copy to + * @info_size (IN/OUT) - exception info buffer size (bytes) + * @source_id (IN) - target gpu or queue id + * @exception_code (IN) - target exception + * @clear_exception (IN) - clear raised @exception_code exception + * (0 = false, 1 = true) + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * If @exception_code is EC_DEVICE_MEMORY_VIOLATION, copy @info_size(OUT) + * bytes of memory exception data to @info_ptr. + * If @exception_code is EC_PROCESS_RUNTIME, copy saved + * kfd_runtime_info to @info_ptr. + * Actual required @info_ptr size (bytes) is returned in @info_size. + */ +struct kfd_ioctl_dbg_trap_query_exception_info_args { + __u64 info_ptr; + __u32 info_size; + __u32 source_id; + __u32 exception_code; + __u32 clear_exception; +}; + +/** + * kfd_ioctl_dbg_trap_get_queue_snapshot_args + * + * Arguments KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT + * Get queue information. + * + * @exception_mask (IN) - exceptions raised to clear + * @snapshot_buf_ptr (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry) + * @num_queues (IN/OUT) - number of queue snapshot entries + * The debugger specifies the size of the array allocated in @num_queues. + * KFD returns the number of queues that actually existed. If this is + * larger than the size specified by the debugger, KFD will not overflow + * the array allocated by the debugger. + * + * @entry_size (IN/OUT) - size per entry in bytes + * The debugger specifies sizeof(struct kfd_queue_snapshot_entry) in + * @entry_size. KFD returns the number of bytes actually populated per + * entry. The debugger should use the KFD_IOCTL_MINOR_VERSION to determine, + * which fields in struct kfd_queue_snapshot_entry are valid. This allows + * growing the ABI in a backwards compatible manner. + * Note that entry_size(IN) should still be used to stride the snapshot buffer in the + * event that it's larger than actual kfd_queue_snapshot_entry. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies @num_queues(IN) queue snapshot entries of size @entry_size(IN) + * into @snapshot_buf_ptr if @num_queues(IN) > 0. + * Otherwise return @num_queues(OUT) queue snapshot entries that exist. + */ +struct kfd_ioctl_dbg_trap_queue_snapshot_args { + __u64 exception_mask; + __u64 snapshot_buf_ptr; + __u32 num_queues; + __u32 entry_size; +}; + +/** + * kfd_ioctl_dbg_trap_get_device_snapshot_args + * + * Arguments for KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT + * Get device information. + * + * @exception_mask (IN) - exceptions raised to clear + * @snapshot_buf_ptr (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry) + * @num_devices (IN/OUT) - number of debug devices to snapshot + * The debugger specifies the size of the array allocated in @num_devices. + * KFD returns the number of devices that actually existed. If this is + * larger than the size specified by the debugger, KFD will not overflow + * the array allocated by the debugger. + * + * @entry_size (IN/OUT) - size per entry in bytes + * The debugger specifies sizeof(struct kfd_dbg_device_info_entry) in + * @entry_size. KFD returns the number of bytes actually populated. The + * debugger should use KFD_IOCTL_MINOR_VERSION to determine, which fields + * in struct kfd_dbg_device_info_entry are valid. This allows growing the + * ABI in a backwards compatible manner. + * Note that entry_size(IN) should still be used to stride the snapshot buffer in the + * event that it's larger than actual kfd_dbg_device_info_entry. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies @num_devices(IN) device snapshot entries of size @entry_size(IN) + * into @snapshot_buf_ptr if @num_devices(IN) > 0. + * Otherwise return @num_devices(OUT) queue snapshot entries that exist. + */ +struct kfd_ioctl_dbg_trap_device_snapshot_args { + __u64 exception_mask; + __u64 snapshot_buf_ptr; + __u32 num_devices; + __u32 entry_size; +}; + +/** + * kfd_ioctl_dbg_trap_args + * + * Arguments to debug target process. + * + * @pid - target process to debug + * @op - debug operation (see kfd_dbg_trap_operations) + * + * @op determines which union struct args to use. + * Refer to kern docs for each kfd_ioctl_dbg_trap_*_args struct. + */ +struct kfd_ioctl_dbg_trap_args { + __u32 pid; + __u32 op; + + union { + struct kfd_ioctl_dbg_trap_enable_args enable; + struct kfd_ioctl_dbg_trap_send_runtime_event_args send_runtime_event; + struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args set_exceptions_enabled; + struct kfd_ioctl_dbg_trap_set_wave_launch_override_args launch_override; + struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args launch_mode; + struct kfd_ioctl_dbg_trap_suspend_queues_args suspend_queues; + struct kfd_ioctl_dbg_trap_resume_queues_args resume_queues; + struct kfd_ioctl_dbg_trap_set_node_address_watch_args set_node_address_watch; + struct kfd_ioctl_dbg_trap_clear_node_address_watch_args clear_node_address_watch; + struct kfd_ioctl_dbg_trap_set_flags_args set_flags; + struct kfd_ioctl_dbg_trap_query_debug_event_args query_debug_event; + struct kfd_ioctl_dbg_trap_query_exception_info_args query_exception_info; + struct kfd_ioctl_dbg_trap_queue_snapshot_args queue_snapshot; + struct kfd_ioctl_dbg_trap_device_snapshot_args device_snapshot; + }; +}; + #define AMDKFD_IOCTL_BASE 'K' #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr) #define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type) @@ -887,7 +1557,13 @@ struct kfd_ioctl_set_xnack_mode_args { #define AMDKFD_IOC_EXPORT_DMABUF \ AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args) +#define AMDKFD_IOC_RUNTIME_ENABLE \ + AMDKFD_IOWR(0x25, struct kfd_ioctl_runtime_enable_args) + +#define AMDKFD_IOC_DBG_TRAP \ + AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args) + #define AMDKFD_COMMAND_START 0x01 -#define AMDKFD_COMMAND_END 0x25 +#define AMDKFD_COMMAND_END 0x27 #endif diff --git a/include/uapi/linux/kfd_sysfs.h b/include/uapi/linux/kfd_sysfs.h index 3e330f368917..a51b7331e0b4 100644 --- a/include/uapi/linux/kfd_sysfs.h +++ b/include/uapi/linux/kfd_sysfs.h @@ -43,6 +43,11 @@ #define HSA_CAP_DOORBELL_TYPE_2_0 0x2 #define HSA_CAP_AQL_QUEUE_DOUBLE_MAP 0x00004000 +#define HSA_CAP_TRAP_DEBUG_SUPPORT 0x00008000 +#define HSA_CAP_TRAP_DEBUG_WAVE_LAUNCH_TRAP_OVERRIDE_SUPPORTED 0x00010000 +#define HSA_CAP_TRAP_DEBUG_WAVE_LAUNCH_MODE_SUPPORTED 0x00020000 +#define HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED 0x00040000 + /* Old buggy user mode depends on this being 0 */ #define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000 @@ -53,8 +58,18 @@ #define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000 #define HSA_CAP_SVMAPI_SUPPORTED 0x08000000 #define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000 +#define HSA_CAP_TRAP_DEBUG_FIRMWARE_SUPPORTED 0x20000000 #define HSA_CAP_RESERVED 0xe00f8000 +/* debug_prop bits in node properties */ +#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_MASK 0x0000000f +#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_SHIFT 0 +#define HSA_DBG_WATCH_ADDR_MASK_HI_BIT_MASK 0x000003f0 +#define HSA_DBG_WATCH_ADDR_MASK_HI_BIT_SHIFT 4 +#define HSA_DBG_DISPATCH_INFO_ALWAYS_VALID 0x00000400 +#define HSA_DBG_WATCHPOINTS_EXCLUSIVE 0x00000800 +#define HSA_DBG_RESERVED 0xfffffffffffff000ull + /* Heap types in memory properties */ #define HSA_MEM_HEAP_TYPE_SYSTEM 0 #define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1 diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 737318b1c1d9..f089ab290978 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1190,6 +1190,8 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225 #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226 #define KVM_CAP_COUNTER_OFFSET 227 +#define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 +#define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 #ifdef KVM_CAP_IRQ_ROUTING @@ -1442,6 +1444,8 @@ enum kvm_device_type { #define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_ARM_PV_TIME, #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME + KVM_DEV_TYPE_RISCV_AIA, +#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_MAX, }; @@ -1613,7 +1617,7 @@ struct kvm_s390_ucas_mapping { #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) /* - * vcpu version available with KVM_ENABLE_CAP + * vcpu version available with KVM_CAP_ENABLE_CAP * vm version available with KVM_CAP_ENABLE_CAP_VM */ #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h index 256b463e47a6..b826598d1e94 100644 --- a/include/uapi/linux/mdio.h +++ b/include/uapi/linux/mdio.h @@ -231,6 +231,30 @@ #define MDIO_PMA_EXTABLE_BT1 0x0800 /* BASE-T1 ability */ #define MDIO_PMA_EXTABLE_NBT 0x4000 /* 2.5/5GBASE-T ability */ +/* AN Clause 73 linkword */ +#define MDIO_AN_C73_0_S_MASK GENMASK(4, 0) +#define MDIO_AN_C73_0_E_MASK GENMASK(9, 5) +#define MDIO_AN_C73_0_PAUSE BIT(10) +#define MDIO_AN_C73_0_ASM_DIR BIT(11) +#define MDIO_AN_C73_0_C2 BIT(12) +#define MDIO_AN_C73_0_RF BIT(13) +#define MDIO_AN_C73_0_ACK BIT(14) +#define MDIO_AN_C73_0_NP BIT(15) +#define MDIO_AN_C73_1_T_MASK GENMASK(4, 0) +#define MDIO_AN_C73_1_1000BASE_KX BIT(5) +#define MDIO_AN_C73_1_10GBASE_KX4 BIT(6) +#define MDIO_AN_C73_1_10GBASE_KR BIT(7) +#define MDIO_AN_C73_1_40GBASE_KR4 BIT(8) +#define MDIO_AN_C73_1_40GBASE_CR4 BIT(9) +#define MDIO_AN_C73_1_100GBASE_CR10 BIT(10) +#define MDIO_AN_C73_1_100GBASE_KP4 BIT(11) +#define MDIO_AN_C73_1_100GBASE_KR4 BIT(12) +#define MDIO_AN_C73_1_100GBASE_CR4 BIT(13) +#define MDIO_AN_C73_1_25GBASE_R_S BIT(14) +#define MDIO_AN_C73_1_25GBASE_R BIT(15) +#define MDIO_AN_C73_2_2500BASE_KX BIT(0) +#define MDIO_AN_C73_2_5GBASE_KR BIT(1) + /* PHY XGXS lane state register. */ #define MDIO_PHYXS_LNSTAT_SYNC0 0x0001 #define MDIO_PHYXS_LNSTAT_SYNC1 0x0002 diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ddadaea849f..1c80b1d6bbaf 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -140,8 +140,8 @@ struct media_device_info { #define MEDIA_ENT_F_DV_ENCODER (MEDIA_ENT_F_BASE + 0x6002) /* Entity flags */ -#define MEDIA_ENT_FL_DEFAULT (1 << 0) -#define MEDIA_ENT_FL_CONNECTOR (1 << 1) +#define MEDIA_ENT_FL_DEFAULT (1U << 0) +#define MEDIA_ENT_FL_CONNECTOR (1U << 1) /* OR with the entity id value to find the next entity */ #define MEDIA_ENT_ID_FLAG_NEXT (1U << 31) @@ -205,9 +205,9 @@ struct media_entity_desc { }; }; -#define MEDIA_PAD_FL_SINK (1 << 0) -#define MEDIA_PAD_FL_SOURCE (1 << 1) -#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2) +#define MEDIA_PAD_FL_SINK (1U << 0) +#define MEDIA_PAD_FL_SOURCE (1U << 1) +#define MEDIA_PAD_FL_MUST_CONNECT (1U << 2) struct media_pad_desc { __u32 entity; /* entity ID */ @@ -216,14 +216,14 @@ struct media_pad_desc { __u32 reserved[2]; }; -#define MEDIA_LNK_FL_ENABLED (1 << 0) -#define MEDIA_LNK_FL_IMMUTABLE (1 << 1) -#define MEDIA_LNK_FL_DYNAMIC (1 << 2) +#define MEDIA_LNK_FL_ENABLED (1U << 0) +#define MEDIA_LNK_FL_IMMUTABLE (1U << 1) +#define MEDIA_LNK_FL_DYNAMIC (1U << 2) #define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) -# define MEDIA_LNK_FL_DATA_LINK (0 << 28) -# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) -# define MEDIA_LNK_FL_ANCILLARY_LINK (2 << 28) +# define MEDIA_LNK_FL_DATA_LINK (0U << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1U << 28) +# define MEDIA_LNK_FL_ANCILLARY_LINK (2U << 28) struct media_link_desc { struct media_pad_desc source; @@ -293,7 +293,7 @@ struct media_links_enum { * struct media_device_info. */ #define MEDIA_V2_ENTITY_HAS_FLAGS(media_version) \ - ((media_version) >= ((4 << 16) | (19 << 8) | 0)) + ((media_version) >= ((4U << 16) | (19U << 8) | 0U)) struct media_v2_entity { __u32 id; @@ -328,7 +328,7 @@ struct media_v2_interface { * struct media_device_info. */ #define MEDIA_V2_PAD_HAS_INDEX(media_version) \ - ((media_version) >= ((4 << 16) | (19 << 8) | 0)) + ((media_version) >= ((4U << 16) | (19U << 8) | 0U)) struct media_v2_pad { __u32 id; @@ -432,7 +432,7 @@ struct media_v2_topology { #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7) /* Obsolete symbol for media_version, no longer used in the kernel */ -#define MEDIA_API_VERSION ((0 << 16) | (1 << 8) | 0) +#define MEDIA_API_VERSION ((0U << 16) | (1U << 8) | 0U) #endif diff --git a/include/uapi/linux/mman.h b/include/uapi/linux/mman.h index f55bc680b5b0..a246e11988d5 100644 --- a/include/uapi/linux/mman.h +++ b/include/uapi/linux/mman.h @@ -4,6 +4,7 @@ #include <asm/mman.h> #include <asm-generic/hugetlb_encode.h> +#include <linux/types.h> #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 @@ -41,4 +42,17 @@ #define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB #define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB +struct cachestat_range { + __u64 off; + __u64 len; +}; + +struct cachestat { + __u64 nr_cache; + __u64 nr_dirty; + __u64 nr_writeback; + __u64 nr_evicted; + __u64 nr_recently_evicted; +}; + #endif /* _UAPI_LINUX_MMAN_H */ diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h index 4d93967f8aea..8eb0d7b758d2 100644 --- a/include/uapi/linux/mount.h +++ b/include/uapi/linux/mount.h @@ -74,7 +74,8 @@ #define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020 /* Follow automounts on to path */ #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */ #define MOVE_MOUNT_SET_GROUP 0x00000100 /* Set sharing group instead */ -#define MOVE_MOUNT__MASK 0x00000177 +#define MOVE_MOUNT_BENEATH 0x00000200 /* Mount beneath top mount */ +#define MOVE_MOUNT__MASK 0x00000377 /* * fsopen() flags. diff --git a/include/uapi/linux/mptcp.h b/include/uapi/linux/mptcp.h index 32af2d278cb4..ee9c49f949a2 100644 --- a/include/uapi/linux/mptcp.h +++ b/include/uapi/linux/mptcp.h @@ -123,6 +123,11 @@ struct mptcp_info { __u8 mptcpi_local_addr_used; __u8 mptcpi_local_addr_max; __u8 mptcpi_csum_enabled; + __u32 mptcpi_retransmits; + __u64 mptcpi_bytes_retrans; + __u64 mptcpi_bytes_sent; + __u64 mptcpi_bytes_received; + __u64 mptcpi_bytes_acked; }; /* @@ -244,9 +249,33 @@ struct mptcp_subflow_addrs { }; }; +struct mptcp_subflow_info { + __u32 id; + struct mptcp_subflow_addrs addrs; +}; + +struct mptcp_full_info { + __u32 size_tcpinfo_kernel; /* must be 0, set by kernel */ + __u32 size_tcpinfo_user; + __u32 size_sfinfo_kernel; /* must be 0, set by kernel */ + __u32 size_sfinfo_user; + __u32 num_subflows; /* must be 0, set by kernel (real subflow count) */ + __u32 size_arrays_user; /* max subflows that userspace is interested in; + * the buffers at subflow_info/tcp_info + * are respectively at least: + * size_arrays * size_sfinfo_user + * size_arrays * size_tcpinfo_user + * bytes wide + */ + __aligned_u64 subflow_info; + __aligned_u64 tcp_info; + struct mptcp_info mptcp_info; +}; + /* MPTCP socket options */ #define MPTCP_INFO 1 #define MPTCP_TCPINFO 2 #define MPTCP_SUBFLOW_ADDRS 3 +#define MPTCP_FULL_INFO 4 #endif /* _UAPI_MPTCP_H */ diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c4d4d8e42dc8..8466c2a9938f 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -105,6 +105,7 @@ enum nft_verdicts { * @NFT_MSG_DESTROYSETELEM: destroy a set element (enum nft_set_elem_attributes) * @NFT_MSG_DESTROYOBJ: destroy a stateful object (enum nft_object_attributes) * @NFT_MSG_DESTROYFLOWTABLE: destroy flow table (enum nft_flowtable_attributes) + * @NFT_MSG_GETSETELEM_RESET: get set elements and reset attached stateful expressions (enum nft_set_elem_attributes) */ enum nf_tables_msg_types { NFT_MSG_NEWTABLE, @@ -140,6 +141,7 @@ enum nf_tables_msg_types { NFT_MSG_DESTROYSETELEM, NFT_MSG_DESTROYOBJ, NFT_MSG_DESTROYFLOWTABLE, + NFT_MSG_GETSETELEM_RESET, NFT_MSG_MAX, }; @@ -859,12 +861,14 @@ enum nft_exthdr_flags { * @NFT_EXTHDR_OP_TCP: match against tcp options * @NFT_EXTHDR_OP_IPV4: match against ipv4 options * @NFT_EXTHDR_OP_SCTP: match against sctp chunks + * @NFT_EXTHDR_OP_DCCP: match against dccp otions */ enum nft_exthdr_op { NFT_EXTHDR_OP_IPV6, NFT_EXTHDR_OP_TCPOPT, NFT_EXTHDR_OP_IPV4, NFT_EXTHDR_OP_SCTP, + NFT_EXTHDR_OP_DCCP, __NFT_EXTHDR_OP_MAX }; #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index c59fec406da5..88eb85c63029 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -11,7 +11,7 @@ * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> * Copyright 2008 Colin McCabe <colin@cozybit.com> * Copyright 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1309,6 +1309,11 @@ * The number of peers that HW timestamping can be enabled for concurrently * is indicated by %NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS. * + * @NL80211_CMD_LINKS_REMOVED: Notify userspace about the removal of STA MLD + * setup links due to AP MLD removing the corresponding affiliated APs with + * Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide + * information about the removed STA MLD setup links. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1562,6 +1567,8 @@ enum nl80211_commands { NL80211_CMD_SET_HW_TIMESTAMP, + NL80211_CMD_LINKS_REMOVED, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2805,6 +2812,9 @@ enum nl80211_commands { * index. If the userspace includes more RNR elements than number of * MBSSID elements then these will be added in every EMA beacon. * + * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is + * disabled. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3341,6 +3351,8 @@ enum nl80211_attrs { NL80211_ATTR_EMA_RNR_ELEMS, + NL80211_ATTR_MLO_LINK_DISABLED, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -3667,6 +3679,13 @@ enum nl80211_eht_ru_alloc { * (u8, see &enum nl80211_eht_gi) * @NL80211_RATE_INFO_EHT_RU_ALLOC: EHT RU allocation, if not present then * non-OFDMA was used (u8, see &enum nl80211_eht_ru_alloc) + * @NL80211_RATE_INFO_S1G_MCS: S1G MCS index (u8, 0-10) + * @NL80211_RATE_INFO_S1G_NSS: S1G NSS value (u8, 1-4) + * @NL80211_RATE_INFO_1_MHZ_WIDTH: 1 MHz S1G rate + * @NL80211_RATE_INFO_2_MHZ_WIDTH: 2 MHz S1G rate + * @NL80211_RATE_INFO_4_MHZ_WIDTH: 4 MHz S1G rate + * @NL80211_RATE_INFO_8_MHZ_WIDTH: 8 MHz S1G rate + * @NL80211_RATE_INFO_16_MHZ_WIDTH: 16 MHz S1G rate * @__NL80211_RATE_INFO_AFTER_LAST: internal use */ enum nl80211_rate_info { @@ -3693,6 +3712,13 @@ enum nl80211_rate_info { NL80211_RATE_INFO_EHT_NSS, NL80211_RATE_INFO_EHT_GI, NL80211_RATE_INFO_EHT_RU_ALLOC, + NL80211_RATE_INFO_S1G_MCS, + NL80211_RATE_INFO_S1G_NSS, + NL80211_RATE_INFO_1_MHZ_WIDTH, + NL80211_RATE_INFO_2_MHZ_WIDTH, + NL80211_RATE_INFO_4_MHZ_WIDTH, + NL80211_RATE_INFO_8_MHZ_WIDTH, + NL80211_RATE_INFO_16_MHZ_WIDTH, /* keep last */ __NL80211_RATE_INFO_AFTER_LAST, @@ -4424,6 +4450,7 @@ enum nl80211_sched_scan_match_attr { * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed * @NL80211_RRF_NO_HE: HE operation not allowed * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed + * @NL80211_RRF_NO_EHT: EHT operation not allowed */ enum nl80211_reg_rule_flags { NL80211_RRF_NO_OFDM = 1<<0, @@ -4443,6 +4470,7 @@ enum nl80211_reg_rule_flags { NL80211_RRF_NO_160MHZ = 1<<16, NL80211_RRF_NO_HE = 1<<17, NL80211_RRF_NO_320MHZ = 1<<18, + NL80211_RRF_NO_EHT = 1<<19, }; #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index c5d62ee82567..e94870e77ee9 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -765,6 +765,7 @@ struct ovs_action_push_vlan { */ enum ovs_hash_alg { OVS_HASH_ALG_L4, + OVS_HASH_ALG_SYM_L4, }; /* diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index dc2000e0fe3a..e5f558d96493 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -738,6 +738,7 @@ #define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ #define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */ #define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */ +#define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index 648a82f32666..7865f5a9885b 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -594,6 +594,10 @@ enum { TCA_FLOWER_KEY_L2TPV3_SID, /* be32 */ + TCA_FLOWER_L2_MISS, /* u8 */ + + TCA_FLOWER_KEY_CFM, /* nested */ + __TCA_FLOWER_MAX, }; @@ -702,6 +706,13 @@ enum { TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), }; +enum { + TCA_FLOWER_KEY_CFM_OPT_UNSPEC, + TCA_FLOWER_KEY_CFM_MD_LEVEL, + TCA_FLOWER_KEY_CFM_OPCODE, + TCA_FLOWER_KEY_CFM_OPT_MAX, +}; + #define TCA_FLOWER_MASK_FLAGS_RANGE (1 << 0) /* Range-based match */ /* Match-all classifier */ diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index 51a7addc56c6..00f6ff0aff1f 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -1260,6 +1260,16 @@ enum { }; enum { + TCA_TAPRIO_OFFLOAD_STATS_PAD = 1, /* u64 */ + TCA_TAPRIO_OFFLOAD_STATS_WINDOW_DROPS, /* u64 */ + TCA_TAPRIO_OFFLOAD_STATS_TX_OVERRUNS, /* u64 */ + + /* add new constants above here */ + __TCA_TAPRIO_OFFLOAD_STATS_CNT, + TCA_TAPRIO_OFFLOAD_STATS_MAX = (__TCA_TAPRIO_OFFLOAD_STATS_CNT - 1) +}; + +enum { TCA_TAPRIO_ATTR_UNSPEC, TCA_TAPRIO_ATTR_PRIOMAP, /* struct tc_mqprio_qopt */ TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST, /* nested of entry */ diff --git a/include/uapi/linux/pktcdvd.h b/include/uapi/linux/pktcdvd.h index 6a5552dfd6af..987a3022dc5f 100644 --- a/include/uapi/linux/pktcdvd.h +++ b/include/uapi/linux/pktcdvd.h @@ -16,6 +16,7 @@ #include <linux/types.h> /* + * UNUSED: * 1 for normal debug messages, 2 is very verbose. 0 to turn it off. */ #define PACKET_DEBUG 1 diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index f23d9a16507f..3c36aeade991 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -294,4 +294,15 @@ struct prctl_mm_map { #define PR_SET_MEMORY_MERGE 67 #define PR_GET_MEMORY_MERGE 68 + +#define PR_RISCV_V_SET_CONTROL 69 +#define PR_RISCV_V_GET_CONTROL 70 +# define PR_RISCV_V_VSTATE_CTRL_DEFAULT 0 +# define PR_RISCV_V_VSTATE_CTRL_OFF 1 +# define PR_RISCV_V_VSTATE_CTRL_ON 2 +# define PR_RISCV_V_VSTATE_CTRL_INHERIT (1 << 4) +# define PR_RISCV_V_VSTATE_CTRL_CUR_MASK 0x3 +# define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc +# define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f + #endif /* _LINUX_PRCTL_H */ diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h index 1d108d597f66..05cc35fc94ac 100644 --- a/include/uapi/linux/ptp_clock.h +++ b/include/uapi/linux/ptp_clock.h @@ -95,7 +95,8 @@ struct ptp_clock_caps { int cross_timestamping; /* Whether the clock supports adjust phase */ int adjust_phase; - int rsv[12]; /* Reserved for future use. */ + int max_phase_adj; /* Maximum phase adjustment in nanoseconds. */ + int rsv[11]; /* Reserved for future use. */ }; struct ptp_extts_request { diff --git a/include/uapi/linux/spi/spi.h b/include/uapi/linux/spi/spi.h index 9d5f58059703..ca56e477d161 100644 --- a/include/uapi/linux/spi/spi.h +++ b/include/uapi/linux/spi/spi.h @@ -28,6 +28,7 @@ #define SPI_RX_OCTAL _BITUL(14) /* receive with 8 wires */ #define SPI_3WIRE_HIZ _BITUL(15) /* high impedance turnaround */ #define SPI_RX_CPHA_FLIP _BITUL(16) /* flip CPHA on Rx only xfer */ +#define SPI_MOSI_IDLE_LOW _BITUL(17) /* leave mosi line low when idle */ /* * All the bits defined above should be covered by SPI_MODE_USER_MASK. @@ -37,6 +38,6 @@ * These bits must not overlap. A static assert check should make sure of that. * If adding extra bits, make sure to increase the bit index below as well. */ -#define SPI_MODE_USER_MASK (_BITUL(17) - 1) +#define SPI_MODE_USER_MASK (_BITUL(18) - 1) #endif /* _UAPI_SPI_H */ diff --git a/include/uapi/linux/tps6594_pfsm.h b/include/uapi/linux/tps6594_pfsm.h new file mode 100644 index 000000000000..c69569e0a7a2 --- /dev/null +++ b/include/uapi/linux/tps6594_pfsm.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Userspace ABI for TPS6594 PMIC Pre-configurable Finite State Machine + * + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ + */ + +#ifndef __TPS6594_PFSM_H +#define __TPS6594_PFSM_H + +#include <linux/const.h> +#include <linux/ioctl.h> +#include <linux/types.h> + +/** + * struct pmic_state_opt - PMIC state options + * @gpio_retention: if enabled, power rails associated with GPIO retention remain active + * @ddr_retention: if enabled, power rails associated with DDR retention remain active + * @mcu_only_startup_dest: if enabled, startup destination state is MCU_ONLY + */ +struct pmic_state_opt { + __u8 gpio_retention; + __u8 ddr_retention; + __u8 mcu_only_startup_dest; +}; + +/* Commands */ +#define PMIC_BASE 'P' + +#define PMIC_GOTO_STANDBY _IO(PMIC_BASE, 0) +#define PMIC_GOTO_LP_STANDBY _IO(PMIC_BASE, 1) +#define PMIC_UPDATE_PGM _IO(PMIC_BASE, 2) +#define PMIC_SET_ACTIVE_STATE _IO(PMIC_BASE, 3) +#define PMIC_SET_MCU_ONLY_STATE _IOW(PMIC_BASE, 4, struct pmic_state_opt) +#define PMIC_SET_RETENTION_STATE _IOW(PMIC_BASE, 5, struct pmic_state_opt) + +#endif /* __TPS6594_PFSM_H */ diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h index 308433be33c2..6375a0684052 100644 --- a/include/uapi/linux/types.h +++ b/include/uapi/linux/types.h @@ -13,6 +13,10 @@ #include <linux/posix_types.h> +#ifdef __SIZEOF_INT128__ +typedef __signed__ __int128 __s128 __attribute__((aligned(16))); +typedef unsigned __int128 __u128 __attribute__((aligned(16))); +#endif /* * Below are truly Linux-specific types that should never collide with diff --git a/include/uapi/linux/ublk_cmd.h b/include/uapi/linux/ublk_cmd.h index 640bf687b94a..4b8558db90e1 100644 --- a/include/uapi/linux/ublk_cmd.h +++ b/include/uapi/linux/ublk_cmd.h @@ -47,6 +47,14 @@ _IOWR('u', UBLK_CMD_END_USER_RECOVERY, struct ublksrv_ctrl_cmd) #define UBLK_U_CMD_GET_DEV_INFO2 \ _IOR('u', UBLK_CMD_GET_DEV_INFO2, struct ublksrv_ctrl_cmd) +#define UBLK_U_CMD_GET_FEATURES \ + _IOR('u', 0x13, struct ublksrv_ctrl_cmd) + +/* + * 64bits are enough now, and it should be easy to extend in case of + * running out of feature flags + */ +#define UBLK_FEATURES_LEN 8 /* * IO commands, issued by ublk server, and handled by ublk driver. @@ -93,9 +101,29 @@ #define UBLKSRV_CMD_BUF_OFFSET 0 #define UBLKSRV_IO_BUF_OFFSET 0x80000000 -/* tag bit is 12bit, so at most 4096 IOs for each queue */ +/* tag bit is 16bit, so far limit at most 4096 IOs for each queue */ #define UBLK_MAX_QUEUE_DEPTH 4096 +/* single IO buffer max size is 32MB */ +#define UBLK_IO_BUF_OFF 0 +#define UBLK_IO_BUF_BITS 25 +#define UBLK_IO_BUF_BITS_MASK ((1ULL << UBLK_IO_BUF_BITS) - 1) + +/* so at most 64K IOs for each queue */ +#define UBLK_TAG_OFF UBLK_IO_BUF_BITS +#define UBLK_TAG_BITS 16 +#define UBLK_TAG_BITS_MASK ((1ULL << UBLK_TAG_BITS) - 1) + +/* max 4096 queues */ +#define UBLK_QID_OFF (UBLK_TAG_OFF + UBLK_TAG_BITS) +#define UBLK_QID_BITS 12 +#define UBLK_QID_BITS_MASK ((1ULL << UBLK_QID_BITS) - 1) + +#define UBLK_MAX_NR_QUEUES (1U << UBLK_QID_BITS) + +#define UBLKSRV_IO_BUF_TOTAL_BITS (UBLK_QID_OFF + UBLK_QID_BITS) +#define UBLKSRV_IO_BUF_TOTAL_SIZE (1ULL << UBLKSRV_IO_BUF_TOTAL_BITS) + /* * zero copy requires 4k block size, and can remap ublk driver's io * request into ublksrv's vm space @@ -145,6 +173,9 @@ /* use ioctl encoding for uring command */ #define UBLK_F_CMD_IOCTL_ENCODE (1UL << 6) +/* Copy between request and user buffer by pread()/pwrite() */ +#define UBLK_F_USER_COPY (1UL << 7) + /* device state */ #define UBLK_S_DEV_DEAD 0 #define UBLK_S_DEV_LIVE 1 diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index b17e3a21b15f..82ec6af71a1d 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -376,7 +376,10 @@ struct usb_string_descriptor { __u8 bLength; __u8 bDescriptorType; - __le16 wData[1]; /* UTF-16LE encoded */ + union { + __le16 legacy_padding; + __DECLARE_FLEX_ARRAY(__le16, wData); /* UTF-16LE encoded */ + }; } __attribute__ ((packed)); /* note that "string" zero is special, it holds language codes that diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 5e80daa4ffe0..c3604a0a3e30 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -804,6 +804,88 @@ enum v4l2_mpeg_video_frame_skip_mode { #define V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY (V4L2_CID_CODEC_BASE + 653) #define V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE (V4L2_CID_CODEC_BASE + 654) +#define V4L2_CID_MPEG_VIDEO_AV1_PROFILE (V4L2_CID_CODEC_BASE + 655) +/** + * enum v4l2_mpeg_video_av1_profile - AV1 profiles + * + * @V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN: compliant decoders must be able to decode + * streams with seq_profile equal to 0. + * @V4L2_MPEG_VIDEO_AV1_PROFILE_HIGH: compliant decoders must be able to decode + * streams with seq_profile equal less than or equal to 1. + * @V4L2_MPEG_VIDEO_AV1_PROFILE_PROFESSIONAL: compliant decoders must be able to + * decode streams with seq_profile less than or equal to 2. + * + * Conveys the highest profile a decoder can work with. + */ +enum v4l2_mpeg_video_av1_profile { + V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN = 0, + V4L2_MPEG_VIDEO_AV1_PROFILE_HIGH = 1, + V4L2_MPEG_VIDEO_AV1_PROFILE_PROFESSIONAL = 2, +}; + +#define V4L2_CID_MPEG_VIDEO_AV1_LEVEL (V4L2_CID_CODEC_BASE + 656) +/** + * enum v4l2_mpeg_video_av1_level - AV1 levels + * + * @V4L2_MPEG_VIDEO_AV1_LEVEL_2_0: Level 2.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_2_1: Level 2.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_2_2: Level 2.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_2_3: Level 2.3. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_3_0: Level 3.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_3_1: Level 3.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_3_2: Level 3.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_3_3: Level 3.3. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_4_0: Level 4.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_4_1: Level 4.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_4_2: Level 4.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_4_3: Level 4.3. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_5_0: Level 5.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_5_1: Level 5.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_5_2: Level 5.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_5_3: Level 5.3. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_6_0: Level 6.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_6_1: Level 6.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_6_2: Level 6.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_6_3: Level 6.3. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_7_0: Level 7.0. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_7_1: Level 7.1. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_7_2: Level 7.2. + * @V4L2_MPEG_VIDEO_AV1_LEVEL_7_3: Level 7.3. + * + * Conveys the highest level a decoder can work with. + */ +enum v4l2_mpeg_video_av1_level { + V4L2_MPEG_VIDEO_AV1_LEVEL_2_0 = 0, + V4L2_MPEG_VIDEO_AV1_LEVEL_2_1 = 1, + V4L2_MPEG_VIDEO_AV1_LEVEL_2_2 = 2, + V4L2_MPEG_VIDEO_AV1_LEVEL_2_3 = 3, + + V4L2_MPEG_VIDEO_AV1_LEVEL_3_0 = 4, + V4L2_MPEG_VIDEO_AV1_LEVEL_3_1 = 5, + V4L2_MPEG_VIDEO_AV1_LEVEL_3_2 = 6, + V4L2_MPEG_VIDEO_AV1_LEVEL_3_3 = 7, + + V4L2_MPEG_VIDEO_AV1_LEVEL_4_0 = 8, + V4L2_MPEG_VIDEO_AV1_LEVEL_4_1 = 9, + V4L2_MPEG_VIDEO_AV1_LEVEL_4_2 = 10, + V4L2_MPEG_VIDEO_AV1_LEVEL_4_3 = 11, + + V4L2_MPEG_VIDEO_AV1_LEVEL_5_0 = 12, + V4L2_MPEG_VIDEO_AV1_LEVEL_5_1 = 13, + V4L2_MPEG_VIDEO_AV1_LEVEL_5_2 = 14, + V4L2_MPEG_VIDEO_AV1_LEVEL_5_3 = 15, + + V4L2_MPEG_VIDEO_AV1_LEVEL_6_0 = 16, + V4L2_MPEG_VIDEO_AV1_LEVEL_6_1 = 17, + V4L2_MPEG_VIDEO_AV1_LEVEL_6_2 = 18, + V4L2_MPEG_VIDEO_AV1_LEVEL_6_3 = 19, + + V4L2_MPEG_VIDEO_AV1_LEVEL_7_0 = 20, + V4L2_MPEG_VIDEO_AV1_LEVEL_7_1 = 21, + V4L2_MPEG_VIDEO_AV1_LEVEL_7_2 = 22, + V4L2_MPEG_VIDEO_AV1_LEVEL_7_3 = 23 +}; + /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_CODEC_CX2341X_BASE (V4L2_CTRL_CLASS_CODEC | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_CODEC_CX2341X_BASE+0) @@ -2385,6 +2467,9 @@ struct v4l2_ctrl_hevc_slice_params { * @poc_st_curr_after: provides the index of the short term after references * in DPB array * @poc_lt_curr: provides the index of the long term references in DPB array + * @num_delta_pocs_of_ref_rps_idx: same as the derived value NumDeltaPocs[RefRpsIdx], + * can be used to parse the RPS data in slice headers + * instead of skipping it with @short_term_ref_pic_set_size. * @reserved: padding field. Should be zeroed by applications. * @dpb: the decoded picture buffer, for meta-data about reference frames * @flags: see V4L2_HEVC_DECODE_PARAM_FLAG_{} @@ -2400,7 +2485,8 @@ struct v4l2_ctrl_hevc_decode_params { __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 reserved[4]; + __u8 num_delta_pocs_of_ref_rps_idx; + __u8 reserved[3]; struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u64 flags; }; @@ -2754,6 +2840,645 @@ struct v4l2_ctrl_vp9_compressed_hdr { struct v4l2_vp9_mv_probs mv; }; +/* Stateless AV1 controls */ + +#define V4L2_AV1_TOTAL_REFS_PER_FRAME 8 +#define V4L2_AV1_CDEF_MAX 8 +#define V4L2_AV1_NUM_PLANES_MAX 3 /* 1 if monochrome, 3 otherwise */ +#define V4L2_AV1_MAX_SEGMENTS 8 +#define V4L2_AV1_MAX_OPERATING_POINTS (1 << 5) /* 5 bits to encode */ +#define V4L2_AV1_REFS_PER_FRAME 7 +#define V4L2_AV1_MAX_NUM_Y_POINTS (1 << 4) /* 4 bits to encode */ +#define V4L2_AV1_MAX_NUM_CB_POINTS (1 << 4) /* 4 bits to encode */ +#define V4L2_AV1_MAX_NUM_CR_POINTS (1 << 4) /* 4 bits to encode */ +#define V4L2_AV1_AR_COEFFS_SIZE 25 /* (2 * 3 * (3 + 1)) + 1 */ +#define V4L2_AV1_MAX_NUM_PLANES 3 +#define V4L2_AV1_MAX_TILE_COLS 64 +#define V4L2_AV1_MAX_TILE_ROWS 64 +#define V4L2_AV1_MAX_TILE_COUNT 512 + +#define V4L2_AV1_SEQUENCE_FLAG_STILL_PICTURE 0x00000001 +#define V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK 0x00000002 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_FILTER_INTRA 0x00000004 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_INTRA_EDGE_FILTER 0x00000008 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_INTERINTRA_COMPOUND 0x00000010 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_MASKED_COMPOUND 0x00000020 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_WARPED_MOTION 0x00000040 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_DUAL_FILTER 0x00000080 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_ORDER_HINT 0x00000100 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_JNT_COMP 0x00000200 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_REF_FRAME_MVS 0x00000400 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_SUPERRES 0x00000800 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_CDEF 0x00001000 +#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_RESTORATION 0x00002000 +#define V4L2_AV1_SEQUENCE_FLAG_MONO_CHROME 0x00004000 +#define V4L2_AV1_SEQUENCE_FLAG_COLOR_RANGE 0x00008000 +#define V4L2_AV1_SEQUENCE_FLAG_SUBSAMPLING_X 0x00010000 +#define V4L2_AV1_SEQUENCE_FLAG_SUBSAMPLING_Y 0x00020000 +#define V4L2_AV1_SEQUENCE_FLAG_FILM_GRAIN_PARAMS_PRESENT 0x00040000 +#define V4L2_AV1_SEQUENCE_FLAG_SEPARATE_UV_DELTA_Q 0x00080000 + +#define V4L2_CID_STATELESS_AV1_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE + 500) +/** + * struct v4l2_ctrl_av1_sequence - AV1 Sequence + * + * Represents an AV1 Sequence OBU. See section 5.5 "Sequence header OBU syntax" + * for more details. + * + * @flags: See V4L2_AV1_SEQUENCE_FLAG_{}. + * @seq_profile: specifies the features that can be used in the coded video + * sequence. + * @order_hint_bits: specifies the number of bits used for the order_hint field + * at each frame. + * @bit_depth: the bitdepth to use for the sequence as described in section + * 5.5.2 "Color config syntax". + * @reserved: padding field. Should be zeroed by applications. + * @max_frame_width_minus_1: specifies the maximum frame width minus 1 for the + * frames represented by this sequence header. + * @max_frame_height_minus_1: specifies the maximum frame height minus 1 for the + * frames represented by this sequence header. + */ +struct v4l2_ctrl_av1_sequence { + __u32 flags; + __u8 seq_profile; + __u8 order_hint_bits; + __u8 bit_depth; + __u8 reserved; + __u16 max_frame_width_minus_1; + __u16 max_frame_height_minus_1; +}; + +#define V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY (V4L2_CID_CODEC_STATELESS_BASE + 501) +/** + * struct v4l2_ctrl_av1_tile_group_entry - AV1 Tile Group entry + * + * Represents a single AV1 tile inside an AV1 Tile Group. Note that MiRowStart, + * MiRowEnd, MiColStart and MiColEnd can be retrieved from struct + * v4l2_av1_tile_info in struct v4l2_ctrl_av1_frame using tile_row and + * tile_col. See section 6.10.1 "General tile group OBU semantics" for more + * details. + * + * @tile_offset: offset from the OBU data, i.e. where the coded tile data + * actually starts. + * @tile_size: specifies the size in bytes of the coded tile. Equivalent to + * "TileSize" in the AV1 Specification. + * @tile_row: specifies the row of the current tile. Equivalent to "TileRow" in + * the AV1 Specification. + * @tile_col: specifies the col of the current tile. Equivalent to "TileCol" in + * the AV1 Specification. + */ +struct v4l2_ctrl_av1_tile_group_entry { + __u32 tile_offset; + __u32 tile_size; + __u32 tile_row; + __u32 tile_col; +}; + +/** + * enum v4l2_av1_warp_model - AV1 Warp Model as described in section 3 + * "Symbols and abbreviated terms" of the AV1 Specification. + * + * @V4L2_AV1_WARP_MODEL_IDENTITY: Warp model is just an identity transform. + * @V4L2_AV1_WARP_MODEL_TRANSLATION: Warp model is a pure translation. + * @V4L2_AV1_WARP_MODEL_ROTZOOM: Warp model is a rotation + symmetric zoom + + * translation. + * @V4L2_AV1_WARP_MODEL_AFFINE: Warp model is a general affine transform. + */ +enum v4l2_av1_warp_model { + V4L2_AV1_WARP_MODEL_IDENTITY = 0, + V4L2_AV1_WARP_MODEL_TRANSLATION = 1, + V4L2_AV1_WARP_MODEL_ROTZOOM = 2, + V4L2_AV1_WARP_MODEL_AFFINE = 3, +}; + +/** + * enum v4l2_av1_reference_frame - AV1 reference frames + * + * @V4L2_AV1_REF_INTRA_FRAME: Intra Frame Reference + * @V4L2_AV1_REF_LAST_FRAME: Last Reference Frame + * @V4L2_AV1_REF_LAST2_FRAME: Last2 Reference Frame + * @V4L2_AV1_REF_LAST3_FRAME: Last3 Reference Frame + * @V4L2_AV1_REF_GOLDEN_FRAME: Golden Reference Frame + * @V4L2_AV1_REF_BWDREF_FRAME: BWD Reference Frame + * @V4L2_AV1_REF_ALTREF2_FRAME: Alternative2 Reference Frame + * @V4L2_AV1_REF_ALTREF_FRAME: Alternative Reference Frame + */ +enum v4l2_av1_reference_frame { + V4L2_AV1_REF_INTRA_FRAME = 0, + V4L2_AV1_REF_LAST_FRAME = 1, + V4L2_AV1_REF_LAST2_FRAME = 2, + V4L2_AV1_REF_LAST3_FRAME = 3, + V4L2_AV1_REF_GOLDEN_FRAME = 4, + V4L2_AV1_REF_BWDREF_FRAME = 5, + V4L2_AV1_REF_ALTREF2_FRAME = 6, + V4L2_AV1_REF_ALTREF_FRAME = 7, +}; + +#define V4L2_AV1_GLOBAL_MOTION_IS_INVALID(ref) (1 << (ref)) + +#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_GLOBAL 0x1 +#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_ROT_ZOOM 0x2 +#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_TRANSLATION 0x4 +/** + * struct v4l2_av1_global_motion - AV1 Global Motion parameters as described in + * section 6.8.17 "Global motion params semantics" of the AV1 specification. + * + * @flags: A bitfield containing the flags per reference frame. See + * V4L2_AV1_GLOBAL_MOTION_FLAG_{} + * @type: The type of global motion transform used. + * @params: this field has the same meaning as "gm_params" in the AV1 + * specification. + * @invalid: bitfield indicating whether the global motion params are invalid + * for a given reference frame. See section 7.11.3.6 Setup shear process and + * the variable "warpValid". Use V4L2_AV1_GLOBAL_MOTION_IS_INVALID(ref) to + * create a suitable mask. + * @reserved: padding field. Should be zeroed by applications. + */ + +struct v4l2_av1_global_motion { + __u8 flags[V4L2_AV1_TOTAL_REFS_PER_FRAME]; + enum v4l2_av1_warp_model type[V4L2_AV1_TOTAL_REFS_PER_FRAME]; + __s32 params[V4L2_AV1_TOTAL_REFS_PER_FRAME][6]; + __u8 invalid; + __u8 reserved[3]; +}; + +/** + * enum v4l2_av1_frame_restoration_type - AV1 Frame Restoration Type + * @V4L2_AV1_FRAME_RESTORE_NONE: no filtering is applied. + * @V4L2_AV1_FRAME_RESTORE_WIENER: Wiener filter process is invoked. + * @V4L2_AV1_FRAME_RESTORE_SGRPROJ: self guided filter process is invoked. + * @V4L2_AV1_FRAME_RESTORE_SWITCHABLE: restoration filter is swichtable. + */ +enum v4l2_av1_frame_restoration_type { + V4L2_AV1_FRAME_RESTORE_NONE = 0, + V4L2_AV1_FRAME_RESTORE_WIENER = 1, + V4L2_AV1_FRAME_RESTORE_SGRPROJ = 2, + V4L2_AV1_FRAME_RESTORE_SWITCHABLE = 3, +}; + +#define V4L2_AV1_LOOP_RESTORATION_FLAG_USES_LR 0x1 +#define V4L2_AV1_LOOP_RESTORATION_FLAG_USES_CHROMA_LR 0x2 + +/** + * struct v4l2_av1_loop_restoration - AV1 Loop Restauration as described in + * section 6.10.15 "Loop restoration params semantics" of the AV1 specification. + * + * @flags: See V4L2_AV1_LOOP_RESTORATION_FLAG_{}. + * @lr_unit_shift: specifies if the luma restoration size should be halved. + * @lr_uv_shift: specifies if the chroma size should be half the luma size. + * @reserved: padding field. Should be zeroed by applications. + * @frame_restoration_type: specifies the type of restoration used for each + * plane. See enum v4l2_av1_frame_restoration_type. + * @loop_restoration_size: specifies the size of loop restoration units in units + * of samples in the current plane. + */ +struct v4l2_av1_loop_restoration { + __u8 flags; + __u8 lr_unit_shift; + __u8 lr_uv_shift; + __u8 reserved; + enum v4l2_av1_frame_restoration_type frame_restoration_type[V4L2_AV1_NUM_PLANES_MAX]; + __u32 loop_restoration_size[V4L2_AV1_MAX_NUM_PLANES]; +}; + +/** + * struct v4l2_av1_cdef - AV1 CDEF params semantics as described in section + * 6.10.14 "CDEF params semantics" of the AV1 specification + * + * @damping_minus_3: controls the amount of damping in the deringing filter. + * @bits: specifies the number of bits needed to specify which CDEF filter to + * apply. + * @y_pri_strength: specifies the strength of the primary filter. + * @y_sec_strength: specifies the strength of the secondary filter. + * @uv_pri_strength: specifies the strength of the primary filter. + * @uv_sec_strength: specifies the strength of the secondary filter. + */ +struct v4l2_av1_cdef { + __u8 damping_minus_3; + __u8 bits; + __u8 y_pri_strength[V4L2_AV1_CDEF_MAX]; + __u8 y_sec_strength[V4L2_AV1_CDEF_MAX]; + __u8 uv_pri_strength[V4L2_AV1_CDEF_MAX]; + __u8 uv_sec_strength[V4L2_AV1_CDEF_MAX]; +}; + +#define V4L2_AV1_SEGMENTATION_FLAG_ENABLED 0x1 +#define V4L2_AV1_SEGMENTATION_FLAG_UPDATE_MAP 0x2 +#define V4L2_AV1_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x4 +#define V4L2_AV1_SEGMENTATION_FLAG_UPDATE_DATA 0x8 +#define V4L2_AV1_SEGMENTATION_FLAG_SEG_ID_PRE_SKIP 0x10 + +/** + * enum v4l2_av1_segment_feature - AV1 segment features as described in section + * 3 "Symbols and abbreviated terms" of the AV1 specification. + * + * @V4L2_AV1_SEG_LVL_ALT_Q: Index for quantizer segment feature. + * @V4L2_AV1_SEG_LVL_ALT_LF_Y_V: Index for vertical luma loop filter segment + * feature. + * @V4L2_AV1_SEG_LVL_REF_FRAME: Index for reference frame segment feature. + * @V4L2_AV1_SEG_LVL_REF_SKIP: Index for skip segment feature. + * @V4L2_AV1_SEG_LVL_REF_GLOBALMV: Index for global mv feature. + * @V4L2_AV1_SEG_LVL_MAX: Number of segment features. + */ +enum v4l2_av1_segment_feature { + V4L2_AV1_SEG_LVL_ALT_Q = 0, + V4L2_AV1_SEG_LVL_ALT_LF_Y_V = 1, + V4L2_AV1_SEG_LVL_REF_FRAME = 5, + V4L2_AV1_SEG_LVL_REF_SKIP = 6, + V4L2_AV1_SEG_LVL_REF_GLOBALMV = 7, + V4L2_AV1_SEG_LVL_MAX = 8 +}; + +#define V4L2_AV1_SEGMENT_FEATURE_ENABLED(id) (1 << (id)) + +/** + * struct v4l2_av1_segmentation - AV1 Segmentation params as defined in section + * 6.8.13 "Segmentation params semantics" of the AV1 specification. + * + * @flags: see V4L2_AV1_SEGMENTATION_FLAG_{}. + * @last_active_seg_id: indicates the highest numbered segment id that has some + * enabled feature. This is used when decoding the segment id to only decode + * choices corresponding to used segments. + * @feature_enabled: bitmask defining which features are enabled in each + * segment. Use V4L2_AV1_SEGMENT_FEATURE_ENABLED to build a suitable mask. + * @feature_data: data attached to each feature. Data entry is only valid if the + * feature is enabled + */ +struct v4l2_av1_segmentation { + __u8 flags; + __u8 last_active_seg_id; + __u8 feature_enabled[V4L2_AV1_MAX_SEGMENTS]; + __s16 feature_data[V4L2_AV1_MAX_SEGMENTS][V4L2_AV1_SEG_LVL_MAX]; +}; + +#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1 +#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2 +#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_PRESENT 0x4 +#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_MULTI 0x8 + +/** + * struct v4l2_av1_loop_filter - AV1 Loop filter params as defined in section + * 6.8.10 "Loop filter semantics" and 6.8.16 "Loop filter delta parameters + * semantics" of the AV1 specification. + * + * @flags: see V4L2_AV1_LOOP_FILTER_FLAG_{} + * @level: an array containing loop filter strength values. Different loop + * filter strength values from the array are used depending on the image plane + * being filtered, and the edge direction (vertical or horizontal) being + * filtered. + * @sharpness: indicates the sharpness level. The loop_filter_level and + * loop_filter_sharpness together determine when a block edge is filtered, and + * by how much the filtering can change the sample values. The loop filter + * process is described in section 7.14 of the AV1 specification. + * @ref_deltas: contains the adjustment needed for the filter level based on the + * chosen reference frame. If this syntax element is not present, it maintains + * its previous value. + * @mode_deltas: contains the adjustment needed for the filter level based on + * the chosen mode. If this syntax element is not present, it maintains its + * previous value. + * @delta_lf_res: specifies the left shift which should be applied to decoded + * loop filter delta values. + */ +struct v4l2_av1_loop_filter { + __u8 flags; + __u8 level[4]; + __u8 sharpness; + __s8 ref_deltas[V4L2_AV1_TOTAL_REFS_PER_FRAME]; + __s8 mode_deltas[2]; + __u8 delta_lf_res; +}; + +#define V4L2_AV1_QUANTIZATION_FLAG_DIFF_UV_DELTA 0x1 +#define V4L2_AV1_QUANTIZATION_FLAG_USING_QMATRIX 0x2 +#define V4L2_AV1_QUANTIZATION_FLAG_DELTA_Q_PRESENT 0x4 + +/** + * struct v4l2_av1_quantization - AV1 Quantization params as defined in section + * 6.8.11 "Quantization params semantics" of the AV1 specification. + * + * @flags: see V4L2_AV1_QUANTIZATION_FLAG_{} + * @base_q_idx: indicates the base frame qindex. This is used for Y AC + * coefficients and as the base value for the other quantizers. + * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx. + * @delta_q_u_dc: indicates the U DC quantizer relative to base_q_idx. + * @delta_q_u_ac: indicates the U AC quantizer relative to base_q_idx. + * @delta_q_v_dc: indicates the V DC quantizer relative to base_q_idx. + * @delta_q_v_ac: indicates the V AC quantizer relative to base_q_idx. + * @qm_y: specifies the level in the quantizer matrix that should be used for + * luma plane decoding. + * @qm_u: specifies the level in the quantizer matrix that should be used for + * chroma U plane decoding. + * @qm_v: specifies the level in the quantizer matrix that should be used for + * chroma V plane decoding. + * @delta_q_res: specifies the left shift which should be applied to decoded + * quantizer index delta values. + */ +struct v4l2_av1_quantization { + __u8 flags; + __u8 base_q_idx; + __s8 delta_q_y_dc; + __s8 delta_q_u_dc; + __s8 delta_q_u_ac; + __s8 delta_q_v_dc; + __s8 delta_q_v_ac; + __u8 qm_y; + __u8 qm_u; + __u8 qm_v; + __u8 delta_q_res; +}; + +#define V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING 0x1 + +/** + * struct v4l2_av1_tile_info - AV1 Tile info as defined in section 6.8.14 "Tile + * info semantics" of the AV1 specification. + * + * @flags: see V4L2_AV1_TILE_INFO_FLAG_{} + * @context_update_tile_id: specifies which tile to use for the CDF update. + * @tile_rows: specifies the number of tiles down the frame. + * @tile_cols: specifies the number of tiles across the frame. + * @mi_col_starts: an array specifying the start column (in units of 4x4 luma + * samples) for each tile across the image. + * @mi_row_starts: an array specifying the start row (in units of 4x4 luma + * samples) for each tile down the image. + * @width_in_sbs_minus_1: specifies the width of a tile minus 1 in units of + * superblocks. + * @height_in_sbs_minus_1: specifies the height of a tile minus 1 in units of + * superblocks. + * @tile_size_bytes: specifies the number of bytes needed to code each tile + * size. + * @reserved: padding field. Should be zeroed by applications. + */ +struct v4l2_av1_tile_info { + __u8 flags; + __u8 context_update_tile_id; + __u8 tile_cols; + __u8 tile_rows; + __u32 mi_col_starts[V4L2_AV1_MAX_TILE_COLS + 1]; + __u32 mi_row_starts[V4L2_AV1_MAX_TILE_ROWS + 1]; + __u32 width_in_sbs_minus_1[V4L2_AV1_MAX_TILE_COLS]; + __u32 height_in_sbs_minus_1[V4L2_AV1_MAX_TILE_ROWS]; + __u8 tile_size_bytes; + __u8 reserved[3]; +}; + +/** + * enum v4l2_av1_frame_type - AV1 Frame Type + * + * @V4L2_AV1_KEY_FRAME: Key frame + * @V4L2_AV1_INTER_FRAME: Inter frame + * @V4L2_AV1_INTRA_ONLY_FRAME: Intra-only frame + * @V4L2_AV1_SWITCH_FRAME: Switch frame + */ +enum v4l2_av1_frame_type { + V4L2_AV1_KEY_FRAME = 0, + V4L2_AV1_INTER_FRAME = 1, + V4L2_AV1_INTRA_ONLY_FRAME = 2, + V4L2_AV1_SWITCH_FRAME = 3 +}; + +/** + * enum v4l2_av1_interpolation_filter - AV1 interpolation filter types + * + * @V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP: eight tap filter + * @V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH: eight tap smooth filter + * @V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP: eight tap sharp filter + * @V4L2_AV1_INTERPOLATION_FILTER_BILINEAR: bilinear filter + * @V4L2_AV1_INTERPOLATION_FILTER_SWITCHABLE: filter selection is signaled at + * the block level + * + * See section 6.8.9 "Interpolation filter semantics" of the AV1 specification + * for more details. + */ +enum v4l2_av1_interpolation_filter { + V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP = 0, + V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH = 1, + V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP = 2, + V4L2_AV1_INTERPOLATION_FILTER_BILINEAR = 3, + V4L2_AV1_INTERPOLATION_FILTER_SWITCHABLE = 4, +}; + +/** + * enum v4l2_av1_tx_mode - AV1 Tx mode as described in section 6.8.21 "TX mode + * semantics" of the AV1 specification. + * @V4L2_AV1_TX_MODE_ONLY_4X4: the inverse transform will use only 4x4 + * transforms + * @V4L2_AV1_TX_MODE_LARGEST: the inverse transform will use the largest + * transform size that fits inside the block + * @V4L2_AV1_TX_MODE_SELECT: the choice of transform size is specified + * explicitly for each block. + */ +enum v4l2_av1_tx_mode { + V4L2_AV1_TX_MODE_ONLY_4X4 = 0, + V4L2_AV1_TX_MODE_LARGEST = 1, + V4L2_AV1_TX_MODE_SELECT = 2 +}; + +#define V4L2_AV1_FRAME_FLAG_SHOW_FRAME 0x00000001 +#define V4L2_AV1_FRAME_FLAG_SHOWABLE_FRAME 0x00000002 +#define V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE 0x00000004 +#define V4L2_AV1_FRAME_FLAG_DISABLE_CDF_UPDATE 0x00000008 +#define V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS 0x00000010 +#define V4L2_AV1_FRAME_FLAG_FORCE_INTEGER_MV 0x00000020 +#define V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC 0x00000040 +#define V4L2_AV1_FRAME_FLAG_USE_SUPERRES 0x00000080 +#define V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV 0x00000100 +#define V4L2_AV1_FRAME_FLAG_IS_MOTION_MODE_SWITCHABLE 0x00000200 +#define V4L2_AV1_FRAME_FLAG_USE_REF_FRAME_MVS 0x00000400 +#define V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF 0x00000800 +#define V4L2_AV1_FRAME_FLAG_ALLOW_WARPED_MOTION 0x00001000 +#define V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT 0x00002000 +#define V4L2_AV1_FRAME_FLAG_REDUCED_TX_SET 0x00004000 +#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_ALLOWED 0x00008000 +#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_PRESENT 0x00010000 +#define V4L2_AV1_FRAME_FLAG_FRAME_SIZE_OVERRIDE 0x00020000 +#define V4L2_AV1_FRAME_FLAG_BUFFER_REMOVAL_TIME_PRESENT 0x00040000 +#define V4L2_AV1_FRAME_FLAG_FRAME_REFS_SHORT_SIGNALING 0x00080000 + +#define V4L2_CID_STATELESS_AV1_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 502) +/** + * struct v4l2_ctrl_av1_frame - Represents an AV1 Frame Header OBU. + * + * @tile_info: tile info + * @quantization: quantization params + * @segmentation: segmentation params + * @superres_denom: the denominator for the upscaling ratio. + * @loop_filter: loop filter params + * @cdef: cdef params + * @skip_mode_frame: specifies the frames to use for compound prediction when + * skip_mode is equal to 1. + * @primary_ref_frame: specifies which reference frame contains the CDF values + * and other state that should be loaded at the start of the frame. + * @loop_restoration: loop restoration params + * @global_motion: global motion params + * @flags: see V4L2_AV1_FRAME_FLAG_{} + * @frame_type: specifies the AV1 frame type + * @order_hint: specifies OrderHintBits least significant bits of the expected + * output order for this frame. + * @upscaled_width: the upscaled width. + * @interpolation_filter: specifies the filter selection used for performing + * inter prediction. + * @tx_mode: specifies how the transform size is determined. + * @frame_width_minus_1: add 1 to get the frame's width. + * @frame_height_minus_1: add 1 to get the frame's height + * @render_width_minus_1: add 1 to get the render width of the frame in luma + * samples. + * @render_height_minus_1: add 1 to get the render height of the frame in luma + * samples. + * @current_frame_id: specifies the frame id number for the current frame. Frame + * id numbers are additional information that do not affect the decoding + * process, but provide decoders with a way of detecting missing reference + * frames so that appropriate action can be taken. + * @buffer_removal_time: specifies the frame removal time in units of DecCT clock + * ticks counted from the removal time of the last random access point for + * operating point opNum. + * @reserved: padding field. Should be zeroed by applications. + * @order_hints: specifies the expected output order hint for each reference + * frame. This field corresponds to the OrderHints variable from the + * specification (section 5.9.2 "Uncompressed header syntax"). As such, this is + * only used for non-intra frames and ignored otherwise. order_hints[0] is + * always ignored. + * @reference_frame_ts: the V4L2 timestamp of the reference frame slots. + * @ref_frame_idx: used to index into @reference_frame_ts when decoding + * inter-frames. The meaning of this array is the same as in the specification. + * The timestamp refers to the timestamp field in struct v4l2_buffer. Use + * v4l2_timeval_to_ns() to convert the struct timeval to a __u64. + * @refresh_frame_flags: contains a bitmask that specifies which reference frame + * slots will be updated with the current frame after it is decoded. + */ +struct v4l2_ctrl_av1_frame { + struct v4l2_av1_tile_info tile_info; + struct v4l2_av1_quantization quantization; + __u8 superres_denom; + struct v4l2_av1_segmentation segmentation; + struct v4l2_av1_loop_filter loop_filter; + struct v4l2_av1_cdef cdef; + __u8 skip_mode_frame[2]; + __u8 primary_ref_frame; + struct v4l2_av1_loop_restoration loop_restoration; + struct v4l2_av1_global_motion global_motion; + __u32 flags; + enum v4l2_av1_frame_type frame_type; + __u32 order_hint; + __u32 upscaled_width; + enum v4l2_av1_interpolation_filter interpolation_filter; + enum v4l2_av1_tx_mode tx_mode; + __u32 frame_width_minus_1; + __u32 frame_height_minus_1; + __u16 render_width_minus_1; + __u16 render_height_minus_1; + + __u32 current_frame_id; + __u32 buffer_removal_time[V4L2_AV1_MAX_OPERATING_POINTS]; + __u8 reserved[4]; + __u32 order_hints[V4L2_AV1_TOTAL_REFS_PER_FRAME]; + __u64 reference_frame_ts[V4L2_AV1_TOTAL_REFS_PER_FRAME]; + __s8 ref_frame_idx[V4L2_AV1_REFS_PER_FRAME]; + __u8 refresh_frame_flags; +}; + +#define V4L2_AV1_FILM_GRAIN_FLAG_APPLY_GRAIN 0x1 +#define V4L2_AV1_FILM_GRAIN_FLAG_UPDATE_GRAIN 0x2 +#define V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA 0x4 +#define V4L2_AV1_FILM_GRAIN_FLAG_OVERLAP 0x8 +#define V4L2_AV1_FILM_GRAIN_FLAG_CLIP_TO_RESTRICTED_RANGE 0x10 + +#define V4L2_CID_STATELESS_AV1_FILM_GRAIN (V4L2_CID_CODEC_STATELESS_BASE + 505) +/** + * struct v4l2_ctrl_av1_film_grain - AV1 Film Grain parameters. + * + * Film grain parameters as specified by section 6.8.20 of the AV1 Specification. + * + * @flags: see V4L2_AV1_FILM_GRAIN_{}. + * @cr_mult: represents a multiplier for the cr component used in derivation of + * the input index to the cr component scaling function. + * @grain_seed: specifies the starting value for the pseudo-random numbers used + * during film grain synthesis. + * @film_grain_params_ref_idx: indicates which reference frame contains the + * film grain parameters to be used for this frame. + * @num_y_points: specifies the number of points for the piece-wise linear + * scaling function of the luma component. + * @point_y_value: represents the x (luma value) coordinate for the i-th point + * of the piecewise linear scaling function for luma component. The values are + * signaled on the scale of 0..255. In case of 10 bit video, these values + * correspond to luma values divided by 4. In case of 12 bit video, these values + * correspond to luma values divided by 16. + * @point_y_scaling: represents the scaling (output) value for the i-th point + * of the piecewise linear scaling function for luma component. + * @num_cb_points: specifies the number of points for the piece-wise linear + * scaling function of the cb component. + * @point_cb_value: represents the x coordinate for the i-th point of the + * piece-wise linear scaling function for cb component. The values are signaled + * on the scale of 0..255. + * @point_cb_scaling: represents the scaling (output) value for the i-th point + * of the piecewise linear scaling function for cb component. + * @num_cr_points: specifies represents the number of points for the piece-wise + * linear scaling function of the cr component. + * @point_cr_value: represents the x coordinate for the i-th point of the + * piece-wise linear scaling function for cr component. The values are signaled + * on the scale of 0..255. + * @point_cr_scaling: represents the scaling (output) value for the i-th point + * of the piecewise linear scaling function for cr component. + * @grain_scaling_minus_8: represents the shift – 8 applied to the values of the + * chroma component. The grain_scaling_minus_8 can take values of 0..3 and + * determines the range and quantization step of the standard deviation of film + * grain. + * @ar_coeff_lag: specifies the number of auto-regressive coefficients for luma + * and chroma. + * @ar_coeffs_y_plus_128: specifies auto-regressive coefficients used for the Y + * plane. + * @ar_coeffs_cb_plus_128: specifies auto-regressive coefficients used for the U + * plane. + * @ar_coeffs_cr_plus_128: specifies auto-regressive coefficients used for the V + * plane. + * @ar_coeff_shift_minus_6: specifies the range of the auto-regressive + * coefficients. Values of 0, 1, 2, and 3 correspond to the ranges for + * auto-regressive coefficients of [-2, 2), [-1, 1), [-0.5, 0.5) and [-0.25, + * 0.25) respectively. + * @grain_scale_shift: specifies how much the Gaussian random numbers should be + * scaled down during the grain synthesis process. + * @cb_mult: represents a multiplier for the cb component used in derivation of + * the input index to the cb component scaling function. + * @cb_luma_mult: represents a multiplier for the average luma component used in + * derivation of the input index to the cb component scaling function. + * @cr_luma_mult: represents a multiplier for the average luma component used in + * derivation of the input index to the cr component scaling function. + * @cb_offset: represents an offset used in derivation of the input index to the + * cb component scaling function. + * @cr_offset: represents an offset used in derivation of the input index to the + * cr component scaling function. + * @reserved: padding field. Should be zeroed by applications. + */ +struct v4l2_ctrl_av1_film_grain { + __u8 flags; + __u8 cr_mult; + __u16 grain_seed; + __u8 film_grain_params_ref_idx; + __u8 num_y_points; + __u8 point_y_value[V4L2_AV1_MAX_NUM_Y_POINTS]; + __u8 point_y_scaling[V4L2_AV1_MAX_NUM_Y_POINTS]; + __u8 num_cb_points; + __u8 point_cb_value[V4L2_AV1_MAX_NUM_CB_POINTS]; + __u8 point_cb_scaling[V4L2_AV1_MAX_NUM_CB_POINTS]; + __u8 num_cr_points; + __u8 point_cr_value[V4L2_AV1_MAX_NUM_CR_POINTS]; + __u8 point_cr_scaling[V4L2_AV1_MAX_NUM_CR_POINTS]; + __u8 grain_scaling_minus_8; + __u8 ar_coeff_lag; + __u8 ar_coeffs_y_plus_128[V4L2_AV1_AR_COEFFS_SIZE]; + __u8 ar_coeffs_cb_plus_128[V4L2_AV1_AR_COEFFS_SIZE]; + __u8 ar_coeffs_cr_plus_128[V4L2_AV1_AR_COEFFS_SIZE]; + __u8 ar_coeff_shift_minus_6; + __u8 grain_scale_shift; + __u8 cb_mult; + __u8 cb_luma_mult; + __u8 cr_luma_mult; + __u16 cb_offset; + __u16 cr_offset; + __u8 reserved[4]; +}; + /* MPEG-compression definitions kept for backwards compatibility */ #ifndef __KERNEL__ #define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 0552e8dcf0cb..20c804bdc09c 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -213,6 +213,7 @@ struct vfio_device_info { #define VFIO_DEVICE_FLAGS_AP (1 << 5) /* vfio-ap device */ #define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6) /* vfio-fsl-mc device */ #define VFIO_DEVICE_FLAGS_CAPS (1 << 7) /* Info supports caps */ +#define VFIO_DEVICE_FLAGS_CDX (1 << 8) /* vfio-cdx device */ __u32 num_regions; /* Max region index + 1 */ __u32 num_irqs; /* Max IRQ index + 1 */ __u32 cap_offset; /* Offset within info struct of first cap */ @@ -240,6 +241,20 @@ struct vfio_device_info { #define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3 #define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4 +/* + * The following VFIO_DEVICE_INFO capability reports support for PCIe AtomicOp + * completion to the root bus with supported widths provided via flags. + */ +#define VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP 5 +struct vfio_device_info_cap_pci_atomic_comp { + struct vfio_info_cap_header header; + __u32 flags; +#define VFIO_PCI_ATOMIC_COMP32 (1 << 0) +#define VFIO_PCI_ATOMIC_COMP64 (1 << 1) +#define VFIO_PCI_ATOMIC_COMP128 (1 << 2) + __u32 reserved; +}; + /** * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8, * struct vfio_region_info) @@ -511,6 +526,9 @@ struct vfio_region_info_cap_nvlink2_lnkspd { * then add and unmask vectors, it's up to userspace to make the decision * whether to allocate the maximum supported number of vectors or tear * down setup and incrementally increase the vectors as each is enabled. + * Absence of the NORESIZE flag indicates that vectors can be enabled + * and disabled dynamically without impacting other vectors within the + * index. */ struct vfio_irq_info { __u32 argsz; @@ -646,6 +664,15 @@ enum { VFIO_CCW_NUM_IRQS }; +/* + * The vfio-ap bus driver makes use of the following IRQ index mapping. + * Unimplemented IRQ types return a count of zero. + */ +enum { + VFIO_AP_REQ_IRQ_INDEX, + VFIO_AP_NUM_IRQS +}; + /** * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 12, * struct vfio_pci_hot_reset_info) diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index 92e1b700b51c..f5c48b61ab62 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -45,6 +45,25 @@ #define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64) /* Specify an eventfd file descriptor to signal on log write. */ #define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int) +/* By default, a device gets one vhost_worker that its virtqueues share. This + * command allows the owner of the device to create an additional vhost_worker + * for the device. It can later be bound to 1 or more of its virtqueues using + * the VHOST_ATTACH_VRING_WORKER command. + * + * This must be called after VHOST_SET_OWNER and the caller must be the owner + * of the device. The new thread will inherit caller's cgroups and namespaces, + * and will share the caller's memory space. The new thread will also be + * counted against the caller's RLIMIT_NPROC value. + * + * The worker's ID used in other commands will be returned in + * vhost_worker_state. + */ +#define VHOST_NEW_WORKER _IOR(VHOST_VIRTIO, 0x8, struct vhost_worker_state) +/* Free a worker created with VHOST_NEW_WORKER if it's not attached to any + * virtqueue. If userspace is not able to call this for workers its created, + * the kernel will free all the device's workers when the device is closed. + */ +#define VHOST_FREE_WORKER _IOW(VHOST_VIRTIO, 0x9, struct vhost_worker_state) /* Ring setup. */ /* Set number of descriptors in ring. This parameter can not @@ -70,6 +89,18 @@ #define VHOST_VRING_BIG_ENDIAN 1 #define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state) #define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state) +/* Attach a vhost_worker created with VHOST_NEW_WORKER to one of the device's + * virtqueues. + * + * This will replace the virtqueue's existing worker. If the replaced worker + * is no longer attached to any virtqueues, it can be freed with + * VHOST_FREE_WORKER. + */ +#define VHOST_ATTACH_VRING_WORKER _IOW(VHOST_VIRTIO, 0x15, \ + struct vhost_vring_worker) +/* Return the vring worker's ID */ +#define VHOST_GET_VRING_WORKER _IOWR(VHOST_VIRTIO, 0x16, \ + struct vhost_vring_worker) /* The following ioctls use eventfd file descriptors to signal and poll * for events. */ diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h index c5690a8992d8..d3aad12ad1fa 100644 --- a/include/uapi/linux/vhost_types.h +++ b/include/uapi/linux/vhost_types.h @@ -47,6 +47,22 @@ struct vhost_vring_addr { __u64 log_guest_addr; }; +struct vhost_worker_state { + /* + * For VHOST_NEW_WORKER the kernel will return the new vhost_worker id. + * For VHOST_FREE_WORKER this must be set to the id of the vhost_worker + * to free. + */ + unsigned int worker_id; +}; + +struct vhost_vring_worker { + /* vring index */ + unsigned int index; + /* The id of the vhost_worker returned from VHOST_NEW_WORKER */ + unsigned int worker_id; +}; + /* no alignment requirement */ struct vhost_iotlb_msg { __u64 iova; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index aee75eb9e686..3af6a82d0cad 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -672,6 +672,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_NV12_4L4 v4l2_fourcc('V', 'T', '1', '2') /* 12 Y/CbCr 4:2:0 4x4 tiles */ #define V4L2_PIX_FMT_NV12_16L16 v4l2_fourcc('H', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 tiles */ #define V4L2_PIX_FMT_NV12_32L32 v4l2_fourcc('S', 'T', '1', '2') /* 12 Y/CbCr 4:2:0 32x32 tiles */ +#define V4L2_PIX_FMT_NV15_4L4 v4l2_fourcc('V', 'T', '1', '5') /* 15 Y/CbCr 4:2:0 10-bit 4x4 tiles */ #define V4L2_PIX_FMT_P010_4L4 v4l2_fourcc('T', '0', '1', '0') /* 12 Y/CbCr 4:2:0 10-bit 4x4 macroblocks */ #define V4L2_PIX_FMT_NV12_8L128 v4l2_fourcc('A', 'T', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */ #define V4L2_PIX_FMT_NV12_10BE_8L128 v4l2_fourcc_be('A', 'X', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */ @@ -758,6 +759,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */ #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ #define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */ +#define V4L2_PIX_FMT_AV1_FRAME v4l2_fourcc('A', 'V', '1', 'F') /* AV1 parsed frame */ #define V4L2_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0') /* Sorenson Spark */ #define V4L2_PIX_FMT_RV30 v4l2_fourcc('R', 'V', '3', '0') /* RealVideo 8 */ #define V4L2_PIX_FMT_RV40 v4l2_fourcc('R', 'V', '4', '0') /* RealVideo 9 & 10 */ @@ -1720,7 +1722,7 @@ struct v4l2_input { __u8 name[32]; /* Label */ __u32 type; /* Type of input */ __u32 audioset; /* Associated audios (bitfield) */ - __u32 tuner; /* enum v4l2_tuner_type */ + __u32 tuner; /* Tuner index */ v4l2_std_id std; __u32 status; __u32 capabilities; @@ -1807,8 +1809,8 @@ struct v4l2_ext_control { __u8 __user *p_u8; __u16 __user *p_u16; __u32 __user *p_u32; - __u32 __user *p_s32; - __u32 __user *p_s64; + __s32 __user *p_s32; + __s64 __user *p_s64; struct v4l2_area __user *p_area; struct v4l2_ctrl_h264_sps __user *p_h264_sps; struct v4l2_ctrl_h264_pps *p_h264_pps; @@ -1828,6 +1830,10 @@ struct v4l2_ext_control { struct v4l2_ctrl_hevc_slice_params __user *p_hevc_slice_params; struct v4l2_ctrl_hevc_scaling_matrix __user *p_hevc_scaling_matrix; struct v4l2_ctrl_hevc_decode_params __user *p_hevc_decode_params; + struct v4l2_ctrl_av1_sequence __user *p_av1_sequence; + struct v4l2_ctrl_av1_tile_group_entry __user *p_av1_tile_group_entry; + struct v4l2_ctrl_av1_frame __user *p_av1_frame; + struct v4l2_ctrl_av1_film_grain __user *p_av1_film_grain; void __user *ptr; }; } __attribute__ ((packed)); @@ -1901,6 +1907,11 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272, V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273, V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274, + + V4L2_CTRL_TYPE_AV1_SEQUENCE = 0x280, + V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY = 0x281, + V4L2_CTRL_TYPE_AV1_FRAME = 0x282, + V4L2_CTRL_TYPE_AV1_FILM_GRAIN = 0x283, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h index 08967b3f19c8..3c2ad5fae17f 100644 --- a/include/uapi/linux/wireless.h +++ b/include/uapi/linux/wireless.h @@ -835,7 +835,7 @@ struct iw_encode_ext { * individual keys */ __u16 alg; /* IW_ENCODE_ALG_* */ __u16 key_len; - __u8 key[0]; + __u8 key[]; }; /* SIOCSIWMLME data */ diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h index c4e90775da0c..8a2a1d4f6b29 100644 --- a/include/uapi/rdma/bnxt_re-abi.h +++ b/include/uapi/rdma/bnxt_re-abi.h @@ -41,6 +41,7 @@ #define __BNXT_RE_UVERBS_ABI_H__ #include <linux/types.h> +#include <rdma/ib_user_ioctl_cmds.h> #define BNXT_RE_ABI_VERSION 1 @@ -51,6 +52,7 @@ enum { BNXT_RE_UCNTX_CMASK_HAVE_CCTX = 0x1ULL, BNXT_RE_UCNTX_CMASK_HAVE_MODE = 0x02ULL, + BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED = 0x04ULL, }; enum bnxt_re_wqe_mode { @@ -127,4 +129,29 @@ enum bnxt_re_shpg_offt { BNXT_RE_END_RESV_OFFT = 0xFF0 }; +enum bnxt_re_objects { + BNXT_RE_OBJECT_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum bnxt_re_alloc_page_type { + BNXT_RE_ALLOC_WC_PAGE = 0, +}; + +enum bnxt_re_var_alloc_page_attrs { + BNXT_RE_ALLOC_PAGE_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + BNXT_RE_ALLOC_PAGE_TYPE, + BNXT_RE_ALLOC_PAGE_DPI, + BNXT_RE_ALLOC_PAGE_MMAP_OFFSET, + BNXT_RE_ALLOC_PAGE_MMAP_LENGTH, +}; + +enum bnxt_re_alloc_page_attrs { + BNXT_RE_DESTROY_PAGE_HANDLE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum bnxt_re_alloc_page_methods { + BNXT_RE_METHOD_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT), + BNXT_RE_METHOD_DESTROY_PAGE, +}; + #endif /* __BNXT_RE_UVERBS_ABI_H__*/ diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h index 00d2703e8fca..b5bc8604efe8 100644 --- a/include/uapi/sound/asequencer.h +++ b/include/uapi/sound/asequencer.h @@ -10,7 +10,7 @@ #include <sound/asound.h> /** version of the sequencer */ -#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 2) +#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 3) /** * definition of sequencer event types @@ -174,6 +174,7 @@ struct snd_seq_connect { #define SNDRV_SEQ_PRIORITY_HIGH (1<<4) /* event should be processed before others */ #define SNDRV_SEQ_PRIORITY_MASK (1<<4) +#define SNDRV_SEQ_EVENT_UMP (1<<5) /* event holds a UMP packet */ /* note event */ struct snd_seq_ev_note { @@ -252,6 +253,19 @@ struct snd_seq_ev_quote { struct snd_seq_event *event; /* quoted event */ } __attribute__((packed)); +union snd_seq_event_data { /* event data... */ + struct snd_seq_ev_note note; + struct snd_seq_ev_ctrl control; + struct snd_seq_ev_raw8 raw8; + struct snd_seq_ev_raw32 raw32; + struct snd_seq_ev_ext ext; + struct snd_seq_ev_queue_control queue; + union snd_seq_timestamp time; + struct snd_seq_addr addr; + struct snd_seq_connect connect; + struct snd_seq_result result; + struct snd_seq_ev_quote quote; +}; /* sequencer event */ struct snd_seq_event { @@ -262,25 +276,27 @@ struct snd_seq_event { unsigned char queue; /* schedule queue */ union snd_seq_timestamp time; /* schedule time */ - struct snd_seq_addr source; /* source address */ struct snd_seq_addr dest; /* destination address */ - union { /* event data... */ - struct snd_seq_ev_note note; - struct snd_seq_ev_ctrl control; - struct snd_seq_ev_raw8 raw8; - struct snd_seq_ev_raw32 raw32; - struct snd_seq_ev_ext ext; - struct snd_seq_ev_queue_control queue; - union snd_seq_timestamp time; - struct snd_seq_addr addr; - struct snd_seq_connect connect; - struct snd_seq_result result; - struct snd_seq_ev_quote quote; - } data; + union snd_seq_event_data data; }; + /* (compatible) event for UMP-capable clients */ +struct snd_seq_ump_event { + snd_seq_event_type_t type; /* event type */ + unsigned char flags; /* event flags */ + char tag; + unsigned char queue; /* schedule queue */ + union snd_seq_timestamp time; /* schedule time */ + struct snd_seq_addr source; /* source address */ + struct snd_seq_addr dest; /* destination address */ + + union { + union snd_seq_event_data data; + unsigned int ump[4]; + }; +}; /* * bounce event - stored as variable size data @@ -331,6 +347,7 @@ typedef int __bitwise snd_seq_client_type_t; #define SNDRV_SEQ_FILTER_BROADCAST (1U<<0) /* accept broadcast messages */ #define SNDRV_SEQ_FILTER_MULTICAST (1U<<1) /* accept multicast messages */ #define SNDRV_SEQ_FILTER_BOUNCE (1U<<2) /* accept bounce event in error */ +#define SNDRV_SEQ_FILTER_NO_CONVERT (1U<<30) /* don't convert UMP events */ #define SNDRV_SEQ_FILTER_USE_EVENT (1U<<31) /* use event filter */ struct snd_seq_client_info { @@ -344,9 +361,18 @@ struct snd_seq_client_info { int event_lost; /* number of lost events */ int card; /* RO: card number[kernel] */ int pid; /* RO: pid[user] */ - char reserved[56]; /* for future use */ + unsigned int midi_version; /* MIDI version */ + unsigned int group_filter; /* UMP group filter bitmap + * (bit 0 = groupless messages, + * bit 1-16 = messages for groups 1-16) + */ + char reserved[48]; /* for future use */ }; +/* MIDI version numbers in client info */ +#define SNDRV_SEQ_CLIENT_LEGACY_MIDI 0 /* Legacy client */ +#define SNDRV_SEQ_CLIENT_UMP_MIDI_1_0 1 /* UMP MIDI 1.0 */ +#define SNDRV_SEQ_CLIENT_UMP_MIDI_2_0 2 /* UMP MIDI 2.0 */ /* client pool size */ struct snd_seq_client_pool { @@ -406,6 +432,8 @@ struct snd_seq_remove_events { #define SNDRV_SEQ_PORT_CAP_SUBS_READ (1<<5) /* allow read subscription */ #define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /* allow write subscription */ #define SNDRV_SEQ_PORT_CAP_NO_EXPORT (1<<7) /* routing not allowed */ +#define SNDRV_SEQ_PORT_CAP_INACTIVE (1<<8) /* inactive port */ +#define SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT (1<<9) /* MIDI 2.0 UMP Endpoint port */ /* port type */ #define SNDRV_SEQ_PORT_TYPE_SPECIFIC (1<<0) /* hardware specific */ @@ -415,6 +443,7 @@ struct snd_seq_remove_events { #define SNDRV_SEQ_PORT_TYPE_MIDI_XG (1<<4) /* XG compatible device */ #define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /* MT-32 compatible device */ #define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1<<6) /* General MIDI 2 compatible device */ +#define SNDRV_SEQ_PORT_TYPE_MIDI_UMP (1<<7) /* UMP */ /* other standards...*/ #define SNDRV_SEQ_PORT_TYPE_SYNTH (1<<10) /* Synth device (no MIDI compatible - direct wavetable) */ @@ -432,6 +461,12 @@ struct snd_seq_remove_events { #define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1<<1) #define SNDRV_SEQ_PORT_FLG_TIME_REAL (1<<2) +/* port direction */ +#define SNDRV_SEQ_PORT_DIR_UNKNOWN 0 +#define SNDRV_SEQ_PORT_DIR_INPUT 1 +#define SNDRV_SEQ_PORT_DIR_OUTPUT 2 +#define SNDRV_SEQ_PORT_DIR_BIDIRECTION 3 + struct snd_seq_port_info { struct snd_seq_addr addr; /* client/port numbers */ char name[64]; /* port name */ @@ -448,7 +483,9 @@ struct snd_seq_port_info { void *kernel; /* reserved for kernel use (must be NULL) */ unsigned int flags; /* misc. conditioning */ unsigned char time_queue; /* queue # for timestamping */ - char reserved[59]; /* for future use */ + unsigned char direction; /* port usage direction (r/w/bidir) */ + unsigned char ump_group; /* 0 = UMP EP (no conversion), 1-16 = UMP group number */ + char reserved[57]; /* for future use */ }; @@ -552,6 +589,18 @@ struct snd_seq_query_subs { char reserved[64]; /* for future use */ }; +/* + * UMP-specific information + */ +/* type of UMP info query */ +#define SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT 0 +#define SNDRV_SEQ_CLIENT_UMP_INFO_BLOCK 1 + +struct snd_seq_client_ump_info { + int client; /* client number to inquire/set */ + int type; /* type to inquire/set */ + unsigned char info[512]; /* info (either UMP ep or block info) */ +} __packed; /* * IOCTL commands @@ -561,9 +610,12 @@ struct snd_seq_query_subs { #define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int) #define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct snd_seq_system_info) #define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct snd_seq_running_info) +#define SNDRV_SEQ_IOCTL_USER_PVERSION _IOW('S', 0x04, int) #define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct snd_seq_client_info) #define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct snd_seq_client_info) +#define SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO _IOWR('S', 0x12, struct snd_seq_client_ump_info) +#define SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO _IOWR('S', 0x13, struct snd_seq_client_ump_info) #define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct snd_seq_port_info) #define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct snd_seq_port_info) diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 0aa955aa8246..f9939da41122 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -274,6 +274,7 @@ typedef int __bitwise snd_pcm_subformat_t; #define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */ #define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */ #define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020 /* need the explicit sync of appl_ptr update */ +#define SNDRV_PCM_INFO_PERFECT_DRAIN 0x00000040 /* silencing at the end of stream is not required */ #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */ #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */ #define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */ @@ -383,6 +384,9 @@ typedef int snd_pcm_hw_param_t; #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */ #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */ #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */ +#define SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE (1<<3) /* suppress drain with the filling + * of the silence samples + */ struct snd_interval { unsigned int min, max; @@ -708,7 +712,7 @@ enum { * Raw MIDI section - /dev/snd/midi?? */ -#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2) +#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 4) enum { SNDRV_RAWMIDI_STREAM_OUTPUT = 0, @@ -719,6 +723,7 @@ enum { #define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001 #define SNDRV_RAWMIDI_INFO_INPUT 0x00000002 #define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004 +#define SNDRV_RAWMIDI_INFO_UMP 0x00000008 struct snd_rawmidi_info { unsigned int device; /* RO/WR (control): device number */ @@ -779,6 +784,72 @@ struct snd_rawmidi_status { }; #endif +/* UMP EP info flags */ +#define SNDRV_UMP_EP_INFO_STATIC_BLOCKS 0x01 + +/* UMP EP Protocol / JRTS capability bits */ +#define SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK 0x0300 +#define SNDRV_UMP_EP_INFO_PROTO_MIDI1 0x0100 /* MIDI 1.0 */ +#define SNDRV_UMP_EP_INFO_PROTO_MIDI2 0x0200 /* MIDI 2.0 */ +#define SNDRV_UMP_EP_INFO_PROTO_JRTS_MASK 0x0003 +#define SNDRV_UMP_EP_INFO_PROTO_JRTS_TX 0x0001 /* JRTS Transmit */ +#define SNDRV_UMP_EP_INFO_PROTO_JRTS_RX 0x0002 /* JRTS Receive */ + +/* UMP Endpoint information */ +struct snd_ump_endpoint_info { + int card; /* card number */ + int device; /* device number */ + unsigned int flags; /* additional info */ + unsigned int protocol_caps; /* protocol capabilities */ + unsigned int protocol; /* current protocol */ + unsigned int num_blocks; /* # of function blocks */ + unsigned short version; /* UMP major/minor version */ + unsigned short family_id; /* MIDI device family ID */ + unsigned short model_id; /* MIDI family model ID */ + unsigned int manufacturer_id; /* MIDI manufacturer ID */ + unsigned char sw_revision[4]; /* software revision */ + unsigned short padding; + unsigned char name[128]; /* endpoint name string */ + unsigned char product_id[128]; /* unique product id string */ + unsigned char reserved[32]; +} __packed; + +/* UMP direction */ +#define SNDRV_UMP_DIR_INPUT 0x01 +#define SNDRV_UMP_DIR_OUTPUT 0x02 +#define SNDRV_UMP_DIR_BIDIRECTION 0x03 + +/* UMP block info flags */ +#define SNDRV_UMP_BLOCK_IS_MIDI1 (1U << 0) /* MIDI 1.0 port w/o restrict */ +#define SNDRV_UMP_BLOCK_IS_LOWSPEED (1U << 1) /* 31.25Kbps B/W MIDI1 port */ + +/* UMP block user-interface hint */ +#define SNDRV_UMP_BLOCK_UI_HINT_UNKNOWN 0x00 +#define SNDRV_UMP_BLOCK_UI_HINT_RECEIVER 0x01 +#define SNDRV_UMP_BLOCK_UI_HINT_SENDER 0x02 +#define SNDRV_UMP_BLOCK_UI_HINT_BOTH 0x03 + +/* UMP groups and blocks */ +#define SNDRV_UMP_MAX_GROUPS 16 +#define SNDRV_UMP_MAX_BLOCKS 32 + +/* UMP Block information */ +struct snd_ump_block_info { + int card; /* card number */ + int device; /* device number */ + unsigned char block_id; /* block ID (R/W) */ + unsigned char direction; /* UMP direction */ + unsigned char active; /* Activeness */ + unsigned char first_group; /* first group ID */ + unsigned char num_groups; /* number of groups */ + unsigned char midi_ci_version; /* MIDI-CI support version */ + unsigned char sysex8_streams; /* max number of sysex8 streams */ + unsigned char ui_hint; /* user interface hint */ + unsigned int flags; /* various info flags */ + unsigned char name[128]; /* block name string */ + unsigned char reserved[32]; +} __packed; + #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) #define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int) @@ -786,6 +857,9 @@ struct snd_rawmidi_status { #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) #define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) +/* Additional ioctls for UMP rawmidi devices */ +#define SNDRV_UMP_IOCTL_ENDPOINT_INFO _IOR('W', 0x40, struct snd_ump_endpoint_info) +#define SNDRV_UMP_IOCTL_BLOCK_INFO _IOR('W', 0x41, struct snd_ump_block_info) /* * Timer section - /dev/snd/timer @@ -961,7 +1035,7 @@ struct snd_timer_tread { * * ****************************************************************************/ -#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8) +#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9) struct snd_ctl_card_info { int card; /* card number */ @@ -1122,6 +1196,9 @@ struct snd_ctl_tlv { #define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) #define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info) #define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) +#define SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE _IOWR('U', 0x43, int) +#define SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO _IOWR('U', 0x44, struct snd_ump_endpoint_info) +#define SNDRV_CTL_IOCTL_UMP_BLOCK_INFO _IOWR('U', 0x45, struct snd_ump_block_info) #define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) #define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) diff --git a/include/uapi/sound/emu10k1.h b/include/uapi/sound/emu10k1.h index c8e131d6da00..4c32a116e7ad 100644 --- a/include/uapi/sound/emu10k1.h +++ b/include/uapi/sound/emu10k1.h @@ -308,6 +308,8 @@ struct snd_emu10k1_fx8010_info { #define EMU10K1_GPR_TRANSLATION_BASS 2 #define EMU10K1_GPR_TRANSLATION_TREBLE 3 #define EMU10K1_GPR_TRANSLATION_ONOFF 4 +#define EMU10K1_GPR_TRANSLATION_NEGATE 5 +#define EMU10K1_GPR_TRANSLATION_NEG_TABLE100 6 enum emu10k1_ctl_elem_iface { EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ @@ -328,9 +330,9 @@ struct snd_emu10k1_fx8010_control_gpr { unsigned int vcount; /* visible count */ unsigned int count; /* count of GPR (1..16) */ unsigned short gpr[32]; /* GPR number(s) */ - unsigned int value[32]; /* initial values */ - unsigned int min; /* minimum range */ - unsigned int max; /* maximum range */ + int value[32]; /* initial values */ + int min; /* minimum range */ + int max; /* maximum range */ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ const unsigned int *tlv; }; diff --git a/include/uapi/sound/skl-tplg-interface.h b/include/uapi/sound/skl-tplg-interface.h index f29899b179a6..4bf9c4f9add8 100644 --- a/include/uapi/sound/skl-tplg-interface.h +++ b/include/uapi/sound/skl-tplg-interface.h @@ -66,7 +66,8 @@ enum skl_ch_cfg { SKL_CH_CFG_DUAL_MONO = 9, SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10, SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11, - SKL_CH_CFG_4_CHANNEL = 12, + SKL_CH_CFG_7_1 = 12, + SKL_CH_CFG_4_CHANNEL = SKL_CH_CFG_7_1, SKL_CH_CFG_INVALID }; diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index bbc37877aaff..e9ec7e4eb982 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -183,7 +183,7 @@ #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908 -#define SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX 1909 +#define SOF_TKN_CAVS_AUDIO_FORMAT_INPUT_PIN_INDEX 1909 /* intentional token numbering discontinuity, reserved for future use */ #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931 @@ -194,6 +194,7 @@ #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE 1936 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG 1937 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_SAMPLE_TYPE 1938 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUTPUT_PIN_INDEX 1939 /* intentional token numbering discontinuity, reserved for future use */ #define SOF_TKN_CAVS_AUDIO_FORMAT_IBS 1970 #define SOF_TKN_CAVS_AUDIO_FORMAT_OBS 1971 diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index f7553293ba98..6dc11fa0ebb1 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -225,7 +225,6 @@ struct ufs_dev_cmd { struct mutex lock; struct completion *complete; struct ufs_query query; - struct cq_entry *cqe; }; /** @@ -611,6 +610,19 @@ enum ufshcd_quirks { * to reinit the device after switching to maximum gear. */ UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH = 1 << 19, + + /* + * Some host raises interrupt (per queue) in addition to + * CQES (traditional) when ESI is disabled. + * Enable this quirk will disable CQES and use per queue interrupt. + */ + UFSHCD_QUIRK_MCQ_BROKEN_INTR = 1 << 20, + + /* + * Some host does not implement SQ Run Time Command (SQRTC) register + * thus need this quirk to skip related flow. + */ + UFSHCD_QUIRK_MCQ_BROKEN_RTC = 1 << 21, }; enum ufshcd_caps { @@ -1087,6 +1099,7 @@ struct ufs_hba { * @cq_tail_slot: current slot to which CQ tail pointer is pointing * @cq_head_slot: current slot to which CQ head pointer is pointing * @cq_lock: Synchronize between multiple polling instances + * @sq_mutex: prevent submission queue concurrent access */ struct ufs_hw_queue { void __iomem *mcq_sq_head; @@ -1105,6 +1118,8 @@ struct ufs_hw_queue { u32 cq_tail_slot; u32 cq_head_slot; spinlock_t cq_lock; + /* prevent concurrent access to submission queue */ + struct mutex sq_mutex; }; static inline bool is_mcq_enabled(struct ufs_hba *hba) @@ -1133,7 +1148,7 @@ static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba) ({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); }) #endif -static inline size_t sizeof_utp_transfer_cmd_desc(const struct ufs_hba *hba) +static inline size_t ufshcd_get_ucd_size(const struct ufs_hba *hba) { return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba); } @@ -1240,7 +1255,7 @@ void ufshcd_update_evt_hist(struct ufs_hba *hba, u32 id, u32 val); void ufshcd_hba_stop(struct ufs_hba *hba); void ufshcd_schedule_eh_work(struct ufs_hba *hba); void ufshcd_mcq_write_cqis(struct ufs_hba *hba, u32 val, int i); -unsigned long ufshcd_mcq_poll_cqe_nolock(struct ufs_hba *hba, +unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba, struct ufs_hw_queue *hwq); void ufshcd_mcq_enable_esi(struct ufs_hba *hba); void ufshcd_mcq_config_esi(struct ufs_hba *hba, struct msi_msg *msg); @@ -1277,7 +1292,6 @@ extern int ufshcd_system_freeze(struct device *dev); extern int ufshcd_system_thaw(struct device *dev); extern int ufshcd_system_restore(struct device *dev); #endif -extern int ufshcd_shutdown(struct ufs_hba *hba); extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba, int agreed_gear, @@ -1358,7 +1372,7 @@ void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, bool ascii); -int ufshcd_hold(struct ufs_hba *hba, bool async); +void ufshcd_hold(struct ufs_hba *hba); void ufshcd_release(struct ufs_hba *hba); void ufshcd_clkgate_delay_set(struct device *dev, unsigned long value); diff --git a/include/ufs/ufshci.h b/include/ufs/ufshci.h index 11424bb03814..146fbea76d98 100644 --- a/include/ufs/ufshci.h +++ b/include/ufs/ufshci.h @@ -99,6 +99,9 @@ enum { enum { REG_SQHP = 0x0, REG_SQTP = 0x4, + REG_SQRTC = 0x8, + REG_SQCTI = 0xC, + REG_SQRTS = 0x10, }; enum { @@ -111,12 +114,26 @@ enum { REG_CQIE = 0x4, }; +enum { + SQ_START = 0x0, + SQ_STOP = 0x1, + SQ_ICU = 0x2, +}; + +enum { + SQ_STS = 0x1, + SQ_CUS = 0x2, +}; + +#define SQ_ICU_ERR_CODE_MASK GENMASK(7, 4) +#define UPIU_COMMAND_TYPE_MASK GENMASK(31, 28) #define UFS_MASK(mask, offset) ((mask) << (offset)) /* UFS Version 08h */ #define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0) #define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16) +#define UFSHCD_NUM_RESERVED 1 /* * Controller UFSHCI version * - 2.x and newer use the following scheme: @@ -453,7 +470,7 @@ enum { }; /* The maximum length of the data byte count field in the PRDT is 256KB */ -#define PRDT_DATA_BYTE_COUNT_MAX (256 * 1024) +#define PRDT_DATA_BYTE_COUNT_MAX SZ_256K /* The granularity of the data byte count field in the PRDT is 32-bit */ #define PRDT_DATA_BYTE_COUNT_PAD 4 @@ -503,8 +520,7 @@ struct request_desc_header { /** * struct utp_transfer_req_desc - UTP Transfer Request Descriptor (UTRD) * @header: UTRD header DW-0 to DW-3 - * @command_desc_base_addr_lo: UCD base address low DW-4 - * @command_desc_base_addr_hi: UCD base address high DW-5 + * @command_desc_base_addr: UCD base address DW 4-5 * @response_upiu_length: response UPIU length DW-6 * @response_upiu_offset: response UPIU offset DW-6 * @prd_table_length: Physical region descriptor length DW-7 @@ -516,8 +532,7 @@ struct utp_transfer_req_desc { struct request_desc_header header; /* DW 4-5*/ - __le32 command_desc_base_addr_lo; - __le32 command_desc_base_addr_hi; + __le64 command_desc_base_addr; /* DW 6 */ __le16 response_upiu_length; diff --git a/include/video/sticore.h b/include/video/sticore.h new file mode 100644 index 000000000000..945ad60463a1 --- /dev/null +++ b/include/video/sticore.h @@ -0,0 +1,406 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef STICORE_H +#define STICORE_H + +struct fb_info; + +/* generic STI structures & functions */ + +#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ + +#define STI_REGION_MAX 8 /* hardcoded STI constants */ +#define STI_DEV_NAME_LENGTH 32 +#define STI_MONITOR_MAX 256 + +#define STI_FONT_HPROMAN8 1 +#define STI_FONT_KANA8 2 + +#define ALT_CODE_TYPE_UNKNOWN 0x00 /* alt code type values */ +#define ALT_CODE_TYPE_PA_RISC_64 0x01 + +/* The latency of the STI functions cannot really be reduced by setting + * this to 0; STI doesn't seem to be designed to allow calling a different + * function (or the same function with different arguments) after a + * function exited with 1 as return value. + * + * As all of the functions below could be called from interrupt context, + * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1) + * block. Really bad latency there. + * + * Probably the best solution to all this is have the generic code manage + * the screen buffer and a kernel thread to call STI occasionally. + * + * Luckily, the frame buffer guys have the same problem so we can just wait + * for them to fix it and steal their solution. prumpf + */ + +#include <asm/io.h> + +#define STI_WAIT 1 + +#define STI_PTR(p) ( virt_to_phys(p) ) + +#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) +#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) + +/* sti_font_xy() use the native font ROM ! */ +#define sti_font_x(sti) (PTR_STI(sti->font)->width) +#define sti_font_y(sti) (PTR_STI(sti->font)->height) + +#ifdef CONFIG_64BIT +#define STI_LOWMEM (GFP_KERNEL | GFP_DMA) +#else +#define STI_LOWMEM (GFP_KERNEL) +#endif + + +/* STI function configuration structs */ + +typedef union region { + struct { + u32 offset : 14; /* offset in 4kbyte page */ + u32 sys_only : 1; /* don't map to user space */ + u32 cache : 1; /* map to data cache */ + u32 btlb : 1; /* map to block tlb */ + u32 last : 1; /* last region in list */ + u32 length : 14; /* length in 4kbyte page */ + } region_desc; + + u32 region; /* complete region value */ +} region_t; + +#define REGION_OFFSET_TO_PHYS( rt, hpa ) \ + (((rt).region_desc.offset << 12) + (hpa)) + +struct sti_glob_cfg_ext { + u8 curr_mon; /* current monitor configured */ + u8 friendly_boot; /* in friendly boot mode */ + s16 power; /* power calculation (in Watts) */ + s32 freq_ref; /* frequency reference */ + u32 *sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_glob_cfg { + s32 text_planes; /* number of planes used for text */ + s16 onscreen_x; /* screen width in pixels */ + s16 onscreen_y; /* screen height in pixels */ + s16 offscreen_x; /* offset width in pixels */ + s16 offscreen_y; /* offset height in pixels */ + s16 total_x; /* frame buffer width in pixels */ + s16 total_y; /* frame buffer height in pixels */ + u32 *region_ptrs[STI_REGION_MAX]; /* region pointers */ + s32 reent_lvl; /* storage for reentry level value */ + u32 *save_addr; /* where to save or restore reentrant state */ + u32 *ext_ptr; /* pointer to extended glob_cfg data structure */ +}; + + +/* STI init function structs */ + +struct sti_init_flags { + u32 wait : 1; /* should routine idle wait or not */ + u32 reset : 1; /* hard reset the device? */ + u32 text : 1; /* turn on text display planes? */ + u32 nontext : 1; /* turn on non-text display planes? */ + u32 clear : 1; /* clear text display planes? */ + u32 cmap_blk : 1; /* non-text planes cmap black? */ + u32 enable_be_timer : 1; /* enable bus error timer */ + u32 enable_be_int : 1; /* enable bus error timer interrupt */ + u32 no_chg_tx : 1; /* don't change text settings */ + u32 no_chg_ntx : 1; /* don't change non-text settings */ + u32 no_chg_bet : 1; /* don't change berr timer settings */ + u32 no_chg_bei : 1; /* don't change berr int settings */ + u32 init_cmap_tx : 1; /* initialize cmap for text planes */ + u32 cmt_chg : 1; /* change current monitor type */ + u32 retain_ie : 1; /* don't allow reset to clear int enables */ + u32 caller_bootrom : 1; /* set only by bootrom for each call */ + u32 caller_kernel : 1; /* set only by kernel for each call */ + u32 caller_other : 1; /* set only by non-[BR/K] caller */ + u32 pad : 14; /* pad to word boundary */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_init_inptr_ext { + u8 config_mon_type; /* configure to monitor type */ + u8 pad[1]; /* pad to word boundary */ + u16 inflight_data; /* inflight data possible on PCI */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_init_inptr { + s32 text_planes; /* number of planes to use for text */ + u32 *ext_ptr; /* pointer to extended init_graph inptr data structure*/ +}; + + +struct sti_init_outptr { + s32 errno; /* error number on failure */ + s32 text_planes; /* number of planes used for text */ + u32 *future_ptr; /* pointer to future data */ +}; + + + +/* STI configuration function structs */ + +struct sti_conf_flags { + u32 wait : 1; /* should routine idle wait or not */ + u32 pad : 31; /* pad to word boundary */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_conf_inptr { + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_conf_outptr_ext { + u32 crt_config[3]; /* hardware specific X11/OGL information */ + u32 crt_hdw[3]; + u32 *future_ptr; +}; + +struct sti_conf_outptr { + s32 errno; /* error number on failure */ + s16 onscreen_x; /* screen width in pixels */ + s16 onscreen_y; /* screen height in pixels */ + s16 offscreen_x; /* offscreen width in pixels */ + s16 offscreen_y; /* offscreen height in pixels */ + s16 total_x; /* frame buffer width in pixels */ + s16 total_y; /* frame buffer height in pixels */ + s32 bits_per_pixel; /* bits/pixel device has configured */ + s32 bits_used; /* bits which can be accessed */ + s32 planes; /* number of fb planes in system */ + u8 dev_name[STI_DEV_NAME_LENGTH]; /* null terminated product name */ + u32 attributes; /* flags denoting attributes */ + u32 *ext_ptr; /* pointer to future data */ +}; + +struct sti_rom { + u8 type[4]; + u8 res004; + u8 num_mons; + u8 revno[2]; + u32 graphics_id[2]; + + u32 font_start; + u32 statesize; + u32 last_addr; + u32 region_list; + + u16 reentsize; + u16 maxtime; + u32 mon_tbl_addr; + u32 user_data_addr; + u32 sti_mem_req; + + u32 user_data_size; + u16 power; + u8 bus_support; + u8 ext_bus_support; + u8 alt_code_type; + u8 ext_dd_struct[3]; + u32 cfb_addr; + + u32 init_graph; + u32 state_mgmt; + u32 font_unpmv; + u32 block_move; + u32 self_test; + u32 excep_hdlr; + u32 inq_conf; + u32 set_cm_entry; + u32 dma_ctrl; + u8 res040[7 * 4]; + + u32 init_graph_addr; + u32 state_mgmt_addr; + u32 font_unp_addr; + u32 block_move_addr; + u32 self_test_addr; + u32 excep_hdlr_addr; + u32 inq_conf_addr; + u32 set_cm_entry_addr; + u32 image_unpack_addr; + u32 pa_risx_addrs[7]; +}; + +struct sti_rom_font { + u16 first_char; + u16 last_char; + u8 width; + u8 height; + u8 font_type; /* language type */ + u8 bytes_per_char; + u32 next_font; + u8 underline_height; + u8 underline_pos; + u8 res008[2]; +}; + +/* sticore internal font handling */ + +struct sti_cooked_font { + struct sti_rom_font *raw; /* native ptr for STI functions */ + void *raw_ptr; /* kmalloc'ed font data */ + struct sti_cooked_font *next_font; + int height, width; + int refcount; + u32 crc; +}; + +struct sti_cooked_rom { + struct sti_rom *raw; + struct sti_cooked_font *font_start; +}; + +/* STI font printing function structs */ + +struct sti_font_inptr { + u32 *font_start_addr; /* address of font start */ + s16 index; /* index into font table of character */ + u8 fg_color; /* foreground color of character */ + u8 bg_color; /* background color of character */ + s16 dest_x; /* X location of character upper left */ + s16 dest_y; /* Y location of character upper left */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_font_flags { + u32 wait : 1; /* should routine idle wait or not */ + u32 non_text : 1; /* font unpack/move in non_text planes =1, text =0 */ + u32 pad : 30; /* pad to word boundary */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_font_outptr { + s32 errno; /* error number on failure */ + u32 *future_ptr; /* pointer to future data */ +}; + +/* STI blockmove structs */ + +struct sti_blkmv_flags { + u32 wait : 1; /* should routine idle wait or not */ + u32 color : 1; /* change color during move? */ + u32 clear : 1; /* clear during move? */ + u32 non_text : 1; /* block move in non_text planes =1, text =0 */ + u32 pad : 28; /* pad to word boundary */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_blkmv_inptr { + u8 fg_color; /* foreground color after move */ + u8 bg_color; /* background color after move */ + s16 src_x; /* source upper left pixel x location */ + s16 src_y; /* source upper left pixel y location */ + s16 dest_x; /* dest upper left pixel x location */ + s16 dest_y; /* dest upper left pixel y location */ + s16 width; /* block width in pixels */ + s16 height; /* block height in pixels */ + u32 *future_ptr; /* pointer to future data */ +}; + +struct sti_blkmv_outptr { + s32 errno; /* error number on failure */ + u32 *future_ptr; /* pointer to future data */ +}; + + +/* sti_all_data is an internal struct which needs to be allocated in + * low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */ + +struct sti_all_data { + struct sti_glob_cfg glob_cfg; + struct sti_glob_cfg_ext glob_cfg_ext; + + struct sti_conf_inptr inq_inptr; + struct sti_conf_outptr inq_outptr; /* configuration */ + struct sti_conf_outptr_ext inq_outptr_ext; + + struct sti_init_inptr_ext init_inptr_ext; + struct sti_init_inptr init_inptr; + struct sti_init_outptr init_outptr; + + struct sti_blkmv_inptr blkmv_inptr; + struct sti_blkmv_outptr blkmv_outptr; + + struct sti_font_inptr font_inptr; + struct sti_font_outptr font_outptr; + + /* leave as last entries */ + unsigned long save_addr[1024 / sizeof(unsigned long)]; + /* min 256 bytes which is STI default, max sti->sti_mem_request */ + unsigned long sti_mem_addr[256 / sizeof(unsigned long)]; + /* do not add something below here ! */ +}; + +/* internal generic STI struct */ + +struct sti_struct { + spinlock_t lock; + + /* char **mon_strings; */ + int sti_mem_request; + u32 graphics_id[2]; + + struct sti_cooked_rom *rom; + + unsigned long font_unpmv; + unsigned long block_move; + unsigned long init_graph; + unsigned long inq_conf; + int do_call64; /* call 64-bit code */ + + /* all following fields are initialized by the generic routines */ + int text_planes; + region_t regions[STI_REGION_MAX]; + unsigned long regions_phys[STI_REGION_MAX]; + + struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ + + int wordmode; + struct sti_cooked_font *font; /* ptr to selected font (cooked) */ + + struct pci_dev *pd; + + /* PCI data structures (pg. 17ff from sti.pdf) */ + u8 rm_entry[16]; /* pci region mapper array == pci config space offset */ + + /* pointer to the fb_info where this STI device is used */ + struct fb_info *info; + + /* pointer to all internal data */ + struct sti_all_data *sti_data; + + /* pa_path of this device */ + char pa_path[24]; +}; + + +/* sticore interface functions */ + +struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ +void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f); + + +/* sticore main function to call STI firmware */ + +int sti_call(const struct sti_struct *sti, unsigned long func, + const void *flags, void *inptr, void *outptr, + struct sti_glob_cfg *glob_cfg); + + +/* functions to call the STI ROM directly */ + +void sti_putc(struct sti_struct *sti, int c, int y, int x, + struct sti_cooked_font *font); +void sti_set(struct sti_struct *sti, int src_y, int src_x, + int height, int width, u8 color); +void sti_clear(struct sti_struct *sti, int src_y, int src_x, + int height, int width, int c, struct sti_cooked_font *font); +void sti_bmove(struct sti_struct *sti, int src_y, int src_x, + int dst_y, int dst_x, int height, int width, + struct sti_cooked_font *font); + +#endif /* STICORE_H */ diff --git a/include/xen/events.h b/include/xen/events.h index 44c2855c76d1..ac1281c5ead6 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -138,4 +138,7 @@ int xen_test_irq_shared(int irq); /* initialize Xen IRQ subsystem */ void xen_init_IRQ(void); + +irqreturn_t xen_debug_interrupt(int irq, void *dev_id); + #endif /* _XEN_EVENTS_H */ diff --git a/include/xen/xen.h b/include/xen/xen.h index 0efeb652f9b8..f989162983c3 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -31,6 +31,9 @@ extern uint32_t xen_start_flags; #include <xen/interface/hvm/start_info.h> extern struct hvm_start_info pvh_start_info; +void xen_prepare_pvh(void); +struct pt_regs; +void xen_pv_evtchn_do_upcall(struct pt_regs *regs); #ifdef CONFIG_XEN_DOM0 #include <xen/interface/xen.h> |