mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge 6.1.105 into android14-6.1-lts
Changes in 6.1.105 irqchip/mbigen: Fix mbigen node address layout platform/x86/intel/ifs: Gen2 Scan test support platform/x86/intel/ifs: Initialize union ifs_status to zero jump_label: Fix the fix, brown paper bags galore x86/mm: Fix pti_clone_pgtable() alignment assumption x86/mm: Fix pti_clone_entry_text() for i386 sctp: Fix null-ptr-deref in reuseport_add_sock(). net: usb: qmi_wwan: fix memory leak for not ip packets net: bridge: mcast: wait for previous gc cycles when removing port net: linkwatch: use system_unbound_wq Bluetooth: l2cap: always unlock channel in l2cap_conless_channel() Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv monitor net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register() l2tp: fix lockdep splat net: fec: Stop PPS on driver remove rcutorture: Fix rcu_torture_fwd_cb_cr() data race md: do not delete safemode_timer in mddev_suspend md/raid5: avoid BUG_ON() while continue reshape after reassembling block: change rq_integrity_vec to respect the iterator rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation clocksource/drivers/sh_cmt: Address race condition for clock events ACPI: battery: create alarm sysfs attribute atomically ACPI: SBS: manage alarm sysfs attribute through psy core wifi: nl80211: disallow setting special AP channel widths net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT af_unix: Don't retry after unix_state_lock_nested() in unix_stream_connect(). PCI: Add Edimax Vendor ID to pci_ids.h udf: prevent integer overflow in udf_bitmap_free_blocks() wifi: nl80211: don't give key data to userspace can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index erratum can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of mcp2518fd btrfs: fix bitmap leak when loading free space cache on duplicate entry drm/amdgpu/pm: Fix the param type of set_power_profile_mode drm/amdgpu/pm: Fix the null pointer dereference for smu7 drm/amdgpu: Fix the null pointer dereference to ras_manager drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules drm/amdgpu: Add lock around VF RLCG interface drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr media: amphion: Remove lock in s_ctrl callback drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update drm/amd/display: Add null checker before passing variables media: uvcvideo: Ignore empty TS packets media: uvcvideo: Fix the bandwdith quirk on USB 3.x media: xc2028: avoid use-after-free in load_firmware_cb() ext4: fix uninitialized variable in ext4_inlinedir_to_tree jbd2: avoid memleak in jbd2_journal_write_metadata_buffer s390/sclp: Prevent release of buffer in I/O SUNRPC: Fix a race to wake a sync task bus: mhi: host: pci_generic: add support for Telit FE990 modem Revert "bpftool: Mount bpffs when pinmaps path not under the bpffs" profiling: remove profile=sleep support scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_spinlock_t' irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq() sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime ext4: fix wrong unit use in ext4_mb_find_by_goal arm64: Add Neoverse-V2 part arm64: barrier: Restore spec_bar() macro arm64: cputype: Add Cortex-X4 definitions arm64: cputype: Add Neoverse-V3 definitions arm64: errata: Add workaround for Arm errata 3194386 and 3312417 arm64: cputype: Add Cortex-X3 definitions arm64: cputype: Add Cortex-A720 definitions arm64: cputype: Add Cortex-X925 definitions arm64: errata: Unify speculative SSBS errata logic arm64: errata: Expand speculative SSBS workaround arm64: cputype: Add Cortex-X1C definitions arm64: cputype: Add Cortex-A725 definitions arm64: errata: Expand speculative SSBS workaround (again) i2c: smbus: Improve handling of stuck alerts ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask ASoC: codecs: wsa881x: Correct Soundwire ports mask ASoC: codecs: wsa883x: parse port-mapping information ASoC: codecs: wsa883x: Correct Soundwire ports mask spi: spidev: Add missing spi_device_id for bh2228fv ASoC: SOF: Remove libraries from topology lookups i2c: smbus: Send alert notifications to all devices if source not found bpf: kprobe: remove unused declaring of bpf_kprobe_override kprobes: Fix to check symbol prefixes correctly i2c: qcom-geni: add desc struct to prepare support for I2C Master Hub variant i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume spi: spi-fsl-lpspi: Fix scldiv calculation ALSA: usb-audio: Re-add ScratchAmp quirk entries ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT drm/amd/display: Skip Recompute DSC Params if no Stream on Link drm/client: fix null pointer dereference in drm_client_modeset_probe ALSA: line6: Fix racy access to midibuf ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4 usb: vhci-hcd: Do not drop references before new references are gained USB: serial: debug: do not echo input by default usb: gadget: core: Check for unset descriptor usb: gadget: u_serial: Set start_delayed during suspend usb: gadget: u_audio: Check return codes from usb_ep_enable and config_ep_by_speed. scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic tick/broadcast: Move per CPU pointer access into the atomic section vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler ntp: Clamp maxerror and esterror to operating range torture: Enable clocksource watchdog with "tsc=watchdog" clocksource: Scale the watchdog read retries automatically clocksource: Fix brown-bag boolean thinko in cs_watchdog_read() driver core: Fix uevent_show() vs driver detach race ntp: Safeguard against time_constant overflow timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex() serial: core: check uartclk for zero to avoid divide by zero ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx kcov: properly check for softirq context irqchip/xilinx: Fix shift out of bounds genirq/irqdesc: Honor caller provided affinity in alloc_desc() power: supply: axp288_charger: Fix constant_charge_voltage writes power: supply: axp288_charger: Round constant_charge_voltage writes down tracing: Fix overflow in get_free_elt() padata: Fix possible divide-by-0 panic in padata_mt_helper() smb3: fix setting SecurityFlags when encryption is required btrfs: avoid using fixed char array size for tree names x86/mtrr: Check if fixed MTRRs exist before saving them sched/smt: Introduce sched_smt_present_inc/dec() helper sched/smt: Fix unbalance sched_smt_present dec/inc drm/bridge: analogix_dp: properly handle zero sized AUX transactions drm/dp_mst: Skip CSN if topology probing is not done yet drm/lima: Mark simple_ondemand governor as softdep drm/mgag200: Set DDC timeout in milliseconds drm/mgag200: Bind I2C lifetime to DRM device mptcp: mib: count MPJ with backup flag mptcp: export local_address mptcp: pm: fix backup support in signal endpoints selftests: mptcp: join: validate backup in MPJ selftests: mptcp: join: check backup support in signal endp mptcp: pm: deny endp with signal + subflow + port block: use the right type for stub rq_integrity_vec() Revert "drm/amd/display: Add NULL check for 'afb' before dereferencing in amdgpu_dm_plane_handle_cursor_update" mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit machines btrfs: fix corruption after buffer fault in during direct IO append write ipv6: fix source address selection with route leak tools headers arm64: Sync arm64's cputype.h with the kernel sources mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio() block: Call .limit_depth() after .hctx has been set block/mq-deadline: Fix the tag reservation code xfs: fix log recovery buffer allocation for the legacy h_size fixup netfilter: nf_tables: bail out if stateful expression provides no .clone netfilter: nf_tables: allow clone callbacks to sleep netfilter: nf_tables: prefer nft_chain_validate i2c: qcom-geni: fix missing clk_disable_unprepare() and geni_se_resources_off() btrfs: fix double inode unlock for direct IO sync writes Linux 6.1.105 Change-Id: I63c645dee46d43a3f1b166622e1858afba6ae3a8 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -741,7 +741,7 @@ SecurityFlags Flags which control security negotiation and
|
||||
may use NTLMSSP 0x00080
|
||||
must use NTLMSSP 0x80080
|
||||
seal (packet encryption) 0x00040
|
||||
must seal (not implemented yet) 0x40040
|
||||
must seal 0x40040
|
||||
|
||||
cifsFYI If set to non-zero value, additional debug information
|
||||
will be logged to the system error log. This field
|
||||
|
||||
@@ -637,12 +637,6 @@
|
||||
loops can be debugged more effectively on production
|
||||
systems.
|
||||
|
||||
clocksource.max_cswd_read_retries= [KNL]
|
||||
Number of clocksource_watchdog() retries due to
|
||||
external delays before the clock will be marked
|
||||
unstable. Defaults to two retries, that is,
|
||||
three attempts to read the clock under test.
|
||||
|
||||
clocksource.verify_n_cpus= [KNL]
|
||||
Limit the number of CPUs checked for clocksources
|
||||
marked with CLOCK_SOURCE_VERIFY_PERCPU that
|
||||
@@ -4604,11 +4598,9 @@
|
||||
|
||||
profile= [KNL] Enable kernel profiling via /proc/profile
|
||||
Format: [<profiletype>,]<number>
|
||||
Param: <profiletype>: "schedule", "sleep", or "kvm"
|
||||
Param: <profiletype>: "schedule" or "kvm"
|
||||
[defaults to kernel profiling]
|
||||
Param: "schedule" - profile schedule points.
|
||||
Param: "sleep" - profile D-state sleeping (millisecs).
|
||||
Requires CONFIG_SCHEDSTATS
|
||||
Param: "kvm" - profile VM exits.
|
||||
Param: <number> - step/bucket size as a power of 2 for
|
||||
statistical time based profiling.
|
||||
|
||||
@@ -104,8 +104,16 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A510 | #2077057 | ARM64_ERRATUM_2077057 |
|
||||
@@ -120,22 +128,50 @@ stable kernels.
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N1 | #1349291 | N/A |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | MMU-500 | #841119,826419 | N/A |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| ARM | MMU-600 | #1076982,1209401| N/A |
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 104
|
||||
SUBLEVEL = 105
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -987,6 +987,44 @@ config ARM64_ERRATUM_2966298
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_ERRATUM_3194386
|
||||
bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing"
|
||||
default y
|
||||
help
|
||||
This option adds the workaround for the following errata:
|
||||
|
||||
* ARM Cortex-A76 erratum 3324349
|
||||
* ARM Cortex-A77 erratum 3324348
|
||||
* ARM Cortex-A78 erratum 3324344
|
||||
* ARM Cortex-A78C erratum 3324346
|
||||
* ARM Cortex-A78C erratum 3324347
|
||||
* ARM Cortex-A710 erratam 3324338
|
||||
* ARM Cortex-A720 erratum 3456091
|
||||
* ARM Cortex-A725 erratum 3456106
|
||||
* ARM Cortex-X1 erratum 3324344
|
||||
* ARM Cortex-X1C erratum 3324346
|
||||
* ARM Cortex-X2 erratum 3324338
|
||||
* ARM Cortex-X3 erratum 3324335
|
||||
* ARM Cortex-X4 erratum 3194386
|
||||
* ARM Cortex-X925 erratum 3324334
|
||||
* ARM Neoverse-N1 erratum 3324349
|
||||
* ARM Neoverse N2 erratum 3324339
|
||||
* ARM Neoverse-V1 erratum 3324341
|
||||
* ARM Neoverse V2 erratum 3324336
|
||||
* ARM Neoverse-V3 erratum 3312417
|
||||
|
||||
On affected cores "MSR SSBS, #0" instructions may not affect
|
||||
subsequent speculative instructions, which may permit unexepected
|
||||
speculative store bypassing.
|
||||
|
||||
Work around this problem by placing a Speculation Barrier (SB) or
|
||||
Instruction Synchronization Barrier (ISB) after kernel changes to
|
||||
SSBS. The presence of the SSBS special-purpose register is hidden
|
||||
from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace
|
||||
will use the PR_SPEC_STORE_BYPASS prctl to change SSBS.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config CAVIUM_ERRATUM_22375
|
||||
bool "Cavium erratum 22375, 24313"
|
||||
default y
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
*/
|
||||
#define dgh() asm volatile("hint #6" : : : "memory")
|
||||
|
||||
#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \
|
||||
SB_BARRIER_INSN"nop\n", \
|
||||
ARM64_HAS_SB))
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
#define pmr_sync() \
|
||||
do { \
|
||||
|
||||
@@ -85,6 +85,14 @@
|
||||
#define ARM_CPU_PART_CORTEX_X2 0xD48
|
||||
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
|
||||
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
|
||||
#define ARM_CPU_PART_CORTEX_X1C 0xD4C
|
||||
#define ARM_CPU_PART_CORTEX_X3 0xD4E
|
||||
#define ARM_CPU_PART_NEOVERSE_V2 0xD4F
|
||||
#define ARM_CPU_PART_CORTEX_A720 0xD81
|
||||
#define ARM_CPU_PART_CORTEX_X4 0xD82
|
||||
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
|
||||
#define ARM_CPU_PART_CORTEX_X925 0xD85
|
||||
#define ARM_CPU_PART_CORTEX_A725 0xD87
|
||||
|
||||
#define APM_CPU_PART_XGENE 0x000
|
||||
#define APM_CPU_VAR_POTENZA 0x00
|
||||
@@ -151,6 +159,14 @@
|
||||
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
|
||||
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
|
||||
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
|
||||
#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
|
||||
#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
|
||||
#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
|
||||
#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
|
||||
#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
|
||||
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
|
||||
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
|
||||
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
||||
|
||||
@@ -435,6 +435,30 @@ static struct midr_range broken_aarch32_aes[] = {
|
||||
};
|
||||
#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
|
||||
|
||||
#ifdef CONFIG_ARM64_ERRATUM_3194386
|
||||
static const struct midr_range erratum_spec_ssbs_list[] = {
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
|
||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
|
||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
#ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
|
||||
{
|
||||
@@ -726,6 +750,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
||||
.cpu_enable = cpu_clear_bf16_from_user_emulation,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_ERRATUM_3194386
|
||||
{
|
||||
.desc = "SSBS not fully self-synchronizing",
|
||||
.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
|
||||
ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
|
||||
{
|
||||
.desc = "ARM erratum 2966298",
|
||||
|
||||
@@ -2085,6 +2085,17 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
|
||||
}
|
||||
#endif /* CONFIG_ARM64_MTE */
|
||||
|
||||
static void user_feature_fixup(void)
|
||||
{
|
||||
if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
|
||||
struct arm64_ftr_reg *regp;
|
||||
|
||||
regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
|
||||
if (regp)
|
||||
regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
static void elf_hwcap_fixup(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1742098
|
||||
@@ -3285,6 +3296,7 @@ void __init setup_cpu_features(void)
|
||||
u32 cwg;
|
||||
|
||||
setup_system_capabilities();
|
||||
user_feature_fixup();
|
||||
setup_elf_hwcaps(arm64_elf_hwcaps);
|
||||
|
||||
if (system_supports_32bit_el0()) {
|
||||
|
||||
@@ -570,6 +570,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void)
|
||||
|
||||
/* SCTLR_EL1.DSSBS was initialised to 0 during boot */
|
||||
set_pstate_ssbs(0);
|
||||
|
||||
/*
|
||||
* SSBS is self-synchronizing and is intended to affect subsequent
|
||||
* speculative instructions, but some CPUs can speculate with a stale
|
||||
* value of SSBS.
|
||||
*
|
||||
* Mitigate this with an unconditional speculation barrier, as CPUs
|
||||
* could mis-speculate branches and bypass a conditional barrier.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
|
||||
spec_bar();
|
||||
|
||||
return SPECTRE_MITIGATED;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ WORKAROUND_NXP_ERR050104
|
||||
WORKAROUND_QCOM_FALKOR_E1003
|
||||
WORKAROUND_REPEAT_TLBI
|
||||
WORKAROUND_SPECULATIVE_AT
|
||||
WORKAROUND_SPECULATIVE_SSBS
|
||||
WORKAROUND_SPECULATIVE_UNPRIV_LOAD
|
||||
ANDROID_KABI_RESERVE_02
|
||||
ANDROID_KABI_RESERVE_03
|
||||
|
||||
@@ -816,7 +816,7 @@ void mtrr_save_state(void)
|
||||
{
|
||||
int first_cpu;
|
||||
|
||||
if (!mtrr_enabled())
|
||||
if (!mtrr_enabled() || !mtrr_state.have_fixed)
|
||||
return;
|
||||
|
||||
first_cpu = cpumask_first(cpu_online_mask);
|
||||
|
||||
@@ -374,14 +374,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
|
||||
*/
|
||||
*target_pmd = *pmd;
|
||||
|
||||
addr += PMD_SIZE;
|
||||
addr = round_up(addr + 1, PMD_SIZE);
|
||||
|
||||
} else if (level == PTI_CLONE_PTE) {
|
||||
|
||||
/* Walk the page-table down to the pte level */
|
||||
pte = pte_offset_kernel(pmd, addr);
|
||||
if (pte_none(*pte)) {
|
||||
addr += PAGE_SIZE;
|
||||
addr = round_up(addr + 1, PAGE_SIZE);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
|
||||
/* Clone the PTE */
|
||||
*target_pte = *pte;
|
||||
|
||||
addr += PAGE_SIZE;
|
||||
addr = round_up(addr + 1, PAGE_SIZE);
|
||||
|
||||
} else {
|
||||
BUG();
|
||||
@@ -496,7 +496,7 @@ static void pti_clone_entry_text(void)
|
||||
{
|
||||
pti_clone_pgtable((unsigned long) __entry_text_start,
|
||||
(unsigned long) __entry_text_end,
|
||||
PTI_CLONE_PMD);
|
||||
PTI_LEVEL_KERNEL_IMAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -439,6 +439,7 @@ __blk_mq_alloc_requests_batch(struct blk_mq_alloc_data *data,
|
||||
|
||||
static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
|
||||
{
|
||||
void (*limit_depth)(blk_opf_t, struct blk_mq_alloc_data *) = NULL;
|
||||
struct request_queue *q = data->q;
|
||||
u64 alloc_time_ns = 0;
|
||||
struct request *rq;
|
||||
@@ -465,7 +466,7 @@ static struct request *__blk_mq_alloc_requests(struct blk_mq_alloc_data *data)
|
||||
!blk_op_is_passthrough(data->cmd_flags) &&
|
||||
e->type->ops.limit_depth &&
|
||||
!(data->flags & BLK_MQ_REQ_RESERVED))
|
||||
e->type->ops.limit_depth(data->cmd_flags, data);
|
||||
limit_depth = e->type->ops.limit_depth;
|
||||
}
|
||||
|
||||
retry:
|
||||
@@ -477,6 +478,9 @@ retry:
|
||||
if (data->flags & BLK_MQ_REQ_RESERVED)
|
||||
data->rq_flags |= RQF_RESV;
|
||||
|
||||
if (limit_depth)
|
||||
limit_depth(data->cmd_flags, data);
|
||||
|
||||
/*
|
||||
* Try batched alloc if we want more than 1 tag.
|
||||
*/
|
||||
|
||||
@@ -597,6 +597,20 @@ unlock:
|
||||
return rq;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'depth' is a number in the range 1..INT_MAX representing a number of
|
||||
* requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since
|
||||
* 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow().
|
||||
* Values larger than q->nr_requests have the same effect as q->nr_requests.
|
||||
*/
|
||||
static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth)
|
||||
{
|
||||
struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags;
|
||||
const unsigned int nrr = hctx->queue->nr_requests;
|
||||
|
||||
return ((qdepth << bt->sb.shift) + nrr - 1) / nrr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by __blk_mq_alloc_request(). The shallow_depth value set by this
|
||||
* function is used by __blk_mq_get_tag().
|
||||
@@ -613,7 +627,7 @@ static void dd_limit_depth(blk_opf_t opf, struct blk_mq_alloc_data *data)
|
||||
* Throttle asynchronous requests and writes such that these requests
|
||||
* do not block the allocation of synchronous requests.
|
||||
*/
|
||||
data->shallow_depth = dd->async_depth;
|
||||
data->shallow_depth = dd_to_word_depth(data->hctx, dd->async_depth);
|
||||
}
|
||||
|
||||
/* Called by blk_mq_update_nr_requests(). */
|
||||
@@ -623,9 +637,9 @@ static void dd_depth_updated(struct blk_mq_hw_ctx *hctx)
|
||||
struct deadline_data *dd = q->elevator->elevator_data;
|
||||
struct blk_mq_tags *tags = hctx->sched_tags;
|
||||
|
||||
dd->async_depth = max(1UL, 3 * q->nr_requests / 4);
|
||||
dd->async_depth = q->nr_requests;
|
||||
|
||||
sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth);
|
||||
sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, 1);
|
||||
}
|
||||
|
||||
/* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */
|
||||
|
||||
@@ -667,12 +667,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct device_attribute alarm_attr = {
|
||||
static struct device_attribute alarm_attr = {
|
||||
.attr = {.name = "alarm", .mode = 0644},
|
||||
.show = acpi_battery_alarm_show,
|
||||
.store = acpi_battery_alarm_store,
|
||||
};
|
||||
|
||||
static struct attribute *acpi_battery_attrs[] = {
|
||||
&alarm_attr.attr,
|
||||
NULL
|
||||
};
|
||||
ATTRIBUTE_GROUPS(acpi_battery);
|
||||
|
||||
/*
|
||||
* The Battery Hooking API
|
||||
*
|
||||
@@ -809,7 +815,10 @@ static void __exit battery_hook_exit(void)
|
||||
|
||||
static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
{
|
||||
struct power_supply_config psy_cfg = { .drv_data = battery, };
|
||||
struct power_supply_config psy_cfg = {
|
||||
.drv_data = battery,
|
||||
.attr_grp = acpi_battery_groups,
|
||||
};
|
||||
bool full_cap_broken = false;
|
||||
|
||||
if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
|
||||
@@ -854,7 +863,7 @@ static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
return result;
|
||||
}
|
||||
battery_hook_add_battery(battery);
|
||||
return device_create_file(&battery->bat->dev, &alarm_attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
@@ -865,7 +874,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
return;
|
||||
}
|
||||
battery_hook_remove_battery(battery);
|
||||
device_remove_file(&battery->bat->dev, &alarm_attr);
|
||||
power_supply_unregister(battery->bat);
|
||||
battery->bat = NULL;
|
||||
mutex_unlock(&battery->sysfs_lock);
|
||||
|
||||
@@ -77,7 +77,6 @@ struct acpi_battery {
|
||||
u16 spec;
|
||||
u8 id;
|
||||
u8 present:1;
|
||||
u8 have_sysfs_alarm:1;
|
||||
};
|
||||
|
||||
#define to_acpi_battery(x) power_supply_get_drvdata(x)
|
||||
@@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct device_attribute alarm_attr = {
|
||||
static struct device_attribute alarm_attr = {
|
||||
.attr = {.name = "alarm", .mode = 0644},
|
||||
.show = acpi_battery_alarm_show,
|
||||
.store = acpi_battery_alarm_store,
|
||||
};
|
||||
|
||||
static struct attribute *acpi_battery_attrs[] = {
|
||||
&alarm_attr.attr,
|
||||
NULL
|
||||
};
|
||||
ATTRIBUTE_GROUPS(acpi_battery);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
@@ -509,7 +514,10 @@ static int acpi_battery_read(struct acpi_battery *battery)
|
||||
static int acpi_battery_add(struct acpi_sbs *sbs, int id)
|
||||
{
|
||||
struct acpi_battery *battery = &sbs->battery[id];
|
||||
struct power_supply_config psy_cfg = { .drv_data = battery, };
|
||||
struct power_supply_config psy_cfg = {
|
||||
.drv_data = battery,
|
||||
.attr_grp = acpi_battery_groups,
|
||||
};
|
||||
int result;
|
||||
|
||||
battery->id = id;
|
||||
@@ -539,10 +547,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
|
||||
goto end;
|
||||
}
|
||||
|
||||
result = device_create_file(&battery->bat->dev, &alarm_attr);
|
||||
if (result)
|
||||
goto end;
|
||||
battery->have_sysfs_alarm = 1;
|
||||
end:
|
||||
pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n",
|
||||
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
|
||||
@@ -554,11 +558,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
|
||||
{
|
||||
struct acpi_battery *battery = &sbs->battery[id];
|
||||
|
||||
if (battery->bat) {
|
||||
if (battery->have_sysfs_alarm)
|
||||
device_remove_file(&battery->bat->dev, &alarm_attr);
|
||||
if (battery->bat)
|
||||
power_supply_unregister(battery->bat);
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_charger_add(struct acpi_sbs *sbs)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/swiotlb.h>
|
||||
@@ -2558,6 +2559,7 @@ static const char *dev_uevent_name(struct kobject *kobj)
|
||||
static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct device_driver *driver;
|
||||
int retval = 0;
|
||||
|
||||
/* add device node properties if present */
|
||||
@@ -2586,8 +2588,12 @@ static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env)
|
||||
if (dev->type && dev->type->name)
|
||||
add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_uevent_var(env, "DRIVER=%s", dev->driver->name);
|
||||
/* Synchronize with module_remove_driver() */
|
||||
rcu_read_lock();
|
||||
driver = READ_ONCE(dev->driver);
|
||||
if (driver)
|
||||
add_uevent_var(env, "DRIVER=%s", driver->name);
|
||||
rcu_read_unlock();
|
||||
|
||||
/* Add common DT information about the device */
|
||||
of_device_uevent(dev, env);
|
||||
@@ -2657,11 +2663,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
|
||||
if (!env)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Synchronize with really_probe() */
|
||||
device_lock(dev);
|
||||
/* let the kset specific function add its keys */
|
||||
retval = kset->uevent_ops->uevent(&dev->kobj, env);
|
||||
device_unlock(dev);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include "base.h"
|
||||
|
||||
static char *make_driver_name(struct device_driver *drv)
|
||||
@@ -77,6 +78,9 @@ void module_remove_driver(struct device_driver *drv)
|
||||
if (!drv)
|
||||
return;
|
||||
|
||||
/* Synchronize with dev_uevent() */
|
||||
synchronize_rcu();
|
||||
|
||||
sysfs_remove_link(&drv->p->kobj, "module");
|
||||
|
||||
if (drv->owner)
|
||||
|
||||
@@ -553,6 +553,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
|
||||
/* Telit FN990 */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
|
||||
.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
|
||||
/* Telit FE990 */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
|
||||
.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
|
||||
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
|
||||
{ PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */
|
||||
|
||||
@@ -529,6 +529,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta)
|
||||
static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct sh_cmt_channel *ch = dev_id;
|
||||
unsigned long flags;
|
||||
|
||||
/* clear flags */
|
||||
sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
|
||||
@@ -559,6 +560,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
|
||||
|
||||
ch->flags &= ~FLAG_SKIPEVENT;
|
||||
|
||||
raw_spin_lock_irqsave(&ch->lock, flags);
|
||||
|
||||
if (ch->flags & FLAG_REPROGRAM) {
|
||||
ch->flags &= ~FLAG_REPROGRAM;
|
||||
sh_cmt_clock_event_program_verify(ch, 1);
|
||||
@@ -571,6 +574,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
|
||||
|
||||
ch->flags &= ~FLAG_IRQCONTEXT;
|
||||
|
||||
raw_spin_unlock_irqrestore(&ch->lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -781,12 +786,18 @@ static int sh_cmt_clock_event_next(unsigned long delta,
|
||||
struct clock_event_device *ced)
|
||||
{
|
||||
struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!clockevent_state_oneshot(ced));
|
||||
|
||||
raw_spin_lock_irqsave(&ch->lock, flags);
|
||||
|
||||
if (likely(ch->flags & FLAG_IRQCONTEXT))
|
||||
ch->next_match_value = delta - 1;
|
||||
else
|
||||
sh_cmt_set_next(ch, delta - 1);
|
||||
__sh_cmt_set_next(ch, delta - 1);
|
||||
|
||||
raw_spin_unlock_irqrestore(&ch->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3631,6 +3631,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
mutex_init(&adev->grbm_idx_mutex);
|
||||
mutex_init(&adev->mn_lock);
|
||||
mutex_init(&adev->virt.vf_errors.lock);
|
||||
mutex_init(&adev->virt.rlcg_reg_lock);
|
||||
hash_init(adev->mn_hash);
|
||||
mutex_init(&adev->psp.mutex);
|
||||
mutex_init(&adev->notifier_lock);
|
||||
|
||||
@@ -1679,12 +1679,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work)
|
||||
int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
|
||||
struct ras_dispatch_if *info)
|
||||
{
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
|
||||
struct ras_ih_data *data = &obj->ih_data;
|
||||
struct ras_manager *obj;
|
||||
struct ras_ih_data *data;
|
||||
|
||||
obj = amdgpu_ras_find_obj(adev, &info->head);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
|
||||
data = &obj->ih_data;
|
||||
|
||||
if (data->inuse == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -956,6 +956,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
|
||||
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
|
||||
scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
|
||||
scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
|
||||
|
||||
mutex_lock(&adev->virt.rlcg_reg_lock);
|
||||
|
||||
if (reg_access_ctrl->spare_int)
|
||||
spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
|
||||
|
||||
@@ -1009,6 +1012,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
|
||||
}
|
||||
|
||||
ret = readl(scratch_reg0);
|
||||
|
||||
mutex_unlock(&adev->virt.rlcg_reg_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -260,6 +260,8 @@ struct amdgpu_virt {
|
||||
|
||||
/* the ucode id to signal the autoload */
|
||||
uint32_t autoload_ucode_id;
|
||||
|
||||
struct mutex rlcg_reg_lock;
|
||||
};
|
||||
|
||||
struct amdgpu_video_codec_info;
|
||||
|
||||
@@ -2636,7 +2636,8 @@ static int dm_suspend(void *handle)
|
||||
|
||||
dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
|
||||
|
||||
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
|
||||
if (dm->cached_dc_state)
|
||||
dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
|
||||
|
||||
amdgpu_dm_commit_zero_streams(dm->dc);
|
||||
|
||||
@@ -6388,7 +6389,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
|
||||
aconnector->dc_sink = aconnector->dc_link->local_sink ?
|
||||
aconnector->dc_link->local_sink :
|
||||
aconnector->dc_em_sink;
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
if (aconnector->dc_sink)
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7121,7 +7123,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
|
||||
drm_add_modes_noedid(connector, 640, 480);
|
||||
} else {
|
||||
amdgpu_dm_connector_ddc_get_modes(connector, edid);
|
||||
amdgpu_dm_connector_add_common_modes(encoder, connector);
|
||||
if (encoder)
|
||||
amdgpu_dm_connector_add_common_modes(encoder, connector);
|
||||
amdgpu_dm_connector_add_freesync_modes(connector, edid);
|
||||
}
|
||||
amdgpu_dm_fbc_init(connector);
|
||||
|
||||
@@ -1255,6 +1255,9 @@ static bool is_dsc_need_re_compute(
|
||||
}
|
||||
}
|
||||
|
||||
if (new_stream_on_link_num == 0)
|
||||
return false;
|
||||
|
||||
/* check current_state if there stream on link but it is not in
|
||||
* new request state
|
||||
*/
|
||||
|
||||
@@ -928,7 +928,7 @@ static int pp_dpm_switch_power_profile(void *handle,
|
||||
enum PP_SMC_POWER_PROFILE type, bool en)
|
||||
{
|
||||
struct pp_hwmgr *hwmgr = handle;
|
||||
long workload;
|
||||
long workload[1];
|
||||
uint32_t index;
|
||||
|
||||
if (!hwmgr || !hwmgr->pm_en)
|
||||
@@ -946,12 +946,12 @@ static int pp_dpm_switch_power_profile(void *handle,
|
||||
hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]);
|
||||
index = fls(hwmgr->workload_mask);
|
||||
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
|
||||
workload = hwmgr->workload_setting[index];
|
||||
workload[0] = hwmgr->workload_setting[index];
|
||||
} else {
|
||||
hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]);
|
||||
index = fls(hwmgr->workload_mask);
|
||||
index = index <= Workload_Policy_Max ? index - 1 : 0;
|
||||
workload = hwmgr->workload_setting[index];
|
||||
workload[0] = hwmgr->workload_setting[index];
|
||||
}
|
||||
|
||||
if (type == PP_SMC_POWER_PROFILE_COMPUTE &&
|
||||
@@ -961,7 +961,7 @@ static int pp_dpm_switch_power_profile(void *handle,
|
||||
}
|
||||
|
||||
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
|
||||
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0);
|
||||
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
|
||||
struct pp_power_state *new_ps)
|
||||
{
|
||||
uint32_t index;
|
||||
long workload;
|
||||
long workload[1];
|
||||
|
||||
if (hwmgr->not_vf) {
|
||||
if (!skip_display_settings)
|
||||
@@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set
|
||||
if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
|
||||
index = fls(hwmgr->workload_mask);
|
||||
index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
|
||||
workload = hwmgr->workload_setting[index];
|
||||
workload[0] = hwmgr->workload_setting[index];
|
||||
|
||||
if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode)
|
||||
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0);
|
||||
if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode)
|
||||
hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2970,6 +2970,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr)
|
||||
|
||||
static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
struct smu7_hwmgr *data;
|
||||
int result = 0;
|
||||
|
||||
@@ -3006,40 +3007,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
|
||||
/* Initalize Dynamic State Adjustment Rule Settings */
|
||||
result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
|
||||
|
||||
if (0 == result) {
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
if (result)
|
||||
goto fail;
|
||||
|
||||
data->is_tlu_enabled = false;
|
||||
data->is_tlu_enabled = false;
|
||||
|
||||
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
|
||||
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
|
||||
SMU7_MAX_HARDWARE_POWERLEVELS;
|
||||
hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
|
||||
hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
|
||||
hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
|
||||
hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
|
||||
|
||||
data->pcie_gen_cap = adev->pm.pcie_gen_mask;
|
||||
if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
data->pcie_spc_cap = 20;
|
||||
else
|
||||
data->pcie_spc_cap = 16;
|
||||
data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
|
||||
data->pcie_gen_cap = adev->pm.pcie_gen_mask;
|
||||
if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
|
||||
data->pcie_spc_cap = 20;
|
||||
else
|
||||
data->pcie_spc_cap = 16;
|
||||
data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
|
||||
|
||||
hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
|
||||
/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
|
||||
hwmgr->platform_descriptor.clockStep.engineClock = 500;
|
||||
hwmgr->platform_descriptor.clockStep.memoryClock = 500;
|
||||
smu7_thermal_parameter_init(hwmgr);
|
||||
} else {
|
||||
/* Ignore return value in here, we are cleaning up a mess. */
|
||||
smu7_hwmgr_backend_fini(hwmgr);
|
||||
}
|
||||
hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
|
||||
/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
|
||||
hwmgr->platform_descriptor.clockStep.engineClock = 500;
|
||||
hwmgr->platform_descriptor.clockStep.memoryClock = 500;
|
||||
smu7_thermal_parameter_init(hwmgr);
|
||||
|
||||
result = smu7_update_edc_leakage_table(hwmgr);
|
||||
if (result) {
|
||||
smu7_hwmgr_backend_fini(hwmgr);
|
||||
return result;
|
||||
}
|
||||
if (result)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
smu7_hwmgr_backend_fini(hwmgr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
|
||||
@@ -3329,8 +3327,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
|
||||
const struct pp_power_state *current_ps)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
struct smu7_power_state *smu7_ps =
|
||||
cast_phw_smu7_power_state(&request_ps->hardware);
|
||||
struct smu7_power_state *smu7_ps;
|
||||
uint32_t sclk;
|
||||
uint32_t mclk;
|
||||
struct PP_Clocks minimum_clocks = {0};
|
||||
@@ -3347,6 +3344,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
|
||||
uint32_t latency;
|
||||
bool latency_allowed = false;
|
||||
|
||||
smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware);
|
||||
if (!smu7_ps)
|
||||
return -EINVAL;
|
||||
|
||||
data->battery_state = (PP_StateUILabel_Battery ==
|
||||
request_ps->classification.ui_label);
|
||||
data->mclk_ignore_signal = false;
|
||||
|
||||
@@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
|
||||
struct pp_power_state *prequest_ps,
|
||||
const struct pp_power_state *pcurrent_ps)
|
||||
{
|
||||
struct smu8_power_state *smu8_ps =
|
||||
cast_smu8_power_state(&prequest_ps->hardware);
|
||||
|
||||
const struct smu8_power_state *smu8_current_ps =
|
||||
cast_const_smu8_power_state(&pcurrent_ps->hardware);
|
||||
|
||||
struct smu8_power_state *smu8_ps;
|
||||
const struct smu8_power_state *smu8_current_ps;
|
||||
struct smu8_hwmgr *data = hwmgr->backend;
|
||||
struct PP_Clocks clocks = {0, 0, 0, 0};
|
||||
bool force_high;
|
||||
|
||||
smu8_ps = cast_smu8_power_state(&prequest_ps->hardware);
|
||||
smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware);
|
||||
|
||||
if (!smu8_ps || !smu8_current_ps)
|
||||
return -EINVAL;
|
||||
|
||||
smu8_ps->need_dfs_bypass = true;
|
||||
|
||||
data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
|
||||
|
||||
@@ -3263,8 +3263,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
|
||||
const struct pp_power_state *current_ps)
|
||||
{
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
struct vega10_power_state *vega10_ps =
|
||||
cast_phw_vega10_power_state(&request_ps->hardware);
|
||||
struct vega10_power_state *vega10_ps;
|
||||
uint32_t sclk;
|
||||
uint32_t mclk;
|
||||
struct PP_Clocks minimum_clocks = {0};
|
||||
@@ -3282,6 +3281,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
|
||||
uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
|
||||
uint32_t latency;
|
||||
|
||||
vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware);
|
||||
if (!vega10_ps)
|
||||
return -EINVAL;
|
||||
|
||||
data->battery_state = (PP_StateUILabel_Battery ==
|
||||
request_ps->classification.ui_label);
|
||||
|
||||
@@ -3419,13 +3422,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co
|
||||
const struct vega10_power_state *vega10_ps =
|
||||
cast_const_phw_vega10_power_state(states->pnew_state);
|
||||
struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
|
||||
uint32_t sclk = vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].gfx_clock;
|
||||
struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
|
||||
uint32_t mclk = vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].mem_clock;
|
||||
uint32_t sclk, mclk;
|
||||
uint32_t i;
|
||||
|
||||
if (vega10_ps == NULL)
|
||||
return -EINVAL;
|
||||
sclk = vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].gfx_clock;
|
||||
mclk = vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].mem_clock;
|
||||
|
||||
for (i = 0; i < sclk_table->count; i++) {
|
||||
if (sclk == sclk_table->dpm_levels[i].value)
|
||||
break;
|
||||
@@ -3732,6 +3739,9 @@ static int vega10_generate_dpm_level_enable_mask(
|
||||
cast_const_phw_vega10_power_state(states->pnew_state);
|
||||
int i;
|
||||
|
||||
if (vega10_ps == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps),
|
||||
"Attempt to Trim DPM States Failed!",
|
||||
return -1);
|
||||
@@ -4999,6 +5009,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr,
|
||||
|
||||
vega10_psa = cast_const_phw_vega10_power_state(pstate1);
|
||||
vega10_psb = cast_const_phw_vega10_power_state(pstate2);
|
||||
if (vega10_psa == NULL || vega10_psb == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the two states don't even have the same number of performance levels
|
||||
* they cannot be the same state.
|
||||
@@ -5132,6 +5144,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
|
||||
return -EINVAL;
|
||||
|
||||
vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
|
||||
if (vega10_ps == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].gfx_clock =
|
||||
@@ -5183,6 +5197,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
|
||||
return -EINVAL;
|
||||
|
||||
vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
|
||||
if (vega10_ps == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
vega10_ps->performance_levels
|
||||
[vega10_ps->performance_level_count - 1].mem_clock =
|
||||
@@ -5424,6 +5440,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
|
||||
return;
|
||||
|
||||
vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
|
||||
if (vega10_ps == NULL)
|
||||
return;
|
||||
|
||||
max_level = vega10_ps->performance_level_count - 1;
|
||||
|
||||
if (vega10_ps->performance_levels[max_level].gfx_clock !=
|
||||
@@ -5446,6 +5465,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
|
||||
|
||||
ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1));
|
||||
vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
|
||||
if (vega10_ps == NULL)
|
||||
return;
|
||||
|
||||
max_level = vega10_ps->performance_level_count - 1;
|
||||
|
||||
if (vega10_ps->performance_levels[max_level].gfx_clock !=
|
||||
@@ -5636,6 +5658,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_
|
||||
return -EINVAL;
|
||||
|
||||
vega10_ps = cast_const_phw_vega10_power_state(state);
|
||||
if (vega10_ps == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
i = index > vega10_ps->performance_level_count - 1 ?
|
||||
vega10_ps->performance_level_count - 1 : index;
|
||||
|
||||
@@ -1834,7 +1834,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
{
|
||||
int ret = 0;
|
||||
int index = 0;
|
||||
long workload;
|
||||
long workload[1];
|
||||
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
|
||||
|
||||
if (!skip_display_settings) {
|
||||
@@ -1874,10 +1874,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu,
|
||||
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
|
||||
index = fls(smu->workload_mask);
|
||||
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
|
||||
workload = smu->workload_setting[index];
|
||||
workload[0] = smu->workload_setting[index];
|
||||
|
||||
if (smu->power_profile_mode != workload)
|
||||
smu_bump_power_profile_mode(smu, &workload, 0);
|
||||
if (smu->power_profile_mode != workload[0])
|
||||
smu_bump_power_profile_mode(smu, workload, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1927,7 +1927,7 @@ static int smu_switch_power_profile(void *handle,
|
||||
{
|
||||
struct smu_context *smu = handle;
|
||||
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
|
||||
long workload;
|
||||
long workload[1];
|
||||
uint32_t index;
|
||||
|
||||
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
|
||||
@@ -1940,17 +1940,17 @@ static int smu_switch_power_profile(void *handle,
|
||||
smu->workload_mask &= ~(1 << smu->workload_prority[type]);
|
||||
index = fls(smu->workload_mask);
|
||||
index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
|
||||
workload = smu->workload_setting[index];
|
||||
workload[0] = smu->workload_setting[index];
|
||||
} else {
|
||||
smu->workload_mask |= (1 << smu->workload_prority[type]);
|
||||
index = fls(smu->workload_mask);
|
||||
index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
|
||||
workload = smu->workload_setting[index];
|
||||
workload[0] = smu->workload_setting[index];
|
||||
}
|
||||
|
||||
if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
|
||||
smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
|
||||
smu_bump_power_profile_mode(smu, &workload, 0);
|
||||
smu_bump_power_profile_mode(smu, workload, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1027,7 +1027,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
|
||||
u32 status_reg;
|
||||
u8 *buffer = msg->buffer;
|
||||
unsigned int i;
|
||||
int num_transferred = 0;
|
||||
int ret;
|
||||
|
||||
/* Buffer size of AUX CH is 16 bytes */
|
||||
@@ -1079,7 +1078,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
|
||||
reg = buffer[i];
|
||||
writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
|
||||
4 * i);
|
||||
num_transferred++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,7 +1125,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
|
||||
reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
|
||||
4 * i);
|
||||
buffer[i] = (unsigned char)reg;
|
||||
num_transferred++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1144,7 +1141,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
|
||||
(msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
|
||||
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
|
||||
|
||||
return num_transferred > 0 ? num_transferred : -EBUSY;
|
||||
return msg->size;
|
||||
|
||||
aux_error:
|
||||
/* if aux err happen, reset aux */
|
||||
|
||||
@@ -4024,6 +4024,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
|
||||
const struct drm_dp_connection_status_notify *conn_stat =
|
||||
&up_req->msg.u.conn_stat;
|
||||
bool handle_csn;
|
||||
|
||||
drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
|
||||
conn_stat->port_number,
|
||||
@@ -4032,6 +4033,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
conn_stat->message_capability_status,
|
||||
conn_stat->input_port,
|
||||
conn_stat->peer_device_type);
|
||||
|
||||
mutex_lock(&mgr->probe_lock);
|
||||
handle_csn = mgr->mst_primary->link_address_sent;
|
||||
mutex_unlock(&mgr->probe_lock);
|
||||
|
||||
if (!handle_csn) {
|
||||
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
|
||||
kfree(up_req);
|
||||
goto out;
|
||||
}
|
||||
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
|
||||
const struct drm_dp_resource_status_notify *res_stat =
|
||||
&up_req->msg.u.resource_stat;
|
||||
|
||||
@@ -873,6 +873,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width,
|
||||
|
||||
kfree(modeset->mode);
|
||||
modeset->mode = drm_mode_duplicate(dev, mode);
|
||||
if (!modeset->mode) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
drm_connector_get(connector);
|
||||
modeset->connectors[modeset->num_connectors++] = connector;
|
||||
modeset->x = offset->x;
|
||||
|
||||
@@ -489,3 +489,4 @@ module_platform_driver(lima_platform_driver);
|
||||
MODULE_AUTHOR("Lima Project Developers");
|
||||
MODULE_DESCRIPTION("Lima DRM Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_SOFTDEP("pre: governor_simpleondemand");
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include "mgag200_drv.h"
|
||||
|
||||
static int mga_i2c_read_gpio(struct mga_device *mdev)
|
||||
@@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data)
|
||||
return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void mgag200_i2c_release(void *res)
|
||||
static void mgag200_i2c_release(struct drm_device *dev, void *res)
|
||||
{
|
||||
struct mga_i2c_chan *i2c = res;
|
||||
|
||||
@@ -115,7 +117,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
|
||||
i2c->adapter.algo_data = &i2c->bit;
|
||||
|
||||
i2c->bit.udelay = 10;
|
||||
i2c->bit.timeout = 2;
|
||||
i2c->bit.timeout = usecs_to_jiffies(2200);
|
||||
i2c->bit.data = i2c;
|
||||
i2c->bit.setsda = mga_gpio_setsda;
|
||||
i2c->bit.setscl = mga_gpio_setscl;
|
||||
@@ -126,5 +128,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c);
|
||||
return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ struct geni_i2c_dev {
|
||||
int cur_wr;
|
||||
int cur_rd;
|
||||
spinlock_t lock;
|
||||
struct clk *core_clk;
|
||||
u32 clk_freq_out;
|
||||
const struct geni_i2c_clk_fld *clk_fld;
|
||||
int suspended;
|
||||
@@ -100,6 +101,13 @@ struct geni_i2c_dev {
|
||||
bool abort_done;
|
||||
};
|
||||
|
||||
struct geni_i2c_desc {
|
||||
bool has_core_clk;
|
||||
char *icc_ddr;
|
||||
bool no_dma_support;
|
||||
unsigned int tx_fifo_depth;
|
||||
};
|
||||
|
||||
struct geni_i2c_err_log {
|
||||
int err;
|
||||
const char *msg;
|
||||
@@ -763,6 +771,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
||||
u32 proto, tx_depth, fifo_disable;
|
||||
int ret;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct geni_i2c_desc *desc = NULL;
|
||||
|
||||
gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL);
|
||||
if (!gi2c)
|
||||
@@ -775,6 +784,14 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(gi2c->se.base))
|
||||
return PTR_ERR(gi2c->se.base);
|
||||
|
||||
desc = device_get_match_data(&pdev->dev);
|
||||
|
||||
if (desc && desc->has_core_clk) {
|
||||
gi2c->core_clk = devm_clk_get(dev, "core");
|
||||
if (IS_ERR(gi2c->core_clk))
|
||||
return PTR_ERR(gi2c->core_clk);
|
||||
}
|
||||
|
||||
gi2c->se.clk = devm_clk_get(dev, "se");
|
||||
if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev))
|
||||
return PTR_ERR(gi2c->se.clk);
|
||||
@@ -818,7 +835,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
||||
gi2c->adap.dev.of_node = dev->of_node;
|
||||
strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
|
||||
|
||||
ret = geni_icc_get(&gi2c->se, "qup-memory");
|
||||
ret = geni_icc_get(&gi2c->se, desc ? desc->icc_ddr : "qup-memory");
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
@@ -828,36 +845,62 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
||||
*/
|
||||
gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW;
|
||||
gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
|
||||
gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out);
|
||||
if (!desc || desc->icc_ddr)
|
||||
gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out);
|
||||
|
||||
ret = geni_icc_set_bw(&gi2c->se);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(gi2c->core_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = geni_se_resources_on(&gi2c->se);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error turning on resources %d\n", ret);
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
return ret;
|
||||
}
|
||||
proto = geni_se_read_proto(&gi2c->se);
|
||||
if (proto != GENI_SE_I2C) {
|
||||
dev_err(dev, "Invalid proto %d\n", proto);
|
||||
geni_se_resources_off(&gi2c->se);
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
|
||||
if (desc && desc->no_dma_support)
|
||||
fifo_disable = false;
|
||||
else
|
||||
fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
|
||||
|
||||
if (fifo_disable) {
|
||||
/* FIFO is disabled, so we can only use GPI DMA */
|
||||
gi2c->gpi_mode = true;
|
||||
ret = setup_gpi_dma(gi2c);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
geni_se_resources_off(&gi2c->se);
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
return dev_err_probe(dev, ret, "Failed to setup GPI DMA mode\n");
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Using GPI DMA mode for I2C\n");
|
||||
} else {
|
||||
gi2c->gpi_mode = false;
|
||||
tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
|
||||
|
||||
/* I2C Master Hub Serial Elements doesn't have the HW_PARAM_0 register */
|
||||
if (!tx_depth && desc)
|
||||
tx_depth = desc->tx_fifo_depth;
|
||||
|
||||
if (!tx_depth) {
|
||||
dev_err(dev, "Invalid TX FIFO depth\n");
|
||||
geni_se_resources_off(&gi2c->se);
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gi2c->tx_wm = tx_depth - 1;
|
||||
geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth);
|
||||
geni_se_config_packing(&gi2c->se, BITS_PER_BYTE,
|
||||
@@ -866,6 +909,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
||||
dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
ret = geni_se_resources_off(&gi2c->se);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error turning off resources %d\n", ret);
|
||||
@@ -931,6 +975,8 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
|
||||
gi2c->suspended = 1;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
|
||||
return geni_icc_disable(&gi2c->se);
|
||||
}
|
||||
|
||||
@@ -943,10 +989,17 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = geni_se_resources_on(&gi2c->se);
|
||||
ret = clk_prepare_enable(gi2c->core_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = geni_se_resources_on(&gi2c->se);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(gi2c->core_clk);
|
||||
geni_icc_disable(&gi2c->se);
|
||||
return ret;
|
||||
}
|
||||
|
||||
enable_irq(gi2c->irq);
|
||||
gi2c->suspended = 0;
|
||||
return 0;
|
||||
|
||||
@@ -34,6 +34,7 @@ static int smbus_do_alert(struct device *dev, void *addrp)
|
||||
struct i2c_client *client = i2c_verify_client(dev);
|
||||
struct alert_data *data = addrp;
|
||||
struct i2c_driver *driver;
|
||||
int ret;
|
||||
|
||||
if (!client || client->addr != data->addr)
|
||||
return 0;
|
||||
@@ -47,16 +48,47 @@ static int smbus_do_alert(struct device *dev, void *addrp)
|
||||
device_lock(dev);
|
||||
if (client->dev.driver) {
|
||||
driver = to_i2c_driver(client->dev.driver);
|
||||
if (driver->alert)
|
||||
if (driver->alert) {
|
||||
/* Stop iterating after we find the device */
|
||||
driver->alert(client, data->type, data->data);
|
||||
else
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
dev_warn(&client->dev, "no driver alert()!\n");
|
||||
} else
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
} else {
|
||||
dev_dbg(&client->dev, "alert with no driver\n");
|
||||
ret = -ENODEV;
|
||||
}
|
||||
device_unlock(dev);
|
||||
|
||||
/* Stop iterating after we find the device */
|
||||
return -EBUSY;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Same as above, but call back all drivers with alert handler */
|
||||
|
||||
static int smbus_do_alert_force(struct device *dev, void *addrp)
|
||||
{
|
||||
struct i2c_client *client = i2c_verify_client(dev);
|
||||
struct alert_data *data = addrp;
|
||||
struct i2c_driver *driver;
|
||||
|
||||
if (!client || (client->flags & I2C_CLIENT_TEN))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Drivers should either disable alerts, or provide at least
|
||||
* a minimal handler. Lock so the driver won't change.
|
||||
*/
|
||||
device_lock(dev);
|
||||
if (client->dev.driver) {
|
||||
driver = to_i2c_driver(client->dev.driver);
|
||||
if (driver->alert)
|
||||
driver->alert(client, data->type, data->data);
|
||||
}
|
||||
device_unlock(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -67,6 +99,7 @@ static irqreturn_t smbus_alert(int irq, void *d)
|
||||
{
|
||||
struct i2c_smbus_alert *alert = d;
|
||||
struct i2c_client *ara;
|
||||
unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */
|
||||
|
||||
ara = alert->ara;
|
||||
|
||||
@@ -94,8 +127,25 @@ static irqreturn_t smbus_alert(int irq, void *d)
|
||||
data.addr, data.data);
|
||||
|
||||
/* Notify driver for the device which issued the alert */
|
||||
device_for_each_child(&ara->adapter->dev, &data,
|
||||
smbus_do_alert);
|
||||
status = device_for_each_child(&ara->adapter->dev, &data,
|
||||
smbus_do_alert);
|
||||
/*
|
||||
* If we read the same address more than once, and the alert
|
||||
* was not handled by a driver, it won't do any good to repeat
|
||||
* the loop because it will never terminate. Try again, this
|
||||
* time calling the alert handlers of all devices connected to
|
||||
* the bus, and abort the loop afterwards. If this helps, we
|
||||
* are all set. If it doesn't, there is nothing else we can do,
|
||||
* so we might as well abort the loop.
|
||||
* Note: This assumes that a driver with alert handler handles
|
||||
* the alert properly and clears it if necessary.
|
||||
*/
|
||||
if (data.addr == prev_addr && status != -EBUSY) {
|
||||
device_for_each_child(&ara->adapter->dev, &data,
|
||||
smbus_do_alert_force);
|
||||
break;
|
||||
}
|
||||
prev_addr = data.addr;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle;
|
||||
|
||||
static u32 lpic_gsi_to_irq(u32 gsi)
|
||||
{
|
||||
int irq = 0;
|
||||
|
||||
/* Only pch irqdomain transferring is required for LoongArch. */
|
||||
if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ)
|
||||
return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
|
||||
irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
|
||||
|
||||
return 0;
|
||||
return (irq > 0) ? irq : 0;
|
||||
}
|
||||
|
||||
static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi)
|
||||
|
||||
@@ -64,6 +64,20 @@ struct mbigen_device {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static inline unsigned int get_mbigen_node_offset(unsigned int nid)
|
||||
{
|
||||
unsigned int offset = nid * MBIGEN_NODE_OFFSET;
|
||||
|
||||
/*
|
||||
* To avoid touched clear register in unexpected way, we need to directly
|
||||
* skip clear register when access to more than 10 mbigen nodes.
|
||||
*/
|
||||
if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET))
|
||||
offset += MBIGEN_NODE_OFFSET;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
|
||||
{
|
||||
unsigned int nid, pin;
|
||||
@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
|
||||
nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
|
||||
pin = hwirq % IRQS_PER_MBIGEN_NODE;
|
||||
|
||||
return pin * 4 + nid * MBIGEN_NODE_OFFSET
|
||||
+ REG_MBIGEN_VEC_OFFSET;
|
||||
return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET;
|
||||
}
|
||||
|
||||
static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
|
||||
@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
|
||||
*mask = 1 << (irq_ofst % 32);
|
||||
ofst = irq_ofst / 32 * 4;
|
||||
|
||||
*addr = ofst + nid * MBIGEN_NODE_OFFSET
|
||||
+ REG_MBIGEN_TYPE_OFFSET;
|
||||
*addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
|
||||
|
||||
@@ -168,7 +168,7 @@ struct meson_gpio_irq_controller {
|
||||
void __iomem *base;
|
||||
u32 channel_irqs[MAX_NUM_CHANNEL];
|
||||
DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
|
||||
spinlock_t lock;
|
||||
raw_spinlock_t lock;
|
||||
};
|
||||
|
||||
static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
|
||||
@@ -177,14 +177,14 @@ static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
|
||||
unsigned long flags;
|
||||
u32 tmp;
|
||||
|
||||
spin_lock_irqsave(&ctl->lock, flags);
|
||||
raw_spin_lock_irqsave(&ctl->lock, flags);
|
||||
|
||||
tmp = readl_relaxed(ctl->base + reg);
|
||||
tmp &= ~mask;
|
||||
tmp |= val;
|
||||
writel_relaxed(tmp, ctl->base + reg);
|
||||
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
}
|
||||
|
||||
static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
|
||||
@@ -234,12 +234,12 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
|
||||
unsigned long flags;
|
||||
unsigned int idx;
|
||||
|
||||
spin_lock_irqsave(&ctl->lock, flags);
|
||||
raw_spin_lock_irqsave(&ctl->lock, flags);
|
||||
|
||||
/* Find a free channel */
|
||||
idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
|
||||
if (idx >= ctl->params->nr_channels) {
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
pr_err("No channel available\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
@@ -247,7 +247,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
|
||||
/* Mark the channel as used */
|
||||
set_bit(idx, ctl->channel_map);
|
||||
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
|
||||
/*
|
||||
* Setup the mux of the channel to route the signal of the pad
|
||||
@@ -557,7 +557,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
|
||||
if (!ctl)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&ctl->lock);
|
||||
raw_spin_lock_init(&ctl->lock);
|
||||
|
||||
ctl->base = of_iomap(node, 0);
|
||||
if (!ctl->base) {
|
||||
|
||||
@@ -189,7 +189,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
|
||||
irqc->intr_mask = 0;
|
||||
}
|
||||
|
||||
if (irqc->intr_mask >> irqc->nr_irq)
|
||||
if ((u64)irqc->intr_mask >> irqc->nr_irq)
|
||||
pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
|
||||
|
||||
pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n",
|
||||
|
||||
@@ -489,7 +489,6 @@ void mddev_suspend(struct mddev *mddev)
|
||||
clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags);
|
||||
wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags));
|
||||
|
||||
del_timer_sync(&mddev->safemode_timer);
|
||||
/* restrict memory reclaim I/O during raid array is suspend */
|
||||
mddev->noio_flag = memalloc_noio_save();
|
||||
}
|
||||
|
||||
@@ -6316,7 +6316,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
|
||||
safepos = conf->reshape_safe;
|
||||
sector_div(safepos, data_disks);
|
||||
if (mddev->reshape_backwards) {
|
||||
BUG_ON(writepos < reshape_sectors);
|
||||
if (WARN_ON(writepos < reshape_sectors))
|
||||
return MaxSector;
|
||||
|
||||
writepos -= reshape_sectors;
|
||||
readpos += reshape_sectors;
|
||||
safepos += reshape_sectors;
|
||||
@@ -6334,14 +6336,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk
|
||||
* to set 'stripe_addr' which is where we will write to.
|
||||
*/
|
||||
if (mddev->reshape_backwards) {
|
||||
BUG_ON(conf->reshape_progress == 0);
|
||||
if (WARN_ON(conf->reshape_progress == 0))
|
||||
return MaxSector;
|
||||
|
||||
stripe_addr = writepos;
|
||||
BUG_ON((mddev->dev_sectors &
|
||||
~((sector_t)reshape_sectors - 1))
|
||||
- reshape_sectors - stripe_addr
|
||||
!= sector_nr);
|
||||
if (WARN_ON((mddev->dev_sectors &
|
||||
~((sector_t)reshape_sectors - 1)) -
|
||||
reshape_sectors - stripe_addr != sector_nr))
|
||||
return MaxSector;
|
||||
} else {
|
||||
BUG_ON(writepos != sector_nr + reshape_sectors);
|
||||
if (WARN_ON(writepos != sector_nr + reshape_sectors))
|
||||
return MaxSector;
|
||||
|
||||
stripe_addr = sector_nr;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
struct vdec_t *vdec = inst->priv;
|
||||
int ret = 0;
|
||||
|
||||
vpu_inst_lock(inst);
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:
|
||||
vdec->params.display_delay_enable = ctrl->val;
|
||||
@@ -157,7 +156,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
vpu_inst_unlock(inst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -528,7 +528,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
struct venc_t *venc = inst->priv;
|
||||
int ret = 0;
|
||||
|
||||
vpu_inst_lock(inst);
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
||||
venc->params.profile = ctrl->val;
|
||||
@@ -589,7 +588,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
vpu_inst_unlock(inst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1361,9 +1361,16 @@ static void load_firmware_cb(const struct firmware *fw,
|
||||
void *context)
|
||||
{
|
||||
struct dvb_frontend *fe = context;
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
struct xc2028_data *priv;
|
||||
int rc;
|
||||
|
||||
if (!fe) {
|
||||
pr_warn("xc2028: No frontend in %s\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = fe->tuner_priv;
|
||||
|
||||
tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
|
||||
if (!fw) {
|
||||
tuner_err("Could not load firmware %s.\n", priv->fname);
|
||||
|
||||
@@ -212,13 +212,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
|
||||
* Compute a bandwidth estimation by multiplying the frame
|
||||
* size by the number of video frames per second, divide the
|
||||
* result by the number of USB frames (or micro-frames for
|
||||
* high-speed devices) per second and add the UVC header size
|
||||
* (assumed to be 12 bytes long).
|
||||
* high- and super-speed devices) per second and add the UVC
|
||||
* header size (assumed to be 12 bytes long).
|
||||
*/
|
||||
bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
|
||||
bandwidth *= 10000000 / interval + 1;
|
||||
bandwidth /= 1000;
|
||||
if (stream->dev->udev->speed == USB_SPEED_HIGH)
|
||||
if (stream->dev->udev->speed >= USB_SPEED_HIGH)
|
||||
bandwidth /= 8;
|
||||
bandwidth += 12;
|
||||
|
||||
@@ -476,6 +476,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
|
||||
ktime_t time;
|
||||
u16 host_sof;
|
||||
u16 dev_sof;
|
||||
u32 dev_stc;
|
||||
|
||||
switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
|
||||
case UVC_STREAM_PTS | UVC_STREAM_SCR:
|
||||
@@ -522,6 +523,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
|
||||
if (dev_sof == stream->clock.last_sof)
|
||||
return;
|
||||
|
||||
dev_stc = get_unaligned_le32(&data[header_size - 6]);
|
||||
|
||||
/*
|
||||
* STC (Source Time Clock) is the clock used by the camera. The UVC 1.5
|
||||
* standard states that it "must be captured when the first video data
|
||||
* of a video frame is put on the USB bus". This is generally understood
|
||||
* as requiring devices to clear the payload header's SCR bit before
|
||||
* the first packet containing video data.
|
||||
*
|
||||
* Most vendors follow that interpretation, but some (namely SunplusIT
|
||||
* on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR
|
||||
* field with 0's,and expect that the driver only processes the SCR if
|
||||
* there is data in the packet.
|
||||
*
|
||||
* Ignore all the hardware timestamp information if we haven't received
|
||||
* any data for this frame yet, the packet contains no data, and both
|
||||
* STC and SOF are zero. This heuristics should be safe on compliant
|
||||
* devices. This should be safe with compliant devices, as in the very
|
||||
* unlikely case where a UVC 1.1 device would send timing information
|
||||
* only before the first packet containing data, and both STC and SOF
|
||||
* happen to be zero for a particular frame, we would only miss one
|
||||
* clock sample from many and the clock recovery algorithm wouldn't
|
||||
* suffer from this condition.
|
||||
*/
|
||||
if (buf && buf->bytesused == 0 && len == header_size &&
|
||||
dev_stc == 0 && dev_sof == 0)
|
||||
return;
|
||||
|
||||
stream->clock.last_sof = dev_sof;
|
||||
|
||||
host_sof = usb_get_current_frame_number(stream->dev->udev);
|
||||
@@ -560,7 +589,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
|
||||
spin_lock_irqsave(&stream->clock.lock, flags);
|
||||
|
||||
sample = &stream->clock.samples[stream->clock.head];
|
||||
sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
|
||||
sample->dev_stc = dev_stc;
|
||||
sample->dev_sof = dev_sof;
|
||||
sample->host_sof = host_sof;
|
||||
sample->host_time = time;
|
||||
|
||||
@@ -475,6 +475,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
|
||||
clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
|
||||
}
|
||||
|
||||
tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) -
|
||||
ilog2(tx_ring->obj_num);
|
||||
tx_ring->obj_size = tx_obj_size;
|
||||
|
||||
rem = priv->rx_obj_num;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
|
||||
//
|
||||
// Copyright (c) 2019, 2020, 2021 Pengutronix,
|
||||
// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
|
||||
// Marc Kleine-Budde <kernel@pengutronix.de>
|
||||
//
|
||||
// Based on:
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
#include "mcp251xfd.h"
|
||||
|
||||
static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta)
|
||||
{
|
||||
return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
|
||||
}
|
||||
|
||||
static inline int
|
||||
mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv,
|
||||
u8 *tef_tail)
|
||||
@@ -55,56 +60,39 @@ static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
|
||||
{
|
||||
const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||
u32 tef_sta;
|
||||
int err;
|
||||
|
||||
err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) {
|
||||
netdev_err(priv->ndev,
|
||||
"Transmit Event FIFO buffer overflow.\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
netdev_info(priv->ndev,
|
||||
"Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n",
|
||||
tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ?
|
||||
"full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ?
|
||||
"not empty" : "empty",
|
||||
seq, priv->tef->tail, priv->tef->head, tx_ring->head);
|
||||
|
||||
/* The Sequence Number in the TEF doesn't match our tef_tail. */
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
static int
|
||||
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
||||
const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
|
||||
unsigned int *frame_len_ptr)
|
||||
{
|
||||
struct net_device_stats *stats = &priv->ndev->stats;
|
||||
u32 seq, tef_tail_masked, tef_tail;
|
||||
struct sk_buff *skb;
|
||||
u32 seq, seq_masked, tef_tail_masked, tef_tail;
|
||||
|
||||
seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK,
|
||||
/* Use the MCP2517FD mask on the MCP2518FD, too. We only
|
||||
* compare 7 bits, this is enough to detect old TEF objects.
|
||||
*/
|
||||
seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK,
|
||||
hw_tef_obj->flags);
|
||||
|
||||
/* Use the MCP2517FD mask on the MCP2518FD, too. We only
|
||||
* compare 7 bits, this should be enough to detect
|
||||
* net-yet-completed, i.e. old TEF objects.
|
||||
*/
|
||||
seq_masked = seq &
|
||||
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
|
||||
tef_tail_masked = priv->tef->tail &
|
||||
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
|
||||
if (seq_masked != tef_tail_masked)
|
||||
return mcp251xfd_handle_tefif_recover(priv, seq);
|
||||
|
||||
/* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
|
||||
* bits of a FIFOSTA register, here the TX FIFO tail index
|
||||
* might be corrupted and we might process past the TEF FIFO's
|
||||
* head into old CAN frames.
|
||||
*
|
||||
* Compare the sequence number of the currently processed CAN
|
||||
* frame with the expected sequence number. Abort with
|
||||
* -EBADMSG if an old CAN frame is detected.
|
||||
*/
|
||||
if (seq != tef_tail_masked) {
|
||||
netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__,
|
||||
seq, tef_tail_masked);
|
||||
stats->tx_fifo_errors++;
|
||||
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
tef_tail = mcp251xfd_get_tef_tail(priv);
|
||||
skb = priv->can.echo_skb[tef_tail];
|
||||
@@ -120,28 +108,44 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv)
|
||||
static int
|
||||
mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p)
|
||||
{
|
||||
const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||
unsigned int new_head;
|
||||
u8 chip_tx_tail;
|
||||
const u8 shift = tx_ring->obj_num_shift_to_u8;
|
||||
u8 chip_tx_tail, tail, len;
|
||||
u32 fifo_sta;
|
||||
int err;
|
||||
|
||||
err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail);
|
||||
err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr),
|
||||
&fifo_sta);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* chip_tx_tail, is the next TX-Object send by the HW.
|
||||
* The new TEF head must be >= the old head, ...
|
||||
if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) {
|
||||
*len_p = tx_ring->obj_num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
|
||||
|
||||
err = mcp251xfd_check_tef_tail(priv);
|
||||
if (err)
|
||||
return err;
|
||||
tail = mcp251xfd_get_tef_tail(priv);
|
||||
|
||||
/* First shift to full u8. The subtraction works on signed
|
||||
* values, that keeps the difference steady around the u8
|
||||
* overflow. The right shift acts on len, which is an u8.
|
||||
*/
|
||||
new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail;
|
||||
if (new_head <= priv->tef->head)
|
||||
new_head += tx_ring->obj_num;
|
||||
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail));
|
||||
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail));
|
||||
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len));
|
||||
|
||||
/* ... but it cannot exceed the TX head. */
|
||||
priv->tef->head = min(new_head, tx_ring->head);
|
||||
len = (chip_tx_tail << shift) - (tail << shift);
|
||||
*len_p = len >> shift;
|
||||
|
||||
return mcp251xfd_check_tef_tail(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -182,13 +186,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||
u8 tef_tail, len, l;
|
||||
int err, i;
|
||||
|
||||
err = mcp251xfd_tef_ring_update(priv);
|
||||
err = mcp251xfd_get_tef_len(priv, &len);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tef_tail = mcp251xfd_get_tef_tail(priv);
|
||||
len = mcp251xfd_get_tef_len(priv);
|
||||
l = mcp251xfd_get_tef_linear_len(priv);
|
||||
l = mcp251xfd_get_tef_linear_len(priv, len);
|
||||
err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -203,12 +206,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||
unsigned int frame_len = 0;
|
||||
|
||||
err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
|
||||
/* -EAGAIN means the Sequence Number in the TEF
|
||||
* doesn't match our tef_tail. This can happen if we
|
||||
* read the TEF objects too early. Leave loop let the
|
||||
* interrupt handler call us again.
|
||||
/* -EBADMSG means we're affected by mcp2518fd erratum
|
||||
* DS80000789E 6., i.e. the Sequence Number in the TEF
|
||||
* doesn't match our tef_tail. Don't process any
|
||||
* further and mark processed frames as good.
|
||||
*/
|
||||
if (err == -EAGAIN)
|
||||
if (err == -EBADMSG)
|
||||
goto out_netif_wake_queue;
|
||||
if (err)
|
||||
return err;
|
||||
@@ -223,6 +226,8 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
||||
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||
int offset;
|
||||
|
||||
ring->head += len;
|
||||
|
||||
/* Increment the TEF FIFO tail pointer 'len' times in
|
||||
* a single SPI message.
|
||||
*
|
||||
|
||||
@@ -519,6 +519,7 @@ struct mcp251xfd_tef_ring {
|
||||
|
||||
/* u8 obj_num equals tx_ring->obj_num */
|
||||
/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
|
||||
/* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */
|
||||
|
||||
union mcp251xfd_write_reg_buf irq_enable_buf;
|
||||
struct spi_transfer irq_enable_xfer;
|
||||
@@ -537,6 +538,7 @@ struct mcp251xfd_tx_ring {
|
||||
u8 nr;
|
||||
u8 fifo_nr;
|
||||
u8 obj_num;
|
||||
u8 obj_num_shift_to_u8;
|
||||
u8 obj_size;
|
||||
|
||||
struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX];
|
||||
@@ -843,17 +845,8 @@ static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv)
|
||||
return priv->tef->tail & (priv->tx->obj_num - 1);
|
||||
}
|
||||
|
||||
static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv)
|
||||
static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len)
|
||||
{
|
||||
return priv->tef->head - priv->tef->tail;
|
||||
}
|
||||
|
||||
static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv)
|
||||
{
|
||||
u8 len;
|
||||
|
||||
len = mcp251xfd_get_tef_len(priv);
|
||||
|
||||
return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv));
|
||||
}
|
||||
|
||||
|
||||
@@ -678,8 +678,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
|
||||
of_remove_property(child, prop);
|
||||
|
||||
phydev = of_phy_find_device(child);
|
||||
if (phydev)
|
||||
if (phydev) {
|
||||
phy_device_remove(phydev);
|
||||
phy_device_free(phydev);
|
||||
}
|
||||
}
|
||||
|
||||
err = mdiobus_register(priv->slave_mii_bus);
|
||||
|
||||
@@ -635,6 +635,9 @@ void fec_ptp_stop(struct platform_device *pdev)
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
|
||||
if (fep->pps_enable)
|
||||
fec_ptp_enable_pps(fep, 0);
|
||||
|
||||
cancel_delayed_work_sync(&fep->time_keep);
|
||||
if (fep->ptp_clock)
|
||||
ptp_clock_unregister(fep->ptp_clock);
|
||||
|
||||
@@ -2146,6 +2146,9 @@ mpwrq_cqe_out:
|
||||
if (likely(wi->consumed_strides < rq->mpwqe.num_strides))
|
||||
return;
|
||||
|
||||
if (unlikely(!cstrides))
|
||||
return;
|
||||
|
||||
wq = &rq->mpwqe.wq;
|
||||
wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
|
||||
mlx5e_free_rx_mpwqe(rq, wi, true);
|
||||
|
||||
@@ -200,6 +200,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||
break;
|
||||
default:
|
||||
/* not ip - do not know what to do */
|
||||
kfree_skb(skbn);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
||||
@@ -873,9 +873,9 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req,
|
||||
struct nvme_command *cmnd)
|
||||
{
|
||||
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
|
||||
struct bio_vec bv = rq_integrity_vec(req);
|
||||
|
||||
iod->meta_dma = dma_map_bvec(dev->dev, rq_integrity_vec(req),
|
||||
rq_dma_dir(req), 0);
|
||||
iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0);
|
||||
if (dma_mapping_error(dev->dev, iod->meta_dma))
|
||||
return BLK_STS_IOERR;
|
||||
cmnd->rw.metadata = cpu_to_le64(iod->meta_dma);
|
||||
@@ -1016,7 +1016,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req)
|
||||
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
|
||||
|
||||
dma_unmap_page(dev->dev, iod->meta_dma,
|
||||
rq_integrity_vec(req)->bv_len, rq_dma_dir(req));
|
||||
rq_integrity_vec(req).bv_len, rq_dma_dir(req));
|
||||
}
|
||||
|
||||
if (blk_rq_nr_phys_segments(req))
|
||||
|
||||
@@ -157,9 +157,17 @@ union ifs_chunks_auth_status {
|
||||
union ifs_scan {
|
||||
u64 data;
|
||||
struct {
|
||||
u32 start :8;
|
||||
u32 stop :8;
|
||||
u32 rsvd :16;
|
||||
union {
|
||||
struct {
|
||||
u8 start;
|
||||
u8 stop;
|
||||
u16 rsvd;
|
||||
} gen0;
|
||||
struct {
|
||||
u16 start;
|
||||
u16 stop;
|
||||
} gen2;
|
||||
};
|
||||
u32 delay :31;
|
||||
u32 sigmce :1;
|
||||
};
|
||||
@@ -169,9 +177,17 @@ union ifs_scan {
|
||||
union ifs_status {
|
||||
u64 data;
|
||||
struct {
|
||||
u32 chunk_num :8;
|
||||
u32 chunk_stop_index :8;
|
||||
u32 rsvd1 :16;
|
||||
union {
|
||||
struct {
|
||||
u8 chunk_num;
|
||||
u8 chunk_stop_index;
|
||||
u16 rsvd1;
|
||||
} gen0;
|
||||
struct {
|
||||
u16 chunk_num;
|
||||
u16 chunk_stop_index;
|
||||
} gen2;
|
||||
};
|
||||
u32 error_code :8;
|
||||
u32 rsvd2 :22;
|
||||
u32 control_error :1;
|
||||
|
||||
@@ -165,25 +165,35 @@ static int doscan(void *data)
|
||||
*/
|
||||
static void ifs_test_core(int cpu, struct device *dev)
|
||||
{
|
||||
union ifs_status status = {};
|
||||
union ifs_scan activate;
|
||||
union ifs_status status;
|
||||
unsigned long timeout;
|
||||
struct ifs_data *ifsd;
|
||||
int to_start, to_stop;
|
||||
int status_chunk;
|
||||
u64 msrvals[2];
|
||||
int retries;
|
||||
|
||||
ifsd = ifs_get_data(dev);
|
||||
|
||||
activate.rsvd = 0;
|
||||
activate.gen0.rsvd = 0;
|
||||
activate.delay = IFS_THREAD_WAIT;
|
||||
activate.sigmce = 0;
|
||||
activate.start = 0;
|
||||
activate.stop = ifsd->valid_chunks - 1;
|
||||
to_start = 0;
|
||||
to_stop = ifsd->valid_chunks - 1;
|
||||
|
||||
if (ifsd->generation) {
|
||||
activate.gen2.start = to_start;
|
||||
activate.gen2.stop = to_stop;
|
||||
} else {
|
||||
activate.gen0.start = to_start;
|
||||
activate.gen0.stop = to_stop;
|
||||
}
|
||||
|
||||
timeout = jiffies + HZ / 2;
|
||||
retries = MAX_IFS_RETRIES;
|
||||
|
||||
while (activate.start <= activate.stop) {
|
||||
while (to_start <= to_stop) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
status.error_code = IFS_SW_TIMEOUT;
|
||||
break;
|
||||
@@ -194,13 +204,14 @@ static void ifs_test_core(int cpu, struct device *dev)
|
||||
|
||||
status.data = msrvals[1];
|
||||
|
||||
trace_ifs_status(cpu, activate, status);
|
||||
trace_ifs_status(cpu, to_start, to_stop, status.data);
|
||||
|
||||
/* Some cases can be retried, give up for others */
|
||||
if (!can_restart(status))
|
||||
break;
|
||||
|
||||
if (status.chunk_num == activate.start) {
|
||||
status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num;
|
||||
if (status_chunk == to_start) {
|
||||
/* Check for forward progress */
|
||||
if (--retries == 0) {
|
||||
if (status.error_code == IFS_NO_ERROR)
|
||||
@@ -209,7 +220,11 @@ static void ifs_test_core(int cpu, struct device *dev)
|
||||
}
|
||||
} else {
|
||||
retries = MAX_IFS_RETRIES;
|
||||
activate.start = status.chunk_num;
|
||||
if (ifsd->generation)
|
||||
activate.gen2.start = status_chunk;
|
||||
else
|
||||
activate.gen0.start = status_chunk;
|
||||
to_start = status_chunk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,18 +178,18 @@ static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv)
|
||||
u8 reg_val;
|
||||
int ret;
|
||||
|
||||
if (cv <= CV_4100MV) {
|
||||
reg_val = CHRG_CCCV_CV_4100MV;
|
||||
cv = CV_4100MV;
|
||||
} else if (cv <= CV_4150MV) {
|
||||
reg_val = CHRG_CCCV_CV_4150MV;
|
||||
cv = CV_4150MV;
|
||||
} else if (cv <= CV_4200MV) {
|
||||
reg_val = CHRG_CCCV_CV_4200MV;
|
||||
cv = CV_4200MV;
|
||||
} else {
|
||||
if (cv >= CV_4350MV) {
|
||||
reg_val = CHRG_CCCV_CV_4350MV;
|
||||
cv = CV_4350MV;
|
||||
} else if (cv >= CV_4200MV) {
|
||||
reg_val = CHRG_CCCV_CV_4200MV;
|
||||
cv = CV_4200MV;
|
||||
} else if (cv >= CV_4150MV) {
|
||||
reg_val = CHRG_CCCV_CV_4150MV;
|
||||
cv = CV_4150MV;
|
||||
} else {
|
||||
reg_val = CHRG_CCCV_CV_4100MV;
|
||||
cv = CV_4100MV;
|
||||
}
|
||||
|
||||
reg_val = reg_val << CHRG_CCCV_CV_BIT_POS;
|
||||
@@ -337,8 +337,8 @@ static int axp288_charger_usb_set_property(struct power_supply *psy,
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
|
||||
scaled_val = min(val->intval, info->max_cv);
|
||||
scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000);
|
||||
scaled_val = DIV_ROUND_CLOSEST(val->intval, 1000);
|
||||
scaled_val = min(scaled_val, info->max_cv);
|
||||
ret = axp288_charger_set_cv(info, scaled_val);
|
||||
if (ret < 0) {
|
||||
dev_warn(&info->pdev->dev, "set charge voltage failed\n");
|
||||
|
||||
@@ -320,8 +320,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di)
|
||||
&esize);
|
||||
if (rc) {
|
||||
/* Cancel running request if interrupted */
|
||||
if (rc == -ERESTARTSYS)
|
||||
sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL);
|
||||
if (rc == -ERESTARTSYS) {
|
||||
if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) {
|
||||
pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n",
|
||||
(size_t)dsize * PAGE_SIZE);
|
||||
data = NULL;
|
||||
asce = 0;
|
||||
}
|
||||
}
|
||||
vfree(data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3389,6 +3389,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,
|
||||
scmd->sc_data_direction);
|
||||
priv->meta_sg_valid = 1; /* To unmap meta sg DMA */
|
||||
} else {
|
||||
/*
|
||||
* Some firmware versions byte-swap the REPORT ZONES command
|
||||
* reply from ATA-ZAC devices by directly accessing in the host
|
||||
* buffer. This does not respect the default command DMA
|
||||
* direction and causes IOMMU page faults on some architectures
|
||||
* with an IOMMU enforcing write mappings (e.g. AMD hosts).
|
||||
* Avoid such issue by making the REPORT ZONES buffer mapping
|
||||
* bi-directional.
|
||||
*/
|
||||
if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES)
|
||||
scmd->sc_data_direction = DMA_BIDIRECTIONAL;
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
}
|
||||
|
||||
@@ -2672,6 +2672,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
|
||||
_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
|
||||
}
|
||||
|
||||
static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd)
|
||||
{
|
||||
/*
|
||||
* Some firmware versions byte-swap the REPORT ZONES command reply from
|
||||
* ATA-ZAC devices by directly accessing in the host buffer. This does
|
||||
* not respect the default command DMA direction and causes IOMMU page
|
||||
* faults on some architectures with an IOMMU enforcing write mappings
|
||||
* (e.g. AMD hosts). Avoid such issue by making the report zones buffer
|
||||
* mapping bi-directional.
|
||||
*/
|
||||
if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES)
|
||||
cmd->sc_data_direction = DMA_BIDIRECTIONAL;
|
||||
|
||||
return scsi_dma_map(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* _base_build_sg_scmd - main sg creation routine
|
||||
* pcie_device is unused here!
|
||||
@@ -2718,7 +2734,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
|
||||
sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;
|
||||
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
sges_left = _base_scsi_dma_map(scmd);
|
||||
if (sges_left < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2862,7 +2878,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
|
||||
}
|
||||
|
||||
sg_scmd = scsi_sglist(scmd);
|
||||
sges_left = scsi_dma_map(scmd);
|
||||
sges_left = _base_scsi_dma_map(scmd);
|
||||
if (sges_left < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
|
||||
static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
|
||||
{
|
||||
struct lpspi_config config = fsl_lpspi->config;
|
||||
unsigned int perclk_rate, scldiv;
|
||||
unsigned int perclk_rate, scldiv, div;
|
||||
u8 prescale;
|
||||
|
||||
perclk_rate = clk_get_rate(fsl_lpspi->clk_per);
|
||||
@@ -308,8 +308,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
|
||||
|
||||
for (prescale = 0; prescale < 8; prescale++) {
|
||||
scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2;
|
||||
scldiv = div / (1 << prescale) - 2;
|
||||
if (scldiv < 256) {
|
||||
fsl_lpspi->config.prescale = prescale;
|
||||
break;
|
||||
|
||||
@@ -692,6 +692,7 @@ static const struct file_operations spidev_fops = {
|
||||
static struct class *spidev_class;
|
||||
|
||||
static const struct spi_device_id spidev_spi_ids[] = {
|
||||
{ .name = "bh2228fv" },
|
||||
{ .name = "dh2228fv" },
|
||||
{ .name = "ltc2488" },
|
||||
{ .name = "sx1301" },
|
||||
|
||||
@@ -846,6 +846,14 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
|
||||
new_flags = (__force upf_t)new_info->flags;
|
||||
old_custom_divisor = uport->custom_divisor;
|
||||
|
||||
if (!(uport->flags & UPF_FIXED_PORT)) {
|
||||
unsigned int uartclk = new_info->baud_base * 16;
|
||||
/* check needs to be done here before other settings made */
|
||||
if (uartclk == 0) {
|
||||
retval = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (!capable(CAP_SYS_ADMIN)) {
|
||||
retval = -EPERM;
|
||||
if (change_irq || change_port ||
|
||||
|
||||
@@ -4074,11 +4074,16 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba)
|
||||
min_sleep_time_us =
|
||||
MIN_DELAY_BEFORE_DME_CMDS_US - delta;
|
||||
else
|
||||
return; /* no more delay required */
|
||||
min_sleep_time_us = 0; /* no more delay required */
|
||||
}
|
||||
|
||||
/* allow sleep for extra 50us if needed */
|
||||
usleep_range(min_sleep_time_us, min_sleep_time_us + 50);
|
||||
if (min_sleep_time_us > 0) {
|
||||
/* allow sleep for extra 50us if needed */
|
||||
usleep_range(min_sleep_time_us, min_sleep_time_us + 50);
|
||||
}
|
||||
|
||||
/* update the last_dme_cmd_tstamp */
|
||||
hba->last_dme_cmd_tstamp = ktime_get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev)
|
||||
struct usb_ep *ep, *ep_fback;
|
||||
struct uac_rtd_params *prm;
|
||||
struct uac_params *params = &audio_dev->params;
|
||||
int req_len, i;
|
||||
int req_len, i, ret;
|
||||
|
||||
prm = &uac->c_prm;
|
||||
dev_dbg(dev, "start capture with rate %d\n", prm->srate);
|
||||
ep = audio_dev->out_ep;
|
||||
config_ep_by_speed(gadget, &audio_dev->func, ep);
|
||||
ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
req_len = ep->maxpacket;
|
||||
|
||||
prm->ep_enabled = true;
|
||||
usb_ep_enable(ep);
|
||||
ret = usb_ep_enable(ep);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < params->req_number; i++) {
|
||||
if (!prm->reqs[i]) {
|
||||
@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev)
|
||||
return 0;
|
||||
|
||||
/* Setup feedback endpoint */
|
||||
config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
|
||||
ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret);
|
||||
return ret; // TODO: Clean up out_ep
|
||||
}
|
||||
|
||||
prm->fb_ep_enabled = true;
|
||||
usb_ep_enable(ep_fback);
|
||||
ret = usb_ep_enable(ep_fback);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret);
|
||||
return ret; // TODO: Clean up out_ep
|
||||
}
|
||||
req_len = ep_fback->maxpacket;
|
||||
|
||||
req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
|
||||
@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev)
|
||||
struct uac_params *params = &audio_dev->params;
|
||||
unsigned int factor;
|
||||
const struct usb_endpoint_descriptor *ep_desc;
|
||||
int req_len, i;
|
||||
int req_len, i, ret;
|
||||
unsigned int p_pktsize;
|
||||
|
||||
prm = &uac->p_prm;
|
||||
dev_dbg(dev, "start playback with rate %d\n", prm->srate);
|
||||
ep = audio_dev->in_ep;
|
||||
config_ep_by_speed(gadget, &audio_dev->func, ep);
|
||||
ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ep_desc = ep->desc;
|
||||
/*
|
||||
@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev)
|
||||
uac->p_residue_mil = 0;
|
||||
|
||||
prm->ep_enabled = true;
|
||||
usb_ep_enable(ep);
|
||||
ret = usb_ep_enable(ep);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < params->req_number; i++) {
|
||||
if (!prm->reqs[i]) {
|
||||
|
||||
@@ -1446,6 +1446,7 @@ void gserial_suspend(struct gserial *gser)
|
||||
spin_lock(&port->port_lock);
|
||||
spin_unlock(&serial_port_lock);
|
||||
port->suspended = true;
|
||||
port->start_delayed = true;
|
||||
spin_unlock_irqrestore(&port->port_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gserial_suspend);
|
||||
|
||||
@@ -118,12 +118,10 @@ int usb_ep_enable(struct usb_ep *ep)
|
||||
goto out;
|
||||
|
||||
/* UDC drivers can't handle endpoints with maxpacket size 0 */
|
||||
if (usb_endpoint_maxp(ep->desc) == 0) {
|
||||
/*
|
||||
* We should log an error message here, but we can't call
|
||||
* dev_err() because there's no way to find the gadget
|
||||
* given only ep.
|
||||
*/
|
||||
if (!ep->desc || usb_endpoint_maxp(ep->desc) == 0) {
|
||||
WARN_ONCE(1, "%s: ep%d (%s) has %s\n", __func__, ep->address, ep->name,
|
||||
(!ep->desc) ? "NULL descriptor" : "maxpacket 0");
|
||||
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,11 @@ static void usb_debug_process_read_urb(struct urb *urb)
|
||||
usb_serial_generic_process_read_urb(urb);
|
||||
}
|
||||
|
||||
static void usb_debug_init_termios(struct tty_struct *tty)
|
||||
{
|
||||
tty->termios.c_lflag &= ~(ECHO | ECHONL);
|
||||
}
|
||||
|
||||
static struct usb_serial_driver debug_device = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -78,6 +83,7 @@ static struct usb_serial_driver debug_device = {
|
||||
.num_ports = 1,
|
||||
.bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE,
|
||||
.break_ctl = usb_debug_break_ctl,
|
||||
.init_termios = usb_debug_init_termios,
|
||||
.process_read_urb = usb_debug_process_read_urb,
|
||||
};
|
||||
|
||||
@@ -89,6 +95,7 @@ static struct usb_serial_driver dbc_device = {
|
||||
.id_table = dbc_id_table,
|
||||
.num_ports = 1,
|
||||
.break_ctl = usb_debug_break_ctl,
|
||||
.init_termios = usb_debug_init_termios,
|
||||
.process_read_urb = usb_debug_process_read_urb,
|
||||
};
|
||||
|
||||
|
||||
@@ -745,6 +745,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
|
||||
*
|
||||
*/
|
||||
if (usb_pipedevice(urb->pipe) == 0) {
|
||||
struct usb_device *old;
|
||||
__u8 type = usb_pipetype(urb->pipe);
|
||||
struct usb_ctrlrequest *ctrlreq =
|
||||
(struct usb_ctrlrequest *) urb->setup_packet;
|
||||
@@ -755,14 +756,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
|
||||
goto no_need_xmit;
|
||||
}
|
||||
|
||||
old = vdev->udev;
|
||||
switch (ctrlreq->bRequest) {
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
/* set_address may come when a device is reset */
|
||||
dev_info(dev, "SetAddress Request (%d) to port %d\n",
|
||||
ctrlreq->wValue, vdev->rhport);
|
||||
|
||||
usb_put_dev(vdev->udev);
|
||||
vdev->udev = usb_get_dev(urb->dev);
|
||||
usb_put_dev(old);
|
||||
|
||||
spin_lock(&vdev->ud.lock);
|
||||
vdev->ud.status = VDEV_ST_USED;
|
||||
@@ -781,8 +783,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
|
||||
usbip_dbg_vhci_hc(
|
||||
"Not yet?:Get_Descriptor to device 0 (get max pipe size)\n");
|
||||
|
||||
usb_put_dev(vdev->udev);
|
||||
vdev->udev = usb_get_dev(urb->dev);
|
||||
usb_put_dev(old);
|
||||
goto out;
|
||||
|
||||
default:
|
||||
@@ -1067,6 +1069,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
|
||||
static void vhci_device_reset(struct usbip_device *ud)
|
||||
{
|
||||
struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
|
||||
struct usb_device *old = vdev->udev;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ud->lock, flags);
|
||||
@@ -1074,8 +1077,8 @@ static void vhci_device_reset(struct usbip_device *ud)
|
||||
vdev->speed = 0;
|
||||
vdev->devid = 0;
|
||||
|
||||
usb_put_dev(vdev->udev);
|
||||
vdev->udev = NULL;
|
||||
usb_put_dev(old);
|
||||
|
||||
if (ud->tcp_socket) {
|
||||
sockfd_put(ud->tcp_socket);
|
||||
|
||||
@@ -1294,13 +1294,7 @@ static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf)
|
||||
|
||||
notify = ops->get_vq_notification(vdpa, index);
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
if (remap_pfn_range(vma, vmf->address & PAGE_MASK,
|
||||
PFN_DOWN(notify.addr), PAGE_SIZE,
|
||||
vma->vm_page_prot))
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
return VM_FAULT_NOPAGE;
|
||||
return vmf_insert_pfn(vma, vmf->address & PAGE_MASK, PFN_DOWN(notify.addr));
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct vhost_vdpa_vm_ops = {
|
||||
|
||||
@@ -1553,6 +1553,7 @@ struct btrfs_drop_extents_args {
|
||||
struct btrfs_file_private {
|
||||
void *filldir_buf;
|
||||
u64 last_index;
|
||||
bool fsync_skip_inode_lock;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1526,21 +1526,37 @@ relock:
|
||||
* So here we disable page faults in the iov_iter and then retry if we
|
||||
* got -EFAULT, faulting in the pages before the retry.
|
||||
*/
|
||||
again:
|
||||
from->nofault = true;
|
||||
dio = btrfs_dio_write(iocb, from, written);
|
||||
from->nofault = false;
|
||||
|
||||
/*
|
||||
* iomap_dio_complete() will call btrfs_sync_file() if we have a dsync
|
||||
* iocb, and that needs to lock the inode. So unlock it before calling
|
||||
* iomap_dio_complete() to avoid a deadlock.
|
||||
*/
|
||||
btrfs_inode_unlock(inode, ilock_flags);
|
||||
|
||||
if (IS_ERR_OR_NULL(dio))
|
||||
if (IS_ERR_OR_NULL(dio)) {
|
||||
err = PTR_ERR_OR_ZERO(dio);
|
||||
else
|
||||
} else {
|
||||
struct btrfs_file_private stack_private = { 0 };
|
||||
struct btrfs_file_private *private;
|
||||
const bool have_private = (file->private_data != NULL);
|
||||
|
||||
if (!have_private)
|
||||
file->private_data = &stack_private;
|
||||
|
||||
/*
|
||||
* If we have a synchoronous write, we must make sure the fsync
|
||||
* triggered by the iomap_dio_complete() call below doesn't
|
||||
* deadlock on the inode lock - we are already holding it and we
|
||||
* can't call it after unlocking because we may need to complete
|
||||
* partial writes due to the input buffer (or parts of it) not
|
||||
* being already faulted in.
|
||||
*/
|
||||
private = file->private_data;
|
||||
private->fsync_skip_inode_lock = true;
|
||||
err = iomap_dio_complete(dio);
|
||||
private->fsync_skip_inode_lock = false;
|
||||
|
||||
if (!have_private)
|
||||
file->private_data = NULL;
|
||||
}
|
||||
|
||||
/* No increment (+=) because iomap returns a cumulative value. */
|
||||
if (err > 0)
|
||||
@@ -1567,10 +1583,12 @@ relock:
|
||||
} else {
|
||||
fault_in_iov_iter_readable(from, left);
|
||||
prev_left = left;
|
||||
goto relock;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
btrfs_inode_unlock(inode, ilock_flags);
|
||||
|
||||
/*
|
||||
* If 'err' is -ENOTBLK or we have not written all data, then it means
|
||||
* we must fallback to buffered IO.
|
||||
@@ -1777,6 +1795,7 @@ static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx)
|
||||
*/
|
||||
int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
{
|
||||
struct btrfs_file_private *private = file->private_data;
|
||||
struct dentry *dentry = file_dentry(file);
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
|
||||
@@ -1786,6 +1805,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
int ret = 0, err;
|
||||
u64 len;
|
||||
bool full_sync;
|
||||
const bool skip_ilock = (private ? private->fsync_skip_inode_lock : false);
|
||||
|
||||
trace_btrfs_sync_file(file, datasync);
|
||||
|
||||
@@ -1813,7 +1833,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
btrfs_inode_lock(inode, BTRFS_ILOCK_MMAP);
|
||||
if (skip_ilock)
|
||||
down_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
else
|
||||
btrfs_inode_lock(inode, BTRFS_ILOCK_MMAP);
|
||||
|
||||
atomic_inc(&root->log_batch);
|
||||
|
||||
@@ -1837,7 +1860,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
*/
|
||||
ret = start_ordered_ops(inode, start, end);
|
||||
if (ret) {
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
if (skip_ilock)
|
||||
up_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
else
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1940,7 +1966,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
* file again, but that will end up using the synchronization
|
||||
* inside btrfs_sync_log to keep things safe.
|
||||
*/
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
if (skip_ilock)
|
||||
up_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
else
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
|
||||
if (ret == BTRFS_NO_LOG_SYNC) {
|
||||
ret = btrfs_end_transaction(trans);
|
||||
@@ -2008,7 +2037,10 @@ out:
|
||||
|
||||
out_release_extents:
|
||||
btrfs_release_log_ctx_extents(&ctx);
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
if (skip_ilock)
|
||||
up_write(&BTRFS_I(inode)->i_mmap_lock);
|
||||
else
|
||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -865,6 +865,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
btrfs_err(fs_info,
|
||||
"Duplicate entries in free space cache, dumping");
|
||||
kmem_cache_free(btrfs_free_space_bitmap_cachep, e->bitmap);
|
||||
kmem_cache_free(btrfs_free_space_cachep, e);
|
||||
goto free_cache;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
struct root_name_map {
|
||||
u64 id;
|
||||
char name[16];
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct root_name_map root_map[] = {
|
||||
|
||||
@@ -1439,7 +1439,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file,
|
||||
hinfo->hash = EXT4_DIRENT_HASH(de);
|
||||
hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de);
|
||||
} else {
|
||||
ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
|
||||
err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
|
||||
if (err) {
|
||||
ret = err;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if ((hinfo->hash < start_hash) ||
|
||||
((hinfo->hash == start_hash) &&
|
||||
|
||||
@@ -2226,8 +2226,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
|
||||
if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
|
||||
ext4_fsblk_t start;
|
||||
|
||||
start = ext4_group_first_block_no(ac->ac_sb, e4b->bd_group) +
|
||||
ex.fe_start;
|
||||
start = ext4_grp_offs_to_block(ac->ac_sb, &ex);
|
||||
/* use do_div to get remainder (would be 64-bit modulo) */
|
||||
if (do_div(start, sbi->s_stripe) == 0) {
|
||||
ac->ac_found++;
|
||||
|
||||
@@ -409,6 +409,7 @@ repeat:
|
||||
tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
|
||||
if (!tmp) {
|
||||
brelse(new_bh);
|
||||
free_buffer_head(new_bh);
|
||||
return -ENOMEM;
|
||||
}
|
||||
spin_lock(&jh_in->b_state_lock);
|
||||
|
||||
@@ -960,7 +960,7 @@ static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
|
||||
static void
|
||||
cifs_security_flags_handle_must_flags(unsigned int *flags)
|
||||
{
|
||||
unsigned int signflags = *flags & CIFSSEC_MUST_SIGN;
|
||||
unsigned int signflags = *flags & (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL);
|
||||
|
||||
if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
|
||||
*flags = CIFSSEC_MUST_KRB5;
|
||||
|
||||
@@ -1820,7 +1820,7 @@ static inline bool is_retryable_error(int error)
|
||||
#define CIFSSEC_MAY_SIGN 0x00001
|
||||
#define CIFSSEC_MAY_NTLMV2 0x00004
|
||||
#define CIFSSEC_MAY_KRB5 0x00008
|
||||
#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
|
||||
#define CIFSSEC_MAY_SEAL 0x00040
|
||||
#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */
|
||||
|
||||
#define CIFSSEC_MUST_SIGN 0x01001
|
||||
@@ -1830,11 +1830,11 @@ require use of the stronger protocol */
|
||||
#define CIFSSEC_MUST_NTLMV2 0x04004
|
||||
#define CIFSSEC_MUST_KRB5 0x08008
|
||||
#ifdef CONFIG_CIFS_UPCALL
|
||||
#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
|
||||
#define CIFSSEC_MASK 0xCF0CF /* flags supported if no weak allowed */
|
||||
#else
|
||||
#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */
|
||||
#define CIFSSEC_MASK 0xC70C7 /* flags supported if no weak allowed */
|
||||
#endif /* UPCALL */
|
||||
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
|
||||
#define CIFSSEC_MUST_SEAL 0x40040
|
||||
#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
|
||||
|
||||
#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP | CIFSSEC_MAY_SEAL)
|
||||
|
||||
@@ -80,6 +80,9 @@ int smb3_encryption_required(const struct cifs_tcon *tcon)
|
||||
if (tcon->seal &&
|
||||
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
||||
return 1;
|
||||
if (((global_secflags & CIFSSEC_MUST_SEAL) == CIFSSEC_MUST_SEAL) &&
|
||||
(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "udfdecl.h"
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include "udf_i.h"
|
||||
#include "udf_sb.h"
|
||||
@@ -144,7 +145,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
|
||||
{
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct buffer_head *bh = NULL;
|
||||
struct udf_part_map *partmap;
|
||||
unsigned long block;
|
||||
unsigned long block_group;
|
||||
unsigned long bit;
|
||||
@@ -153,19 +153,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
|
||||
unsigned long overflow;
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
|
||||
if (bloc->logicalBlockNum + count < count ||
|
||||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
|
||||
udf_debug("%u < %d || %u + %u > %u\n",
|
||||
bloc->logicalBlockNum, 0,
|
||||
bloc->logicalBlockNum, count,
|
||||
partmap->s_partition_len);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* We make sure this cannot overflow when mounting the filesystem */
|
||||
block = bloc->logicalBlockNum + offset +
|
||||
(sizeof(struct spaceBitmapDesc) << 3);
|
||||
|
||||
do {
|
||||
overflow = 0;
|
||||
block_group = block >> (sb->s_blocksize_bits + 3);
|
||||
@@ -395,7 +385,6 @@ static void udf_table_free_blocks(struct super_block *sb,
|
||||
uint32_t count)
|
||||
{
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct udf_part_map *partmap;
|
||||
uint32_t start, end;
|
||||
uint32_t elen;
|
||||
struct kernel_lb_addr eloc;
|
||||
@@ -404,16 +393,6 @@ static void udf_table_free_blocks(struct super_block *sb,
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
|
||||
if (bloc->logicalBlockNum + count < count ||
|
||||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
|
||||
udf_debug("%u < %d || %u + %u > %u\n",
|
||||
bloc->logicalBlockNum, 0,
|
||||
bloc->logicalBlockNum, count,
|
||||
partmap->s_partition_len);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
iinfo = UDF_I(table);
|
||||
udf_add_free_space(sb, sbi->s_partition, count);
|
||||
|
||||
@@ -688,6 +667,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
|
||||
{
|
||||
uint16_t partition = bloc->partitionReferenceNum;
|
||||
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
|
||||
uint32_t blk;
|
||||
|
||||
if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) ||
|
||||
check_add_overflow(blk, count, &blk) ||
|
||||
bloc->logicalBlockNum + count > map->s_partition_len) {
|
||||
udf_debug("Invalid request to free blocks: (%d, %u), off %u, "
|
||||
"len %u, partition len %u\n",
|
||||
partition, bloc->logicalBlockNum, offset, count,
|
||||
map->s_partition_len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
|
||||
udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,
|
||||
|
||||
@@ -2960,7 +2960,7 @@ xlog_do_recovery_pass(
|
||||
int error = 0, h_size, h_len;
|
||||
int error2 = 0;
|
||||
int bblks, split_bblks;
|
||||
int hblks, split_hblks, wrapped_hblks;
|
||||
int hblks = 1, split_hblks, wrapped_hblks;
|
||||
int i;
|
||||
struct hlist_head rhash[XLOG_RHASH_SIZE];
|
||||
LIST_HEAD (buffer_list);
|
||||
@@ -3016,14 +3016,22 @@ xlog_do_recovery_pass(
|
||||
if (error)
|
||||
goto bread_err1;
|
||||
|
||||
hblks = xlog_logrec_hblks(log, rhead);
|
||||
if (hblks != 1) {
|
||||
kmem_free(hbp);
|
||||
hbp = xlog_alloc_buffer(log, hblks);
|
||||
/*
|
||||
* This open codes xlog_logrec_hblks so that we can reuse the
|
||||
* fixed up h_size value calculated above. Without that we'd
|
||||
* still allocate the buffer based on the incorrect on-disk
|
||||
* size.
|
||||
*/
|
||||
if (h_size > XLOG_HEADER_CYCLE_SIZE &&
|
||||
(rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) {
|
||||
hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE);
|
||||
if (hblks > 1) {
|
||||
kmem_free(hbp);
|
||||
hbp = xlog_alloc_buffer(log, hblks);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(log->l_sectBBsize == 1);
|
||||
hblks = 1;
|
||||
hbp = xlog_alloc_buffer(log, 1);
|
||||
h_size = XLOG_BIG_RECORD_BSIZE;
|
||||
}
|
||||
|
||||
@@ -105,14 +105,13 @@ static inline bool blk_integrity_rq(struct request *rq)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the first bvec that contains integrity data. Only drivers that are
|
||||
* limited to a single integrity segment should use this helper.
|
||||
* Return the current bvec that contains the integrity data. bip_iter may be
|
||||
* advanced to iterate over the integrity data.
|
||||
*/
|
||||
static inline struct bio_vec *rq_integrity_vec(struct request *rq)
|
||||
static inline struct bio_vec rq_integrity_vec(struct request *rq)
|
||||
{
|
||||
if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1))
|
||||
return NULL;
|
||||
return rq->bio->bi_integrity->bip_vec;
|
||||
return mp_bvec_iter_bvec(rq->bio->bi_integrity->bip_vec,
|
||||
rq->bio->bi_integrity->bip_iter);
|
||||
}
|
||||
#else /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
static inline int blk_rq_count_integrity_sg(struct request_queue *q,
|
||||
@@ -176,9 +175,10 @@ static inline int blk_integrity_rq(struct request *rq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct bio_vec *rq_integrity_vec(struct request *rq)
|
||||
static inline struct bio_vec rq_integrity_vec(struct request *rq)
|
||||
{
|
||||
return NULL;
|
||||
/* the optimizer will remove all calls to this function */
|
||||
return (struct bio_vec){ };
|
||||
}
|
||||
#endif /* CONFIG_BLK_DEV_INTEGRITY */
|
||||
#endif /* _LINUX_BLK_INTEGRITY_H */
|
||||
|
||||
@@ -291,7 +291,19 @@ static inline void timer_probe(void) {}
|
||||
#define TIMER_ACPI_DECLARE(name, table_id, fn) \
|
||||
ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn)
|
||||
|
||||
extern ulong max_cswd_read_retries;
|
||||
static inline unsigned int clocksource_get_max_watchdog_retry(void)
|
||||
{
|
||||
/*
|
||||
* When system is in the boot phase or under heavy workload, there
|
||||
* can be random big latencies during the clocksource/watchdog
|
||||
* read, so allow retries to filter the noise latency. As the
|
||||
* latency's frequency and maximum value goes up with the number of
|
||||
* CPUs, scale the number of retries with the number of online
|
||||
* CPUs.
|
||||
*/
|
||||
return (ilog2(num_online_cpus()) / 2) + 1;
|
||||
}
|
||||
|
||||
void clocksource_verify_percpu(struct clocksource *cs);
|
||||
|
||||
#endif /* _LINUX_CLOCKSOURCE_H */
|
||||
|
||||
@@ -2109,6 +2109,8 @@
|
||||
|
||||
#define PCI_VENDOR_ID_CHELSIO 0x1425
|
||||
|
||||
#define PCI_VENDOR_ID_EDIMAX 0x1432
|
||||
|
||||
#define PCI_VENDOR_ID_ADLINK 0x144a
|
||||
|
||||
#define PCI_VENDOR_ID_SAMSUNG 0x144d
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#define CPU_PROFILING 1
|
||||
#define SCHED_PROFILING 2
|
||||
#define SLEEP_PROFILING 3
|
||||
#define KVM_PROFILING 4
|
||||
|
||||
struct proc_dir_entry;
|
||||
|
||||
@@ -843,7 +843,6 @@ do { \
|
||||
struct perf_event;
|
||||
|
||||
DECLARE_PER_CPU(struct pt_regs, perf_trace_regs);
|
||||
DECLARE_PER_CPU(int, bpf_kprobe_override);
|
||||
|
||||
extern int perf_trace_init(struct perf_event *event);
|
||||
extern void perf_trace_destroy(struct perf_event *event);
|
||||
|
||||
@@ -132,18 +132,26 @@ void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args,
|
||||
|
||||
static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i,
|
||||
const struct in6_addr *daddr,
|
||||
unsigned int prefs,
|
||||
unsigned int prefs, int l3mdev_index,
|
||||
struct in6_addr *saddr)
|
||||
{
|
||||
struct net_device *l3mdev;
|
||||
struct net_device *dev;
|
||||
bool same_vrf;
|
||||
int err = 0;
|
||||
|
||||
if (f6i && f6i->fib6_prefsrc.plen) {
|
||||
*saddr = f6i->fib6_prefsrc.addr;
|
||||
} else {
|
||||
struct net_device *dev = f6i ? fib6_info_nh_dev(f6i) : NULL;
|
||||
rcu_read_lock();
|
||||
|
||||
err = ipv6_dev_get_saddr(net, dev, daddr, prefs, saddr);
|
||||
}
|
||||
l3mdev = dev_get_by_index_rcu(net, l3mdev_index);
|
||||
if (!f6i || !f6i->fib6_prefsrc.plen || l3mdev)
|
||||
dev = f6i ? fib6_info_nh_dev(f6i) : NULL;
|
||||
same_vrf = !l3mdev || l3mdev_master_dev_rcu(dev) == l3mdev;
|
||||
if (f6i && f6i->fib6_prefsrc.plen && same_vrf)
|
||||
*saddr = f6i->fib6_prefsrc.addr;
|
||||
else
|
||||
err = ipv6_dev_get_saddr(net, same_vrf ? dev : l3mdev, daddr, prefs, saddr);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
|
||||
return (void *)expr->data;
|
||||
}
|
||||
|
||||
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src);
|
||||
int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src, gfp_t gfp);
|
||||
void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
|
||||
int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
|
||||
const struct nft_expr *expr);
|
||||
@@ -889,7 +889,7 @@ struct nft_expr_ops {
|
||||
struct nft_regs *regs,
|
||||
const struct nft_pktinfo *pkt);
|
||||
int (*clone)(struct nft_expr *dst,
|
||||
const struct nft_expr *src);
|
||||
const struct nft_expr *src, gfp_t gfp);
|
||||
unsigned int size;
|
||||
|
||||
int (*init)(const struct nft_ctx *ctx,
|
||||
|
||||
@@ -10,25 +10,25 @@
|
||||
|
||||
TRACE_EVENT(ifs_status,
|
||||
|
||||
TP_PROTO(int cpu, union ifs_scan activate, union ifs_status status),
|
||||
TP_PROTO(int cpu, int start, int stop, u64 status),
|
||||
|
||||
TP_ARGS(cpu, activate, status),
|
||||
TP_ARGS(cpu, start, stop, status),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field( u64, status )
|
||||
__field( int, cpu )
|
||||
__field( u8, start )
|
||||
__field( u8, stop )
|
||||
__field( u16, start )
|
||||
__field( u16, stop )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->cpu = cpu;
|
||||
__entry->start = activate.start;
|
||||
__entry->stop = activate.stop;
|
||||
__entry->status = status.data;
|
||||
__entry->start = start;
|
||||
__entry->stop = stop;
|
||||
__entry->status = status;
|
||||
),
|
||||
|
||||
TP_printk("cpu: %d, start: %.2x, stop: %.2x, status: %llx",
|
||||
TP_printk("cpu: %d, start: %.4x, stop: %.4x, status: %.16llx",
|
||||
__entry->cpu,
|
||||
__entry->start,
|
||||
__entry->stop,
|
||||
|
||||
@@ -491,6 +491,7 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
|
||||
flags = IRQD_AFFINITY_MANAGED |
|
||||
IRQD_MANAGED_SHUTDOWN;
|
||||
}
|
||||
flags |= IRQD_AFFINITY_SET;
|
||||
mask = &affinity->mask;
|
||||
node = cpu_to_node(cpumask_first(mask));
|
||||
affinity++;
|
||||
|
||||
@@ -199,7 +199,7 @@ void static_key_disable_cpuslocked(struct static_key *key)
|
||||
}
|
||||
|
||||
jump_label_lock();
|
||||
if (atomic_cmpxchg(&key->enabled, 1, 0))
|
||||
if (atomic_cmpxchg(&key->enabled, 1, 0) == 1)
|
||||
jump_label_update(key);
|
||||
jump_label_unlock();
|
||||
}
|
||||
|
||||
@@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area,
|
||||
kmsan_unpoison_memory(&area->list, sizeof(area->list));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike in_serving_softirq(), this function returns false when called during
|
||||
* a hardirq or an NMI that happened in the softirq context.
|
||||
*/
|
||||
static inline bool in_softirq_really(void)
|
||||
{
|
||||
return in_serving_softirq() && !in_hardirq() && !in_nmi();
|
||||
}
|
||||
|
||||
static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
|
||||
{
|
||||
unsigned int mode;
|
||||
@@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru
|
||||
* so we ignore code executed in interrupts, unless we are in a remote
|
||||
* coverage collection section in a softirq.
|
||||
*/
|
||||
if (!in_task() && !(in_serving_softirq() && t->kcov_softirq))
|
||||
if (!in_task() && !(in_softirq_really() && t->kcov_softirq))
|
||||
return false;
|
||||
mode = READ_ONCE(t->kcov_mode);
|
||||
/*
|
||||
@@ -847,7 +856,7 @@ void kcov_remote_start(u64 handle)
|
||||
|
||||
if (WARN_ON(!kcov_check_handle(handle, true, true, true)))
|
||||
return;
|
||||
if (!in_task() && !in_serving_softirq())
|
||||
if (!in_task() && !in_softirq_really())
|
||||
return;
|
||||
|
||||
local_lock_irqsave(&kcov_percpu_data.lock, flags);
|
||||
@@ -989,7 +998,7 @@ void kcov_remote_stop(void)
|
||||
int sequence;
|
||||
unsigned long flags;
|
||||
|
||||
if (!in_task() && !in_serving_softirq())
|
||||
if (!in_task() && !in_softirq_really())
|
||||
return;
|
||||
|
||||
local_lock_irqsave(&kcov_percpu_data.lock, flags);
|
||||
|
||||
@@ -1552,8 +1552,8 @@ static bool is_cfi_preamble_symbol(unsigned long addr)
|
||||
if (lookup_symbol_name(addr, symbuf))
|
||||
return false;
|
||||
|
||||
return str_has_prefix("__cfi_", symbuf) ||
|
||||
str_has_prefix("__pfx_", symbuf);
|
||||
return str_has_prefix(symbuf, "__cfi_") ||
|
||||
str_has_prefix(symbuf, "__pfx_");
|
||||
}
|
||||
|
||||
static int check_kprobe_address_safe(struct kprobe *p,
|
||||
|
||||
@@ -508,6 +508,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
|
||||
ps.chunk_size = max(ps.chunk_size, job->min_chunk);
|
||||
ps.chunk_size = roundup(ps.chunk_size, job->align);
|
||||
|
||||
/*
|
||||
* chunk_size can be 0 if the caller sets min_chunk to 0. So force it
|
||||
* to at least 1 to prevent divide-by-0 panic in padata_mt_helper().`
|
||||
*/
|
||||
if (!ps.chunk_size)
|
||||
ps.chunk_size = 1U;
|
||||
|
||||
list_for_each_entry(pw, &works, pw_list)
|
||||
queue_work(system_unbound_wq, &pw->pw_work);
|
||||
|
||||
|
||||
@@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex);
|
||||
int profile_setup(char *str)
|
||||
{
|
||||
static const char schedstr[] = "schedule";
|
||||
static const char sleepstr[] = "sleep";
|
||||
static const char kvmstr[] = "kvm";
|
||||
const char *select = NULL;
|
||||
int par;
|
||||
|
||||
if (!strncmp(str, sleepstr, strlen(sleepstr))) {
|
||||
#ifdef CONFIG_SCHEDSTATS
|
||||
force_schedstat_enabled();
|
||||
prof_on = SLEEP_PROFILING;
|
||||
select = sleepstr;
|
||||
#else
|
||||
pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n");
|
||||
#endif /* CONFIG_SCHEDSTATS */
|
||||
} else if (!strncmp(str, schedstr, strlen(schedstr))) {
|
||||
if (!strncmp(str, schedstr, strlen(schedstr))) {
|
||||
prof_on = SCHED_PROFILING;
|
||||
select = schedstr;
|
||||
} else if (!strncmp(str, kvmstr, strlen(kvmstr))) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user