diff options
Diffstat (limited to 'include/linux')
282 files changed, 14215 insertions, 4915 deletions
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/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..f401067ac03a 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) @@ -746,8 +739,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 +836,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 +852,7 @@ 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 || + if (!iob || (req->rq_flags & RQF_USE_SCHED) || ioerror || (req->end_io && !blk_rq_is_passthrough(req))) return false; @@ -1164,6 +1156,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 +1198,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 c0ffe203a602..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); @@ -1380,10 +1375,12 @@ 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 *); @@ -1410,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 @@ -1463,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); @@ -1488,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) { @@ -1509,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/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_attributes.h b/include/linux/compiler_attributes.h index e659cb6fded3..571fa7924f74 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -124,6 +124,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 +269,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/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..66c13965153d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -96,7 +96,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 +110,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 +133,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 +327,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 +815,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 */ 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/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/efi.h b/include/linux/efi.h index 571d1a6e1b74..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); 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/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/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/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 133f0640fb24..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 @@ -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/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/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.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 7fe31b2cd02f..bb9c666bd584 100644 --- a/include/linux/io_uring.h +++ b/include/linux/io_uring.h @@ -46,13 +46,23 @@ 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) { @@ -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/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/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/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/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 74bd269a80a2..310f85903c91 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -447,6 +447,14 @@ extern int lockdep_is_held(const void *); #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, diff --git a/include/linux/lockdep_types.h b/include/linux/lockdep_types.h index 59f4fb1626ea..2ebc323d345a 100644 --- a/include/linux/lockdep_types.h +++ b/include/linux/lockdep_types.h @@ -85,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. @@ -110,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 94d2be5848ae..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, }; @@ -1174,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); @@ -1238,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 b89778d0d326..33344a71c3e3 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1710,9 +1710,9 @@ struct mlx5_ifc_cmd_hca_cap_bits { 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]; @@ -1755,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]; @@ -1990,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 { @@ -3112,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 { @@ -3673,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 { @@ -4797,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]; @@ -5175,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 { @@ -5948,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/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/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 c2f0c6002a84..b828c7a75be2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3124,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); @@ -4827,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; @@ -4856,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, @@ -4987,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) { @@ -5035,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; @@ -5093,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-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 95f33dadb2be..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 @@ -568,6 +576,7 @@ #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/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..42125cf9c506 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -103,12 +103,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); 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 6478838405a0..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; \ 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/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/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..7d9c2a63b7cd 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -156,31 +156,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 +932,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 +958,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 +978,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); \ 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/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/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/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/skbuff.h b/include/linux/skbuff.h index 0b40417457cd..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; @@ -2421,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); } /** @@ -2466,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; @@ -3494,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); /** @@ -3992,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); @@ -4043,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; @@ -4859,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; @@ -5126,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/slab.h b/include/linux/slab.h index 6b3e155b70bf..791f7453a04f 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -12,6 +12,7 @@ #ifndef _LINUX_SLAB_H #define _LINUX_SLAB_H +#include <linux/cache.h> #include <linux/gfp.h> #include <linux/overflow.h> #include <linux/types.h> @@ -53,16 +54,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 +109,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) @@ -235,12 +250,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/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/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/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..eb92a50a4599 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); } 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 fbc4bd423b35..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[]; }; 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/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/trace_events.h b/include/linux/trace_events.h index 7c4a0b72334e..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), }; 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/hcd.h b/include/linux/usb/hcd.h index 0c7eff91adf4..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); 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/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/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 |