]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sun, 1 Dec 2024 12:06:16 +0000 (07:06 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 1 Dec 2024 12:06:16 +0000 (07:06 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
192 files changed:
queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch [new file with mode: 0644]
queue-5.10/alsa-6fire-release-resources-at-card-release.patch [new file with mode: 0644]
queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch [new file with mode: 0644]
queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch [new file with mode: 0644]
queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch [new file with mode: 0644]
queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch [new file with mode: 0644]
queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch [new file with mode: 0644]
queue-5.10/alsa-usx2y-coding-style-fixes.patch [new file with mode: 0644]
queue-5.10/alsa-usx2y-fix-spaces.patch [new file with mode: 0644]
queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch [new file with mode: 0644]
queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch [new file with mode: 0644]
queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch [new file with mode: 0644]
queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch [new file with mode: 0644]
queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch [new file with mode: 0644]
queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch [new file with mode: 0644]
queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch [new file with mode: 0644]
queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch [new file with mode: 0644]
queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch [new file with mode: 0644]
queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch [new file with mode: 0644]
queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch [new file with mode: 0644]
queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch [new file with mode: 0644]
queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch [new file with mode: 0644]
queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch [new file with mode: 0644]
queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch [new file with mode: 0644]
queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch [new file with mode: 0644]
queue-5.10/clkdev-remove-config_clkdev_lookup.patch [new file with mode: 0644]
queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch [new file with mode: 0644]
queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch [new file with mode: 0644]
queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch [new file with mode: 0644]
queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch [new file with mode: 0644]
queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch [new file with mode: 0644]
queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch [new file with mode: 0644]
queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch [new file with mode: 0644]
queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch [new file with mode: 0644]
queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch [new file with mode: 0644]
queue-5.10/driver-core-introduce-device_find_any_child-helper.patch [new file with mode: 0644]
queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch [new file with mode: 0644]
queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch [new file with mode: 0644]
queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch [new file with mode: 0644]
queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch [new file with mode: 0644]
queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch [new file with mode: 0644]
queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch [new file with mode: 0644]
queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch [new file with mode: 0644]
queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch [new file with mode: 0644]
queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch [new file with mode: 0644]
queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch [new file with mode: 0644]
queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch [new file with mode: 0644]
queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch [new file with mode: 0644]
queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch [new file with mode: 0644]
queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch [new file with mode: 0644]
queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch [new file with mode: 0644]
queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch [new file with mode: 0644]
queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch [new file with mode: 0644]
queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch [new file with mode: 0644]
queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch [new file with mode: 0644]
queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch [new file with mode: 0644]
queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch [new file with mode: 0644]
queue-5.10/f2fs-open-code-allocate_segment_by_default.patch [new file with mode: 0644]
queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch [new file with mode: 0644]
queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch [new file with mode: 0644]
queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch [new file with mode: 0644]
queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch [new file with mode: 0644]
queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch [new file with mode: 0644]
queue-5.10/firmware-google-unregister-driver_info-on-failure.patch [new file with mode: 0644]
queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch [new file with mode: 0644]
queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch [new file with mode: 0644]
queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch [new file with mode: 0644]
queue-5.10/initramfs-avoid-filename-buffer-overrun.patch [new file with mode: 0644]
queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch [new file with mode: 0644]
queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch [new file with mode: 0644]
queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch [new file with mode: 0644]
queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch [new file with mode: 0644]
queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch [new file with mode: 0644]
queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch [new file with mode: 0644]
queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch [new file with mode: 0644]
queue-5.10/m68k-mvme147-reinstate-early-console.patch [new file with mode: 0644]
queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch [new file with mode: 0644]
queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch [new file with mode: 0644]
queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch [new file with mode: 0644]
queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch [new file with mode: 0644]
queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch [new file with mode: 0644]
queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch [new file with mode: 0644]
queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch [new file with mode: 0644]
queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch [new file with mode: 0644]
queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch [new file with mode: 0644]
queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch [new file with mode: 0644]
queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch [new file with mode: 0644]
queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch [new file with mode: 0644]
queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch [new file with mode: 0644]
queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch [new file with mode: 0644]
queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch [new file with mode: 0644]
queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch [new file with mode: 0644]
queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch [new file with mode: 0644]
queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch [new file with mode: 0644]
queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch [new file with mode: 0644]
queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch [new file with mode: 0644]
queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch [new file with mode: 0644]
queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch [new file with mode: 0644]
queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch [new file with mode: 0644]
queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch [new file with mode: 0644]
queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch [new file with mode: 0644]
queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch [new file with mode: 0644]
queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch [new file with mode: 0644]
queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch [new file with mode: 0644]
queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch [new file with mode: 0644]
queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch [new file with mode: 0644]
queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch [new file with mode: 0644]
queue-5.10/octeontx2-af-forward-error-correction-configuration.patch [new file with mode: 0644]
queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch [new file with mode: 0644]
queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch [new file with mode: 0644]
queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch [new file with mode: 0644]
queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch [new file with mode: 0644]
queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch [new file with mode: 0644]
queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch [new file with mode: 0644]
queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch [new file with mode: 0644]
queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch [new file with mode: 0644]
queue-5.10/perf-probe-fix-libdw-memory-leak.patch [new file with mode: 0644]
queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch [new file with mode: 0644]
queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch [new file with mode: 0644]
queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch [new file with mode: 0644]
queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch [new file with mode: 0644]
queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch [new file with mode: 0644]
queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch [new file with mode: 0644]
queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch [new file with mode: 0644]
queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch [new file with mode: 0644]
queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch [new file with mode: 0644]
queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch [new file with mode: 0644]
queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch [new file with mode: 0644]
queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch [new file with mode: 0644]
queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch [new file with mode: 0644]
queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch [new file with mode: 0644]
queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch [new file with mode: 0644]
queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch [new file with mode: 0644]
queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch [new file with mode: 0644]
queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch [new file with mode: 0644]
queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch [new file with mode: 0644]
queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch [new file with mode: 0644]
queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch [new file with mode: 0644]
queue-5.10/scsi-fusion-remove-unused-variable-rc.patch [new file with mode: 0644]
queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch [new file with mode: 0644]
queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch [new file with mode: 0644]
queue-5.10/selftests-net-really-check-for-bg-process-completion.patch [new file with mode: 0644]
queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch [new file with mode: 0644]
queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch [new file with mode: 0644]
queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch [new file with mode: 0644]
queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch [new file with mode: 0644]
queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch [new file with mode: 0644]
queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch [new file with mode: 0644]
queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch [new file with mode: 0644]
queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch [new file with mode: 0644]
queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch [new file with mode: 0644]
queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch [new file with mode: 0644]
queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch [new file with mode: 0644]
queue-5.10/usb-chaoskey-fail-open-after-removal.patch [new file with mode: 0644]
queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch [new file with mode: 0644]
queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch [new file with mode: 0644]
queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch [new file with mode: 0644]
queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch [new file with mode: 0644]
queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch [new file with mode: 0644]
queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch [new file with mode: 0644]
queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 [new file with mode: 0644]
queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch [new file with mode: 0644]
queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch [new file with mode: 0644]
queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch [new file with mode: 0644]
queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch [new file with mode: 0644]
queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch [new file with mode: 0644]
queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch [new file with mode: 0644]
queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch [new file with mode: 0644]
queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch [new file with mode: 0644]
queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch [new file with mode: 0644]
queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch [new file with mode: 0644]
queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch [new file with mode: 0644]
queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch [new file with mode: 0644]

diff --git a/queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch b/queue-5.10/acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch
new file mode 100644 (file)
index 0000000..a9f8852
--- /dev/null
@@ -0,0 +1,46 @@
+From 5d84a31fc46f4427bdb51099c286e689f3d9ca21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Aug 2024 13:12:39 +0300
+Subject: acpi/arm64: Adjust error handling procedure in
+ gtdt_parse_timer_block()
+
+From: Aleksandr Mishin <amishin@t-argos.ru>
+
+[ Upstream commit 1a9de2f6fda69d5f105dd8af776856a66abdaa64 ]
+
+In case of error in gtdt_parse_timer_block() invalid 'gtdt_frame'
+will be used in 'do {} while (i-- >= 0 && gtdt_frame--);' statement block
+because do{} block will be executed even if 'i == 0'.
+
+Adjust error handling procedure by replacing 'i-- >= 0' with 'i-- > 0'.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: a712c3ed9b8a ("acpi/arm64: Add memory-mapped timer support in GTDT driver")
+Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
+Acked-by: Hanjun Guo <guohanjun@huawei.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Acked-by: Aleksandr Mishin <amishin@t-argos.ru>
+Link: https://lore.kernel.org/r/20240827101239.22020-1-amishin@t-argos.ru
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/arm64/gtdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
+index c0e77c1c8e09d..eb6c2d3603874 100644
+--- a/drivers/acpi/arm64/gtdt.c
++++ b/drivers/acpi/arm64/gtdt.c
+@@ -283,7 +283,7 @@ static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block,
+               if (frame->virt_irq > 0)
+                       acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt);
+               frame->virt_irq = 0;
+-      } while (i-- >= 0 && gtdt_frame--);
++      } while (i-- > 0 && gtdt_frame--);
+       return -EINVAL;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-6fire-release-resources-at-card-release.patch b/queue-5.10/alsa-6fire-release-resources-at-card-release.patch
new file mode 100644 (file)
index 0000000..ce3fec0
--- /dev/null
@@ -0,0 +1,78 @@
+From 8ab1a1a376065713766365f428f797ec3426540e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 12:10:39 +0100
+Subject: ALSA: 6fire: Release resources at card release
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit a0810c3d6dd2d29a9b92604d682eacd2902ce947 ]
+
+The current 6fire code tries to release the resources right after the
+call of usb6fire_chip_abort().  But at this moment, the card object
+might be still in use (as we're calling snd_card_free_when_closed()).
+
+For avoid potential UAFs, move the release of resources to the card's
+private_free instead of the manual call of usb6fire_chip_destroy() at
+the USB disconnect callback.
+
+Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20241113111042.15058-6-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/6fire/chip.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
+index 08c6e6a52eb98..ad6f89845a5c2 100644
+--- a/sound/usb/6fire/chip.c
++++ b/sound/usb/6fire/chip.c
+@@ -62,8 +62,10 @@ static void usb6fire_chip_abort(struct sfire_chip *chip)
+       }
+ }
+-static void usb6fire_chip_destroy(struct sfire_chip *chip)
++static void usb6fire_card_free(struct snd_card *card)
+ {
++      struct sfire_chip *chip = card->private_data;
++
+       if (chip) {
+               if (chip->pcm)
+                       usb6fire_pcm_destroy(chip);
+@@ -73,8 +75,6 @@ static void usb6fire_chip_destroy(struct sfire_chip *chip)
+                       usb6fire_comm_destroy(chip);
+               if (chip->control)
+                       usb6fire_control_destroy(chip);
+-              if (chip->card)
+-                      snd_card_free(chip->card);
+       }
+ }
+@@ -137,6 +137,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
+       chip->regidx = regidx;
+       chip->intf_count = 1;
+       chip->card = card;
++      card->private_free = usb6fire_card_free;
+       ret = usb6fire_comm_init(chip);
+       if (ret < 0)
+@@ -163,7 +164,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
+       return 0;
+ destroy_chip:
+-      usb6fire_chip_destroy(chip);
++      snd_card_free(card);
+       return ret;
+ }
+@@ -182,7 +183,6 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
+                       chip->shutdown = true;
+                       usb6fire_chip_abort(chip);
+-                      usb6fire_chip_destroy(chip);
+               }
+       }
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch b/queue-5.10/alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch
new file mode 100644 (file)
index 0000000..e415ece
--- /dev/null
@@ -0,0 +1,168 @@
+From 452ff0c016d0a2518317507748c575665ceec7bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 12:10:38 +0100
+Subject: ALSA: caiaq: Use snd_card_free_when_closed() at disconnection
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit b04dcbb7f7b1908806b7dc22671cdbe78ff2b82c ]
+
+The USB disconnect callback is supposed to be short and not too-long
+waiting.  OTOH, the current code uses snd_card_free() at
+disconnection, but this waits for the close of all used fds, hence it
+can take long.  It eventually blocks the upper layer USB ioctls, which
+may trigger a soft lockup.
+
+An easy workaround is to replace snd_card_free() with
+snd_card_free_when_closed().  This variant returns immediately while
+the release of resources is done asynchronously by the card device
+release at the last close.
+
+This patch also splits the code to the disconnect and the free phases;
+the former is called immediately at the USB disconnect callback while
+the latter is called from the card destructor.
+
+Fixes: 523f1dce3743 ("[ALSA] Add Native Instrument usb audio device support")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20241113111042.15058-5-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/caiaq/audio.c  | 10 ++++++++--
+ sound/usb/caiaq/audio.h  |  1 +
+ sound/usb/caiaq/device.c | 19 +++++++++++++++----
+ sound/usb/caiaq/input.c  | 12 +++++++++---
+ sound/usb/caiaq/input.h  |  1 +
+ 5 files changed, 34 insertions(+), 9 deletions(-)
+
+diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
+index 3b6bb2cbe886b..1308415b55ed8 100644
+--- a/sound/usb/caiaq/audio.c
++++ b/sound/usb/caiaq/audio.c
+@@ -869,14 +869,20 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev)
+       return 0;
+ }
+-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev)
+ {
+       struct device *dev = caiaqdev_to_dev(cdev);
+       dev_dbg(dev, "%s(%p)\n", __func__, cdev);
+       stream_stop(cdev);
++}
++
++void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
++{
++      struct device *dev = caiaqdev_to_dev(cdev);
++
++      dev_dbg(dev, "%s(%p)\n", __func__, cdev);
+       free_urbs(cdev->data_urbs_in);
+       free_urbs(cdev->data_urbs_out);
+       kfree(cdev->data_cb_info);
+ }
+-
+diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h
+index 869bf6264d6a0..07f5d064456cf 100644
+--- a/sound/usb/caiaq/audio.h
++++ b/sound/usb/caiaq/audio.h
+@@ -3,6 +3,7 @@
+ #define CAIAQ_AUDIO_H
+ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev);
++void snd_usb_caiaq_audio_disconnect(struct snd_usb_caiaqdev *cdev);
+ void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev);
+ #endif /* CAIAQ_AUDIO_H */
+diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
+index 2af3b7eb0a88c..482d4915e0a70 100644
+--- a/sound/usb/caiaq/device.c
++++ b/sound/usb/caiaq/device.c
+@@ -390,6 +390,17 @@ static void setup_card(struct snd_usb_caiaqdev *cdev)
+               dev_err(dev, "Unable to set up control system (ret=%d)\n", ret);
+ }
++static void card_free(struct snd_card *card)
++{
++      struct snd_usb_caiaqdev *cdev = caiaqdev(card);
++
++#ifdef CONFIG_SND_USB_CAIAQ_INPUT
++      snd_usb_caiaq_input_free(cdev);
++#endif
++      snd_usb_caiaq_audio_free(cdev);
++      usb_reset_device(cdev->chip.dev);
++}
++
+ static int create_card(struct usb_device *usb_dev,
+                      struct usb_interface *intf,
+                      struct snd_card **cardp)
+@@ -503,6 +514,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
+                      cdev->vendor_name, cdev->product_name, usbpath);
+       setup_card(cdev);
++      card->private_free = card_free;
+       return 0;
+  err_kill_urb:
+@@ -548,15 +560,14 @@ static void snd_disconnect(struct usb_interface *intf)
+       snd_card_disconnect(card);
+ #ifdef CONFIG_SND_USB_CAIAQ_INPUT
+-      snd_usb_caiaq_input_free(cdev);
++      snd_usb_caiaq_input_disconnect(cdev);
+ #endif
+-      snd_usb_caiaq_audio_free(cdev);
++      snd_usb_caiaq_audio_disconnect(cdev);
+       usb_kill_urb(&cdev->ep1_in_urb);
+       usb_kill_urb(&cdev->midi_out_urb);
+-      snd_card_free(card);
+-      usb_reset_device(interface_to_usbdev(intf));
++      snd_card_free_when_closed(card);
+ }
+diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
+index 84f26dce7f5d0..a9130891bb696 100644
+--- a/sound/usb/caiaq/input.c
++++ b/sound/usb/caiaq/input.c
+@@ -829,15 +829,21 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
+       return ret;
+ }
+-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev)
+ {
+       if (!cdev || !cdev->input_dev)
+               return;
+       usb_kill_urb(cdev->ep4_in_urb);
++      input_unregister_device(cdev->input_dev);
++}
++
++void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev)
++{
++      if (!cdev || !cdev->input_dev)
++              return;
++
+       usb_free_urb(cdev->ep4_in_urb);
+       cdev->ep4_in_urb = NULL;
+-
+-      input_unregister_device(cdev->input_dev);
+       cdev->input_dev = NULL;
+ }
+diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h
+index c42891e7be884..fbe267f85d025 100644
+--- a/sound/usb/caiaq/input.h
++++ b/sound/usb/caiaq/input.h
+@@ -4,6 +4,7 @@
+ void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, char *buf, unsigned int len);
+ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev);
++void snd_usb_caiaq_input_disconnect(struct snd_usb_caiaqdev *cdev);
+ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev);
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch b/queue-5.10/alsa-hda-realtek-add-type-for-alc287.patch
new file mode 100644 (file)
index 0000000..9e4494c
--- /dev/null
@@ -0,0 +1,64 @@
+From bfa5e782c9b957136586fff0522bb84a3914c031 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Jul 2021 09:09:37 +0800
+Subject: ALSA: hda/realtek - Add type for ALC287
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit 99cee034c28947fc122799b0b7714e01b047f3f3 ]
+
+Add independent type for ALC287.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/r/2b7539c3e96f41a4ab458d53ea5f5784@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: cc3d0b5dd989 ("ALSA: hda/realtek: Update ALC256 depop procedure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index e9b7bf94aa3a8..b1dbb0b4c8158 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3168,6 +3168,7 @@ enum {
+       ALC269_TYPE_ALC257,
+       ALC269_TYPE_ALC215,
+       ALC269_TYPE_ALC225,
++      ALC269_TYPE_ALC287,
+       ALC269_TYPE_ALC294,
+       ALC269_TYPE_ALC300,
+       ALC269_TYPE_ALC623,
+@@ -3204,6 +3205,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+       case ALC269_TYPE_ALC257:
+       case ALC269_TYPE_ALC215:
+       case ALC269_TYPE_ALC225:
++      case ALC269_TYPE_ALC287:
+       case ALC269_TYPE_ALC294:
+       case ALC269_TYPE_ALC300:
+       case ALC269_TYPE_ALC623:
+@@ -10250,7 +10252,6 @@ static int patch_alc269(struct hda_codec *codec)
+       case 0x10ec0215:
+       case 0x10ec0245:
+       case 0x10ec0285:
+-      case 0x10ec0287:
+       case 0x10ec0289:
+               spec->codec_variant = ALC269_TYPE_ALC215;
+               spec->shutup = alc225_shutup;
+@@ -10265,6 +10266,12 @@ static int patch_alc269(struct hda_codec *codec)
+               spec->init_hook = alc225_init;
+               spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */
+               break;
++      case 0x10ec0287:
++              spec->codec_variant = ALC269_TYPE_ALC287;
++              spec->shutup = alc225_shutup;
++              spec->init_hook = alc225_init;
++              spec->gen.mixer_nid = 0; /* no loopback on ALC287 */
++              break;
+       case 0x10ec0234:
+       case 0x10ec0274:
+       case 0x10ec0294:
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch b/queue-5.10/alsa-hda-realtek-update-alc256-depop-procedure.patch
new file mode 100644 (file)
index 0000000..a2725bb
--- /dev/null
@@ -0,0 +1,102 @@
+From 07ee559bf2b987dc9741b61d5036d61852782a8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 15:21:09 +0800
+Subject: ALSA: hda/realtek: Update ALC256 depop procedure
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit cc3d0b5dd989d3238d456f9fd385946379a9c13d ]
+
+Old procedure has a chance to meet Headphone no output.
+
+Fixes: 4a219ef8f370 ("ALSA: hda/realtek - Add ALC256 HP depop function")
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/463c5f93715d4714967041a0a8cec28e@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 42 ++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 23 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b1dbb0b4c8158..eec99b9cd7692 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3596,25 +3596,22 @@ static void alc256_init(struct hda_codec *codec)
+       hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+-      if (hp_pin_sense)
++      if (hp_pin_sense) {
+               msleep(2);
++              alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-      alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-
+-      snd_hda_codec_write(codec, hp_pin, 0,
+-                          AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+-
+-      if (hp_pin_sense || spec->ultra_low_power)
+-              msleep(85);
+-
+-      snd_hda_codec_write(codec, hp_pin, 0,
++              snd_hda_codec_write(codec, hp_pin, 0,
+                           AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+-      if (hp_pin_sense || spec->ultra_low_power)
+-              msleep(100);
++              msleep(75);
++
++              snd_hda_codec_write(codec, hp_pin, 0,
++                          AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
++              msleep(75);
++              alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
++      }
+       alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
+-      alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
+       alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
+       alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
+       /*
+@@ -3638,29 +3635,28 @@ static void alc256_shutup(struct hda_codec *codec)
+       alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+       hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+-      if (hp_pin_sense)
++      if (hp_pin_sense) {
+               msleep(2);
+-      snd_hda_codec_write(codec, hp_pin, 0,
++              snd_hda_codec_write(codec, hp_pin, 0,
+                           AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+-      if (hp_pin_sense || spec->ultra_low_power)
+-              msleep(85);
++              msleep(75);
+       /* 3k pull low control for Headset jack. */
+       /* NOTE: call this before clearing the pin, otherwise codec stalls */
+       /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
+        * when booting with headset plugged. So skip setting it for the codec alc257
+        */
+-      if (spec->en_3kpull_low)
+-              alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
++              if (spec->en_3kpull_low)
++                      alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
+-      if (!spec->no_shutup_pins)
+-              snd_hda_codec_write(codec, hp_pin, 0,
++              if (!spec->no_shutup_pins)
++                      snd_hda_codec_write(codec, hp_pin, 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+-      if (hp_pin_sense || spec->ultra_low_power)
+-              msleep(100);
++              msleep(75);
++      }
+       alc_auto_setup_eapd(codec, false);
+       alc_shutup_pins(codec);
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch b/queue-5.10/alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch
new file mode 100644 (file)
index 0000000..7bc8469
--- /dev/null
@@ -0,0 +1,50 @@
+From e4ea1588ecfb97e4717f974e39c6a38ed32f977b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 12:10:36 +0100
+Subject: ALSA: us122l: Use snd_card_free_when_closed() at disconnection
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit b7df09bb348016943f56b09dcaafe221e3f73947 ]
+
+The USB disconnect callback is supposed to be short and not too-long
+waiting.  OTOH, the current code uses snd_card_free() at
+disconnection, but this waits for the close of all used fds, hence it
+can take long.  It eventually blocks the upper layer USB ioctls, which
+may trigger a soft lockup.
+
+An easy workaround is to replace snd_card_free() with
+snd_card_free_when_closed().  This variant returns immediately while
+the release of resources is done asynchronously by the card device
+release at the last close.
+
+The loop of us122l->mmap_count check is dropped as well.  The check is
+useless for the asynchronous operation with *_when_closed().
+
+Fixes: 030a07e44129 ("ALSA: Add USB US122L driver")
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20241113111042.15058-3-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/usx2y/us122l.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
+index 0b0a87a631a06..bccb47d38c6dc 100644
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -617,10 +617,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
+       usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
+       usb_put_dev(us122l->dev);
+-      while (atomic_read(&us122l->mmap_count))
+-              msleep(500);
+-
+-      snd_card_free(card);
++      snd_card_free_when_closed(card);
+ }
+ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch b/queue-5.10/alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch
new file mode 100644 (file)
index 0000000..9ac33b4
--- /dev/null
@@ -0,0 +1,167 @@
+From 759895f8bb6fd488aa135c3f7d1a1224c384a46d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 15:15:44 +0200
+Subject: ALSA: usx2y: Cleanup probe and disconnect callbacks
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 2ac7a12ead2be2e31bd5e796455bef31e8516845 ]
+
+Minor code refactoring by merging the superfluous function calls.
+The functions were split in the past for covering pre-history USB
+driver code, but this is utterly useless.
+
+Link: https://lore.kernel.org/r/20210517131545.27252-11-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/usx2y/usbusx2y.c | 107 ++++++++++++++-----------------------
+ 1 file changed, 40 insertions(+), 67 deletions(-)
+
+diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
+index 373c600ba3fec..9d5a33c4ff2f3 100644
+--- a/sound/usb/usx2y/usbusx2y.c
++++ b/sound/usb/usx2y/usbusx2y.c
+@@ -149,7 +149,6 @@ MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
+ static int snd_usx2y_card_used[SNDRV_CARDS];
+-static void usx2y_usb_disconnect(struct usb_device *usb_device, void *ptr);
+ static void snd_usx2y_card_private_free(struct snd_card *card);
+ /*
+@@ -363,66 +362,6 @@ static int usx2y_create_card(struct usb_device *device,
+       return 0;
+ }
+-static int usx2y_usb_probe(struct usb_device *device,
+-                         struct usb_interface *intf,
+-                         const struct usb_device_id *device_id,
+-                         struct snd_card **cardp)
+-{
+-      int             err;
+-      struct snd_card *card;
+-
+-      *cardp = NULL;
+-      if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
+-          (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
+-           le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
+-           le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
+-              return -EINVAL;
+-
+-      err = usx2y_create_card(device, intf, &card);
+-      if (err < 0)
+-              return err;
+-      err = usx2y_hwdep_new(card, device);
+-      if (err < 0)
+-              goto error;
+-      err = snd_card_register(card);
+-      if (err < 0)
+-              goto error;
+-      *cardp = card;
+-      return 0;
+-
+- error:
+-      snd_card_free(card);
+-      return err;
+-}
+-
+-/*
+- * new 2.5 USB kernel API
+- */
+-static int snd_usx2y_probe(struct usb_interface *intf, const struct usb_device_id *id)
+-{
+-      struct snd_card *card;
+-      int err;
+-
+-      err = usx2y_usb_probe(interface_to_usbdev(intf), intf, id, &card);
+-      if (err < 0)
+-              return err;
+-      dev_set_drvdata(&intf->dev, card);
+-      return 0;
+-}
+-
+-static void snd_usx2y_disconnect(struct usb_interface *intf)
+-{
+-      usx2y_usb_disconnect(interface_to_usbdev(intf),
+-                           usb_get_intfdata(intf));
+-}
+-
+-static struct usb_driver snd_usx2y_usb_driver = {
+-      .name =         "snd-usb-usx2y",
+-      .probe =        snd_usx2y_probe,
+-      .disconnect =   snd_usx2y_disconnect,
+-      .id_table =     snd_usx2y_usb_id_table,
+-};
+-
+ static void snd_usx2y_card_private_free(struct snd_card *card)
+ {
+       struct usx2ydev *usx2y = usx2y(card);
+@@ -436,18 +375,15 @@ static void snd_usx2y_card_private_free(struct snd_card *card)
+               snd_usx2y_card_used[usx2y->card_index] = 0;
+ }
+-/*
+- * Frees the device.
+- */
+-static void usx2y_usb_disconnect(struct usb_device *device, void *ptr)
++static void snd_usx2y_disconnect(struct usb_interface *intf)
+ {
+       struct snd_card *card;
+       struct usx2ydev *usx2y;
+       struct list_head *p;
+-      if (!ptr)
++      card = usb_get_intfdata(intf);
++      if (!card)
+               return;
+-      card = ptr;
+       usx2y = usx2y(card);
+       usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
+       usx2y_unlinkseq(&usx2y->as04);
+@@ -463,4 +399,41 @@ static void usx2y_usb_disconnect(struct usb_device *device, void *ptr)
+       snd_card_free(card);
+ }
++static int snd_usx2y_probe(struct usb_interface *intf,
++                         const struct usb_device_id *id)
++{
++      struct usb_device *device = interface_to_usbdev(intf);
++      struct snd_card *card;
++      int err;
++
++      if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
++          (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
++           le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
++           le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
++              return -EINVAL;
++
++      err = usx2y_create_card(device, intf, &card);
++      if (err < 0)
++              return err;
++      err = usx2y_hwdep_new(card, device);
++      if (err < 0)
++              goto error;
++      err = snd_card_register(card);
++      if (err < 0)
++              goto error;
++
++      dev_set_drvdata(&intf->dev, card);
++      return 0;
++
++ error:
++      snd_card_free(card);
++      return err;
++}
++
++static struct usb_driver snd_usx2y_usb_driver = {
++      .name =         "snd-usb-usx2y",
++      .probe =        snd_usx2y_probe,
++      .disconnect =   snd_usx2y_disconnect,
++      .id_table =     snd_usx2y_usb_id_table,
++};
+ module_usb_driver(snd_usx2y_usb_driver);
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-usx2y-coding-style-fixes.patch b/queue-5.10/alsa-usx2y-coding-style-fixes.patch
new file mode 100644 (file)
index 0000000..cd224f1
--- /dev/null
@@ -0,0 +1,1719 @@
+From 7500224b4d11492fe8f8eea79b20490c4cabff53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 15:15:37 +0200
+Subject: ALSA: usx2y: Coding style fixes
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit a829dd5b3840fd9a24608ed73eb21ba239ae5334 ]
+
+This patch fixes various trivial coding-style issues in usx2y code,
+such as:
+* the assginments in if condition
+* comparison order with constants
+* NULL / zero checks
+* unsigned -> unsigned int
+* addition of braces in control blocks
+* debug print with function names
+* move local variables in block into function head
+* reduction of too nested indentations
+
+No functional changes.
+
+Link: https://lore.kernel.org/r/20210517131545.27252-4-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/usx2y/us122l.c        |  25 ++--
+ sound/usb/usx2y/us122l.h        |   2 +-
+ sound/usb/usx2y/usX2Yhwdep.c    |  38 ++---
+ sound/usb/usx2y/usb_stream.c    |  32 +++--
+ sound/usb/usx2y/usb_stream.h    |  23 ++--
+ sound/usb/usx2y/usbusx2y.c      | 122 ++++++++--------
+ sound/usb/usx2y/usbusx2y.h      |   2 +-
+ sound/usb/usx2y/usbusx2yaudio.c | 220 +++++++++++++++--------------
+ sound/usb/usx2y/usx2yhwdeppcm.c | 237 +++++++++++++++++---------------
+ 9 files changed, 381 insertions(+), 320 deletions(-)
+
+diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
+index 53e7eb4480b30..0b0a87a631a06 100644
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -114,9 +114,9 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
+               goto unlock;
+       offset = vmf->pgoff << PAGE_SHIFT;
+-      if (offset < PAGE_ALIGN(s->read_size))
++      if (offset < PAGE_ALIGN(s->read_size)) {
+               vaddr = (char *)s + offset;
+-      else {
++      } else {
+               offset -= PAGE_ALIGN(s->read_size);
+               if (offset >= PAGE_ALIGN(s->write_size))
+                       goto unlock;
+@@ -238,7 +238,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
+                                         struct file *file, poll_table *wait)
+ {
+       struct us122l   *us122l = hw->private_data;
+-      unsigned        *polled;
++      unsigned int    *polled;
+       __poll_t        mask;
+       poll_wait(file, &us122l->sk.sleep, wait);
+@@ -255,8 +255,9 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
+                       if (*polled != s->periods_done) {
+                               *polled = s->periods_done;
+                               mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM;
+-                      } else
++                      } else {
+                               mask = 0;
++                      }
+               }
+               mutex_unlock(&us122l->mutex);
+       }
+@@ -294,11 +295,11 @@ static int us122l_set_sample_rate(struct usb_device *dev, int rate)
+ }
+ static bool us122l_start(struct us122l *us122l,
+-                       unsigned rate, unsigned period_frames)
++                       unsigned int rate, unsigned int period_frames)
+ {
+       struct list_head *p;
+       int err;
+-      unsigned use_packsize = 0;
++      unsigned int use_packsize = 0;
+       bool success = false;
+       if (us122l->dev->speed == USB_SPEED_HIGH) {
+@@ -331,7 +332,7 @@ static bool us122l_start(struct us122l *us122l,
+       err = usb_stream_start(&us122l->sk);
+       if (err < 0) {
+               us122l_stop(us122l);
+-              snd_printk(KERN_ERR "us122l_start error %i\n", err);
++              snd_printk(KERN_ERR "%s error %i\n", __func__, err);
+               goto out;
+       }
+       list_for_each(p, &us122l->midi_list)
+@@ -342,12 +343,12 @@ static bool us122l_start(struct us122l *us122l,
+ }
+ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
+-                                unsigned cmd, unsigned long arg)
++                                unsigned int cmd, unsigned long arg)
+ {
+       struct usb_stream_config cfg;
+       struct us122l *us122l = hw->private_data;
+       struct usb_stream *s;
+-      unsigned min_period_frames;
++      unsigned int min_period_frames;
+       int err = 0;
+       bool high_speed;
+@@ -388,9 +389,9 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
+       mutex_lock(&us122l->mutex);
+       s = us122l->sk.s;
+-      if (!us122l->master)
++      if (!us122l->master) {
+               us122l->master = file;
+-      else if (us122l->master != file) {
++      } else if (us122l->master != file) {
+               if (!s || memcmp(&cfg, &s->cfg, sizeof(cfg))) {
+                       err = -EIO;
+                       goto unlock;
+@@ -490,7 +491,7 @@ static void snd_us122l_free(struct snd_card *card)
+       struct us122l   *us122l = US122L(card);
+       int             index = us122l->card_index;
+-      if (index >= 0  &&  index < SNDRV_CARDS)
++      if (index >= 0 && index < SNDRV_CARDS)
+               snd_us122l_card_used[index] = 0;
+ }
+diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
+index 34bea99d343ca..c32ae5e981e90 100644
+--- a/sound/usb/usx2y/us122l.h
++++ b/sound/usb/usx2y/us122l.h
+@@ -11,7 +11,7 @@ struct us122l {
+       struct mutex            mutex;
+       struct file             *first;
+-      unsigned                second_periods_polled;
++      unsigned int            second_periods_polled;
+       struct file             *master;
+       struct file             *slave;
+       struct list_head        midi_list;
+diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
+index 90246518dbddb..2d4e943be2dad 100644
+--- a/sound/usb/usx2y/usX2Yhwdep.c
++++ b/sound/usb/usx2y/usX2Yhwdep.c
+@@ -85,7 +85,7 @@ static __poll_t snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll
+       poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
+-      if (shm != NULL && shm->ctl_snapshot_last != shm->ctl_snapshot_red)
++      if (shm && shm->ctl_snapshot_last != shm->ctl_snapshot_red)
+               mask |= EPOLLIN;
+       return mask;
+@@ -114,7 +114,7 @@ static int snd_usx2y_hwdep_dsp_status(struct snd_hwdep *hw,
+               id = USX2Y_TYPE_428;
+               break;
+       }
+-      if (0 > id)
++      if (id < 0)
+               return -ENODEV;
+       strcpy(info->id, type_ids[id]);
+       info->num_dsps = 2;             // 0: Prepad Data, 1: FPGA Code
+@@ -158,7 +158,7 @@ static int usx2y_create_usbmidi(struct snd_card *card)
+               le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
+               &quirk_2 : &quirk_1;
+-      snd_printdd("usx2y_create_usbmidi\n");
++      snd_printdd("%s\n", __func__);
+       return snd_usbmidi_create(card, iface, &usx2y(card)->midi_list, quirk);
+ }
+@@ -166,20 +166,21 @@ static int usx2y_create_alsa_devices(struct snd_card *card)
+ {
+       int err;
+-      do {
+-              if ((err = usx2y_create_usbmidi(card)) < 0) {
+-                      snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i\n", err);
+-                      break;
+-              }
+-              if ((err = usx2y_audio_create(card)) < 0)
+-                      break;
+-              if ((err = usx2y_hwdep_pcm_new(card)) < 0)
+-                      break;
+-              if ((err = snd_card_register(card)) < 0)
+-                      break;
+-      } while (0);
+-
+-      return err;
++      err = usx2y_create_usbmidi(card);
++      if (err < 0) {
++              snd_printk(KERN_ERR "%s: usx2y_create_usbmidi error %i\n", __func__, err);
++              return err;
++      }
++      err = usx2y_audio_create(card);
++      if (err < 0)
++              return err;
++      err = usx2y_hwdep_pcm_new(card);
++      if (err < 0)
++              return err;
++      err = snd_card_register(card);
++      if (err < 0)
++              return err;
++      return 0;
+ }
+ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
+@@ -233,7 +234,8 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device)
+       int err;
+       struct snd_hwdep *hw;
+-      if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
++      err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw);
++      if (err < 0)
+               return err;
+       hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
+diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
+index 5726466c53257..9d0e44793896f 100644
+--- a/sound/usb/usx2y/usb_stream.c
++++ b/sound/usb/usx2y/usb_stream.c
+@@ -10,7 +10,7 @@
+ /*                             setup                                  */
+-static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
++static unsigned int usb_stream_next_packet_size(struct usb_stream_kernel *sk)
+ {
+       struct usb_stream *s = sk->s;
+@@ -44,9 +44,10 @@ static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
+                   lb, s->period_size);
+ }
+-static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+-                         struct urb **urbs, char *transfer,
+-                         struct usb_device *dev, int pipe)
++static int init_pipe_urbs(struct usb_stream_kernel *sk,
++                        unsigned int use_packsize,
++                        struct urb **urbs, char *transfer,
++                        struct usb_device *dev, int pipe)
+ {
+       int u, p;
+       int maxpacket = use_packsize ?
+@@ -82,8 +83,8 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+       return 0;
+ }
+-static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+-                    struct usb_device *dev, int in_pipe, int out_pipe)
++static int init_urbs(struct usb_stream_kernel *sk, unsigned int use_packsize,
++                   struct usb_device *dev, int in_pipe, int out_pipe)
+ {
+       struct usb_stream       *s = sk->s;
+       char                    *indata =
+@@ -112,7 +113,7 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+  * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
+  * this will overflow at approx 524 kHz
+  */
+-static inline unsigned get_usb_full_speed_rate(unsigned rate)
++static inline unsigned int get_usb_full_speed_rate(unsigned int rate)
+ {
+       return ((rate << 13) + 62) / 125;
+ }
+@@ -121,7 +122,7 @@ static inline unsigned get_usb_full_speed_rate(unsigned rate)
+  * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
+  * this will overflow at approx 4 MHz
+  */
+-static inline unsigned get_usb_high_speed_rate(unsigned rate)
++static inline unsigned int get_usb_high_speed_rate(unsigned int rate)
+ {
+       return ((rate << 10) + 62) / 125;
+ }
+@@ -129,7 +130,7 @@ static inline unsigned get_usb_high_speed_rate(unsigned rate)
+ void usb_stream_free(struct usb_stream_kernel *sk)
+ {
+       struct usb_stream *s;
+-      unsigned u;
++      unsigned int u;
+       for (u = 0; u < USB_STREAM_NURBS; ++u) {
+               usb_free_urb(sk->inurb[u]);
+@@ -153,9 +154,12 @@ void usb_stream_free(struct usb_stream_kernel *sk)
+ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
+                                 struct usb_device *dev,
+-                                unsigned in_endpoint, unsigned out_endpoint,
+-                                unsigned sample_rate, unsigned use_packsize,
+-                                unsigned period_frames, unsigned frame_size)
++                                unsigned int in_endpoint,
++                                unsigned int out_endpoint,
++                                unsigned int sample_rate,
++                                unsigned int use_packsize,
++                                unsigned int period_frames,
++                                unsigned int frame_size)
+ {
+       int packets, max_packsize;
+       int in_pipe, out_pipe;
+@@ -531,7 +535,7 @@ static void stream_start(struct usb_stream_kernel *sk,
+       if (s->state >= usb_stream_sync1) {
+               int l, p, max_diff, max_diff_0;
+               int urb_size = 0;
+-              unsigned frames_per_packet, min_frames = 0;
++              unsigned int frames_per_packet, min_frames = 0;
+               frames_per_packet = (s->period_size - s->idle_insize);
+               frames_per_packet <<= 8;
+@@ -573,7 +577,7 @@ static void stream_start(struct usb_stream_kernel *sk,
+                               (s->inpacket_head + 1) % s->inpackets;
+                       s->next_inpacket_split_at = 0;
+               } else {
+-                      unsigned split = s->inpacket_head;
++                      unsigned int split = s->inpacket_head;
+                       l = s->idle_insize;
+                       while (l > s->inpacket[split].length) {
+diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h
+index 851358a8d709a..73e57b341adc8 100644
+--- a/sound/usb/usx2y/usb_stream.h
++++ b/sound/usb/usx2y/usb_stream.h
+@@ -12,7 +12,7 @@ struct usb_stream_kernel {
+       void *write_page;
+-      unsigned n_o_ps;
++      unsigned int n_o_ps;
+       struct urb *inurb[USB_STREAM_NURBS];
+       struct urb *idle_inurb;
+@@ -26,18 +26,21 @@ struct usb_stream_kernel {
+       wait_queue_head_t sleep;
+-      unsigned out_phase;
+-      unsigned out_phase_peeked;
+-      unsigned freqn;
++      unsigned int out_phase;
++      unsigned int out_phase_peeked;
++      unsigned int freqn;
+ };
+ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
+                                 struct usb_device *dev,
+-                                unsigned in_endpoint, unsigned out_endpoint,
+-                                unsigned sample_rate, unsigned use_packsize,
+-                                unsigned period_frames, unsigned frame_size);
+-void usb_stream_free(struct usb_stream_kernel *);
+-int usb_stream_start(struct usb_stream_kernel *);
+-void usb_stream_stop(struct usb_stream_kernel *);
++                                unsigned int in_endpoint,
++                                unsigned int out_endpoint,
++                                unsigned int sample_rate,
++                                unsigned int use_packsize,
++                                unsigned int period_frames,
++                                unsigned int frame_size);
++void usb_stream_free(struct usb_stream_kernel *sk);
++int usb_stream_start(struct usb_stream_kernel *sk);
++void usb_stream_stop(struct usb_stream_kernel *sk);
+ #endif /* __USB_STREAM_H */
+diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
+index 9bd2ade8f9b5b..373c600ba3fec 100644
+--- a/sound/usb/usx2y/usbusx2y.c
++++ b/sound/usb/usx2y/usbusx2y.c
+@@ -164,7 +164,7 @@ static void i_usx2y_out04_int(struct urb *urb)
+               for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++)
+                       ;
+-              snd_printdd("i_usx2y_out04_int() urb %i status=%i\n", i, urb->status);
++              snd_printdd("%s urb %i status=%i\n", __func__, i, urb->status);
+       }
+ #endif
+ }
+@@ -174,6 +174,8 @@ static void i_usx2y_in04_int(struct urb *urb)
+       int                     err = 0;
+       struct usx2ydev         *usx2y = urb->context;
+       struct us428ctls_sharedmem      *us428ctls = usx2y->us428ctls_sharedmem;
++      struct us428_p4out *p4out;
++      int i, j, n, diff, send;
+       usx2y->in04_int_calls++;
+@@ -184,15 +186,12 @@ static void i_usx2y_in04_int(struct urb *urb)
+       //      printk("%i:0x%02X ", 8, (int)((unsigned char*)usx2y->in04_buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
+       if (us428ctls) {
+-              int diff = -1;
+-
+-              if (-2 == us428ctls->ctl_snapshot_last) {
++              diff = -1;
++              if (us428ctls->ctl_snapshot_last == -2) {
+                       diff = 0;
+                       memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
+                       us428ctls->ctl_snapshot_last = -1;
+               } else {
+-                      int i;
+-
+                       for (i = 0; i < 21; i++) {
+                               if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {
+                                       if (diff < 0)
+@@ -201,10 +200,9 @@ static void i_usx2y_in04_int(struct urb *urb)
+                               }
+                       }
+               }
+-              if (0 <= diff) {
+-                      int n = us428ctls->ctl_snapshot_last + 1;
+-
+-                      if (n >= N_US428_CTL_BUFS  ||  n < 0)
++              if (diff >= 0) {
++                      n = us428ctls->ctl_snapshot_last + 1;
++                      if (n >= N_US428_CTL_BUFS || n < 0)
+                               n = 0;
+                       memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0]));
+                       us428ctls->ctl_snapshot_differs_at[n] = diff;
+@@ -214,21 +212,20 @@ static void i_usx2y_in04_int(struct urb *urb)
+       }
+       if (usx2y->us04) {
+-              if (0 == usx2y->us04->submitted)
++              if (!usx2y->us04->submitted) {
+                       do {
+                               err = usb_submit_urb(usx2y->us04->urb[usx2y->us04->submitted++], GFP_ATOMIC);
+                       } while (!err && usx2y->us04->submitted < usx2y->us04->len);
+-      } else
++              }
++      } else {
+               if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) {
+                       if (us428ctls->p4out_last != us428ctls->p4out_sent) {
+-                              int j, send = us428ctls->p4out_sent + 1;
+-
++                              send = us428ctls->p4out_sent + 1;
+                               if (send >= N_US428_P4OUT_BUFS)
+                                       send = 0;
+-                              for (j = 0; j < URBS_ASYNC_SEQ  &&  !err; ++j)
+-                                      if (0 == usx2y->as04.urb[j]->status) {
+-                                              struct us428_p4out *p4out = us428ctls->p4out + send;    // FIXME if more than 1 p4out is new, 1 gets lost.
+-
++                              for (j = 0; j < URBS_ASYNC_SEQ && !err; ++j) {
++                                      if (!usx2y->as04.urb[j]->status) {
++                                              p4out = us428ctls->p4out + send;        // FIXME if more than 1 p4out is new, 1 gets lost.
+                                               usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev,
+                                                                 usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol,
+                                                                 p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5,
+@@ -237,8 +234,10 @@ static void i_usx2y_in04_int(struct urb *urb)
+                                               us428ctls->p4out_sent = send;
+                                               break;
+                                       }
++                              }
+                       }
+               }
++      }
+       if (err)
+               snd_printk(KERN_ERR "in04_int() usb_submit_urb err=%i\n", err);
+@@ -256,31 +255,35 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y)
+       usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ,
+                                          URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL);
+-      if (NULL == usx2y->as04.buffer) {
++      if (!usx2y->as04.buffer) {
+               err = -ENOMEM;
+-      } else
++      } else {
+               for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
+-                      if (NULL == (usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
++                      usx2y->as04.urb[i] = usb_alloc_urb(0, GFP_KERNEL);
++                      if (!usx2y->as04.urb[i]) {
+                               err = -ENOMEM;
+                               break;
+                       }
+                       usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev,
+                                         usb_sndbulkpipe(usx2y->dev, 0x04),
+-                                        usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0,
++                                        usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ * i, 0,
+                                         i_usx2y_out04_int, usx2y);
+                       err = usb_urb_ep_type_check(usx2y->as04.urb[i]);
+                       if (err < 0)
+                               break;
+               }
++      }
+       return err;
+ }
+ int usx2y_in04_init(struct usx2ydev *usx2y)
+ {
+-      if (!(usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL)))
++      usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL);
++      if (!usx2y->in04_urb)
+               return -ENOMEM;
+-      if (!(usx2y->in04_buf = kmalloc(21, GFP_KERNEL)))
++      usx2y->in04_buf = kmalloc(21, GFP_KERNEL);
++      if (!usx2y->in04_buf)
+               return -ENOMEM;
+       init_waitqueue_head(&usx2y->in04_wait_queue);
+@@ -355,8 +358,7 @@ static int usx2y_create_card(struct usb_device *device,
+               le16_to_cpu(device->descriptor.idVendor),
+               le16_to_cpu(device->descriptor.idProduct),
+               0,//us428(card)->usbmidi.ifnum,
+-              usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum
+-              );
++              usx2y(card)->dev->bus->busnum, usx2y(card)->dev->devnum);
+       *cardp = card;
+       return 0;
+ }
+@@ -379,13 +381,18 @@ static int usx2y_usb_probe(struct usb_device *device,
+       err = usx2y_create_card(device, intf, &card);
+       if (err < 0)
+               return err;
+-      if ((err = usx2y_hwdep_new(card, device)) < 0  ||
+-          (err = snd_card_register(card)) < 0) {
+-              snd_card_free(card);
+-              return err;
+-      }
++      err = usx2y_hwdep_new(card, device);
++      if (err < 0)
++              goto error;
++      err = snd_card_register(card);
++      if (err < 0)
++              goto error;
+       *cardp = card;
+       return 0;
++
++ error:
++      snd_card_free(card);
++      return err;
+ }
+ /*
+@@ -406,7 +413,7 @@ static int snd_usx2y_probe(struct usb_interface *intf, const struct usb_device_i
+ static void snd_usx2y_disconnect(struct usb_interface *intf)
+ {
+       usx2y_usb_disconnect(interface_to_usbdev(intf),
+-                               usb_get_intfdata(intf));
++                           usb_get_intfdata(intf));
+ }
+ static struct usb_driver snd_usx2y_usb_driver = {
+@@ -418,13 +425,15 @@ static struct usb_driver snd_usx2y_usb_driver = {
+ static void snd_usx2y_card_private_free(struct snd_card *card)
+ {
+-      kfree(usx2y(card)->in04_buf);
+-      usb_free_urb(usx2y(card)->in04_urb);
+-      if (usx2y(card)->us428ctls_sharedmem)
+-              free_pages_exact(usx2y(card)->us428ctls_sharedmem,
+-                               sizeof(*usx2y(card)->us428ctls_sharedmem));
+-      if (usx2y(card)->card_index >= 0  &&  usx2y(card)->card_index < SNDRV_CARDS)
+-              snd_usx2y_card_used[usx2y(card)->card_index] = 0;
++      struct usx2ydev *usx2y = usx2y(card);
++
++      kfree(usx2y->in04_buf);
++      usb_free_urb(usx2y->in04_urb);
++      if (usx2y->us428ctls_sharedmem)
++              free_pages_exact(usx2y->us428ctls_sharedmem,
++                               sizeof(*usx2y->us428ctls_sharedmem));
++      if (usx2y->card_index >= 0 && usx2y->card_index < SNDRV_CARDS)
++              snd_usx2y_card_used[usx2y->card_index] = 0;
+ }
+ /*
+@@ -432,23 +441,26 @@ static void snd_usx2y_card_private_free(struct snd_card *card)
+  */
+ static void usx2y_usb_disconnect(struct usb_device *device, void *ptr)
+ {
+-      if (ptr) {
+-              struct snd_card *card = ptr;
+-              struct usx2ydev *usx2y = usx2y(card);
+-              struct list_head *p;
+-
+-              usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
+-              usx2y_unlinkseq(&usx2y->as04);
+-              usb_kill_urb(usx2y->in04_urb);
+-              snd_card_disconnect(card);
+-              /* release the midi resources */
+-              list_for_each(p, &usx2y->midi_list) {
+-                      snd_usbmidi_disconnect(p);
+-              }
+-              if (usx2y->us428ctls_sharedmem)
+-                      wake_up(&usx2y->us428ctls_wait_queue_head);
+-              snd_card_free(card);
++      struct snd_card *card;
++      struct usx2ydev *usx2y;
++      struct list_head *p;
++
++      if (!ptr)
++              return;
++      card = ptr;
++      usx2y = usx2y(card);
++      usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
++      usx2y_unlinkseq(&usx2y->as04);
++      usb_kill_urb(usx2y->in04_urb);
++      snd_card_disconnect(card);
++
++      /* release the midi resources */
++      list_for_each(p, &usx2y->midi_list) {
++              snd_usbmidi_disconnect(p);
+       }
++      if (usx2y->us428ctls_sharedmem)
++              wake_up(&usx2y->us428ctls_wait_queue_head);
++      snd_card_free(card);
+ }
+ module_usb_driver(snd_usx2y_usb_driver);
+diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
+index 5ad6e3767621c..6d0e97a07bb8d 100644
+--- a/sound/usb/usx2y/usbusx2y.h
++++ b/sound/usb/usx2y/usbusx2y.h
+@@ -30,7 +30,7 @@ struct usx2ydev {
+       struct urb              *in04_urb;
+       void                    *in04_buf;
+       char                    in04_last[24];
+-      unsigned                in04_int_calls;
++      unsigned int            in04_int_calls;
+       struct snd_usx2y_urb_seq        *us04;
+       wait_queue_head_t       in04_wait_queue;
+       struct snd_usx2y_async_seq      as04;
+diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
+index f92a9d52ea332..a2eeca9548f1c 100644
+--- a/sound/usb/usx2y/usbusx2yaudio.c
++++ b/sound/usb/usx2y/usbusx2yaudio.c
+@@ -61,6 +61,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+       unsigned char   *cp;
+       int             i, len, lens = 0, hwptr_done = subs->hwptr_done;
++      int             cnt, blen;
+       struct usx2ydev *usx2y = subs->usx2y;
+       for (i = 0; i < nr_of_packs(); i++) {
+@@ -79,9 +80,8 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+               /* copy a data chunk */
+               if ((hwptr_done + len) > runtime->buffer_size) {
+-                      int cnt = runtime->buffer_size - hwptr_done;
+-                      int blen = cnt * usx2y->stride;
+-
++                      cnt = runtime->buffer_size - hwptr_done;
++                      blen = cnt * usx2y->stride;
+                       memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen);
+                       memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen);
+               } else {
+@@ -89,7 +89,8 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+                              len * usx2y->stride);
+               }
+               lens += len;
+-              if ((hwptr_done += len) >= runtime->buffer_size)
++              hwptr_done += len;
++              if (hwptr_done >= runtime->buffer_size)
+                       hwptr_done -= runtime->buffer_size;
+       }
+@@ -117,9 +118,9 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
+                                 struct urb *cap_urb,
+                                 struct urb *urb)
+ {
+-      int count, counts, pack;
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
++      int count, counts, pack, len;
+       count = 0;
+       for (pack = 0; pack <  nr_of_packs(); pack++) {
+@@ -137,13 +138,11 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
+                       0;
+               urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
+       }
+-      if (atomic_read(&subs->state) >= STATE_PRERUNNING)
++      if (atomic_read(&subs->state) >= STATE_PRERUNNING) {
+               if (subs->hwptr + count > runtime->buffer_size) {
+                       /* err, the transferred area goes over buffer boundary.
+                        * copy the data to the temp buffer.
+                        */
+-                      int len;
+-
+                       len = runtime->buffer_size - subs->hwptr;
+                       urb->transfer_buffer = subs->tmpbuf;
+                       memcpy(subs->tmpbuf, runtime->dma_area +
+@@ -155,11 +154,13 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
+               } else {
+                       /* set the buffer pointer */
+                       urb->transfer_buffer = runtime->dma_area + subs->hwptr * usx2y->stride;
+-                      if ((subs->hwptr += count) >= runtime->buffer_size)
++                      subs->hwptr += count;
++                      if (subs->hwptr >= runtime->buffer_size)
+                               subs->hwptr -= runtime->buffer_size;
+               }
+-      else
++      } else {
+               urb->transfer_buffer = subs->tmpbuf;
++      }
+       urb->transfer_buffer_length = count * usx2y->stride;
+       return 0;
+ }
+@@ -190,25 +191,26 @@ static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, i
+       if (!urb)
+               return -ENODEV;
+-      urb->start_frame = (frame + NRURBS * nr_of_packs());  // let hcd do rollover sanity checks
++      urb->start_frame = frame + NRURBS * nr_of_packs();  // let hcd do rollover sanity checks
+       urb->hcpriv = NULL;
+       urb->dev = subs->usx2y->dev; /* we need to set this at each time */
+-      if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
++      err = usb_submit_urb(urb, GFP_ATOMIC);
++      if (err < 0) {
+               snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
+               return err;
+       }
+       return 0;
+ }
+-static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+-                                        struct snd_usx2y_substream *playbacksubs,
+-                                        int frame)
++static int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
++                                 struct snd_usx2y_substream *playbacksubs,
++                                 int frame)
+ {
+       int err, state;
+       struct urb *urb = playbacksubs->completed_urb;
+       state = atomic_read(&playbacksubs->state);
+-      if (NULL != urb) {
++      if (urb) {
+               if (state == STATE_RUNNING)
+                       usx2y_urb_play_retire(playbacksubs, urb);
+               else if (state >= STATE_PRERUNNING)
+@@ -226,10 +228,12 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+               }
+       }
+       if (urb) {
+-              if ((err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
+-                  (err = usx2y_urb_submit(playbacksubs, urb, frame))) {
++              err = usx2y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb);
++              if (err)
++                      return err;
++              err = usx2y_urb_submit(playbacksubs, urb, frame);
++              if (err)
+                       return err;
+-              }
+       }
+       playbacksubs->completed_urb = NULL;
+@@ -237,11 +241,14 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+       state = atomic_read(&capsubs->state);
+       if (state >= STATE_PREPARED) {
+               if (state == STATE_RUNNING) {
+-                      if ((err = usx2y_urb_capt_retire(capsubs)))
++                      err = usx2y_urb_capt_retire(capsubs);
++                      if (err)
+                               return err;
+-              } else if (state >= STATE_PRERUNNING)
++              } else if (state >= STATE_PRERUNNING) {
+                       atomic_inc(&capsubs->state);
+-              if ((err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame)))
++              }
++              err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame);
++              if (err)
+                       return err;
+       }
+       capsubs->completed_urb = NULL;
+@@ -250,26 +257,25 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+ static void usx2y_clients_stop(struct usx2ydev *usx2y)
+ {
++      struct snd_usx2y_substream *subs;
++      struct urb *urb;
+       int s, u;
+       for (s = 0; s < 4; s++) {
+-              struct snd_usx2y_substream *subs = usx2y->subs[s];
+-
++              subs = usx2y->subs[s];
+               if (subs) {
+                       snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
+                       atomic_set(&subs->state, STATE_STOPPED);
+               }
+       }
+       for (s = 0; s < 4; s++) {
+-              struct snd_usx2y_substream *subs = usx2y->subs[s];
+-
++              subs = usx2y->subs[s];
+               if (subs) {
+                       if (atomic_read(&subs->state) >= STATE_PRERUNNING)
+                               snd_pcm_stop_xrun(subs->pcm_substream);
+                       for (u = 0; u < NRURBS; u++) {
+-                              struct urb *urb = subs->urb[u];
+-
+-                              if (NULL != urb)
++                              urb = subs->urb[u];
++                              if (urb)
+                                       snd_printdd("%i status=%i start_frame=%i\n",
+                                                   u, urb->status, urb->start_frame);
+                       }
+@@ -291,6 +297,7 @@ static void i_usx2y_urb_complete(struct urb *urb)
+ {
+       struct snd_usx2y_substream *subs = urb->context;
+       struct usx2ydev *usx2y = subs->usx2y;
++      struct snd_usx2y_substream *capsubs, *playbacksubs;
+       if (unlikely(atomic_read(&subs->state) < STATE_PREPARED)) {
+               snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
+@@ -306,20 +313,18 @@ static void i_usx2y_urb_complete(struct urb *urb)
+       subs->completed_urb = urb;
+-      {
+-              struct snd_usx2y_substream *capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE],
+-                      *playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+-
+-              if (capsubs->completed_urb &&
+-                  atomic_read(&capsubs->state) >= STATE_PREPARED &&
+-                  (playbacksubs->completed_urb ||
+-                   atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
+-                      if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
+-                              usx2y->wait_iso_frame += nr_of_packs();
+-                      else {
+-                              snd_printdd("\n");
+-                              usx2y_clients_stop(usx2y);
+-                      }
++      capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
++      playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
++
++      if (capsubs->completed_urb &&
++          atomic_read(&capsubs->state) >= STATE_PREPARED &&
++          (playbacksubs->completed_urb ||
++           atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
++              if (!usx2y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
++                      usx2y->wait_iso_frame += nr_of_packs();
++              } else {
++                      snd_printdd("\n");
++                      usx2y_clients_stop(usx2y);
+               }
+       }
+ }
+@@ -327,18 +332,19 @@ static void i_usx2y_urb_complete(struct urb *urb)
+ static void usx2y_urbs_set_complete(struct usx2ydev *usx2y,
+                                   void (*complete)(struct urb *))
+ {
++      struct snd_usx2y_substream *subs;
++      struct urb *urb;
+       int s, u;
+       for (s = 0; s < 4; s++) {
+-              struct snd_usx2y_substream *subs = usx2y->subs[s];
+-
+-              if (NULL != subs)
++              subs = usx2y->subs[s];
++              if (subs) {
+                       for (u = 0; u < NRURBS; u++) {
+-                              struct urb *urb = subs->urb[u];
+-
+-                              if (NULL != urb)
++                              urb = subs->urb[u];
++                              if (urb)
+                                       urb->complete = complete;
+                       }
++              }
+       }
+ }
+@@ -354,12 +360,13 @@ static void i_usx2y_subs_startup(struct urb *urb)
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
+-      if (NULL != prepare_subs)
++      if (prepare_subs) {
+               if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
+                       usx2y_subs_startup_finish(usx2y);
+                       atomic_inc(&prepare_subs->state);
+                       wake_up(&usx2y->prepare_wait_queue);
+               }
++      }
+       i_usx2y_urb_complete(urb);
+ }
+@@ -392,7 +399,7 @@ static void usx2y_urbs_release(struct snd_usx2y_substream *subs)
+ {
+       int i;
+-      snd_printdd("usx2y_urbs_release() %i\n", subs->endpoint);
++      snd_printdd("%s %i\n", __func__, subs->endpoint);
+       for (i = 0; i < NRURBS; i++)
+               usx2y_urb_release(subs->urb + i,
+                                 subs != subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
+@@ -410,6 +417,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
+       unsigned int pipe;
+       int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+       struct usb_device *dev = subs->usx2y->dev;
++      struct urb **purb;
+       pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
+                       usb_rcvisocpipe(dev, subs->endpoint);
+@@ -417,21 +425,20 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
+       if (!subs->maxpacksize)
+               return -EINVAL;
+-      if (is_playback && NULL == subs->tmpbuf) {      /* allocate a temporary buffer for playback */
++      if (is_playback && !subs->tmpbuf) {     /* allocate a temporary buffer for playback */
+               subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
+               if (!subs->tmpbuf)
+                       return -ENOMEM;
+       }
+       /* allocate and initialize data urbs */
+       for (i = 0; i < NRURBS; i++) {
+-              struct urb **purb = subs->urb + i;
+-
++              purb = subs->urb + i;
+               if (*purb) {
+                       usb_kill_urb(*purb);
+                       continue;
+               }
+               *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
+-              if (NULL == *purb) {
++              if (!*purb) {
+                       usx2y_urbs_release(subs);
+                       return -ENOMEM;
+               }
+@@ -440,7 +447,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
+                       (*purb)->transfer_buffer =
+                               kmalloc_array(subs->maxpacksize,
+                                             nr_of_packs(), GFP_KERNEL);
+-                      if (NULL == (*purb)->transfer_buffer) {
++                      if (!(*purb)->transfer_buffer) {
+                               usx2y_urbs_release(subs);
+                               return -ENOMEM;
+                       }
+@@ -469,26 +476,26 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+ {
+       int i, err;
+       struct usx2ydev *usx2y = subs->usx2y;
++      struct urb *urb;
++      unsigned long pack;
+-      if ((err = usx2y_urbs_allocate(subs)) < 0)
++      err = usx2y_urbs_allocate(subs);
++      if (err < 0)
+               return err;
+       subs->completed_urb = NULL;
+       for (i = 0; i < 4; i++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[i];
+-              if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED)
++              if (subs && atomic_read(&subs->state) >= STATE_PREPARED)
+                       goto start;
+       }
+  start:
+       usx2y_subs_startup(subs);
+       for (i = 0; i < NRURBS; i++) {
+-              struct urb *urb = subs->urb[i];
+-
++              urb = subs->urb[i];
+               if (usb_pipein(urb->pipe)) {
+-                      unsigned long pack;
+-
+-                      if (0 == i)
++                      if (!i)
+                               atomic_set(&subs->state, STATE_STARTING3);
+                       urb->dev = usx2y->dev;
+                       for (pack = 0; pack < nr_of_packs(); pack++) {
+@@ -496,13 +503,15 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+                               urb->iso_frame_desc[pack].length = subs->maxpacksize;
+                       }
+                       urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+-                      if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
++                      err = usb_submit_urb(urb, GFP_ATOMIC);
++                      if (err < 0) {
+                               snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+                               err = -EPIPE;
+                               goto cleanup;
+-                      } else
+-                              if (i == 0)
++                      } else {
++                              if (!i)
+                                       usx2y->wait_iso_frame = urb->start_frame;
++                      }
+                       urb->transfer_flags = 0;
+               } else {
+                       atomic_set(&subs->state, STATE_STARTING1);
+@@ -510,7 +519,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+               }
+       }
+       err = 0;
+-      wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs);
++      wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs);
+       if (atomic_read(&subs->state) != STATE_PREPARED)
+               err = -EPIPE;
+@@ -541,7 +550,7 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+-              snd_printdd("snd_usx2y_pcm_trigger(START)\n");
++              snd_printdd("%s(START)\n", __func__);
+               if (atomic_read(&subs->state) == STATE_PREPARED &&
+                   atomic_read(&subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= STATE_PREPARED) {
+                       atomic_set(&subs->state, STATE_PRERUNNING);
+@@ -551,7 +560,7 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+               }
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+-              snd_printdd("snd_usx2y_pcm_trigger(STOP)\n");
++              snd_printdd("%s(STOP)\n", __func__);
+               if (atomic_read(&subs->state) >= STATE_PRERUNNING)
+                       atomic_set(&subs->state, STATE_PREPARED);
+               break;
+@@ -569,11 +578,11 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+  * if sg buffer is supported on the later version of alsa, we'll follow
+  * that.
+  */
+-static const struct s_c2
+-{
++struct s_c2 {
+       char c1, c2;
+-}
+-      setrate_44100[] = {
++};
++
++static const struct s_c2 setrate_44100[] = {
+       { 0x14, 0x08},  // this line sets 44100, well actually a little less
+       { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
+       { 0x18, 0x42},
+@@ -653,7 +662,7 @@ static void i_usx2y_04int(struct urb *urb)
+       if (urb->status)
+               snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status);
+-      if (0 == --usx2y->us04->len)
++      if (!--usx2y->us04->len)
+               wake_up(&usx2y->in04_wait_queue);
+ }
+@@ -663,21 +672,23 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+       struct snd_usx2y_urb_seq        *us = NULL;
+       int                     *usbdata = NULL;
+       const struct s_c2       *ra = rate == 48000 ? setrate_48000 : setrate_44100;
++      struct urb *urb;
+       if (usx2y->rate != rate) {
+               us = kzalloc(sizeof(*us) + sizeof(struct urb *) * NOOF_SETRATE_URBS, GFP_KERNEL);
+-              if (NULL == us) {
++              if (!us) {
+                       err = -ENOMEM;
+                       goto cleanup;
+               }
+               usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int),
+                                       GFP_KERNEL);
+-              if (NULL == usbdata) {
++              if (!usbdata) {
+                       err = -ENOMEM;
+                       goto cleanup;
+               }
+               for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
+-                      if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
++                      us->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
++                      if (!us->urb[i]) {
+                               err = -ENOMEM;
+                               goto cleanup;
+                       }
+@@ -692,7 +703,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+               us->submitted = 0;
+               us->len =       NOOF_SETRATE_URBS;
+               usx2y->us04 =   us;
+-              wait_event_timeout(usx2y->in04_wait_queue, 0 == us->len, HZ);
++              wait_event_timeout(usx2y->in04_wait_queue, !us->len, HZ);
+               usx2y->us04 =   NULL;
+               if (us->len)
+                       err = -ENODEV;
+@@ -700,8 +711,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+               if (us) {
+                       us->submitted = 2*NOOF_SETRATE_URBS;
+                       for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
+-                              struct urb *urb = us->urb[i];
+-
++                              urb = us->urb[i];
+                               if (!urb)
+                                       continue;
+                               if (urb->status) {
+@@ -722,7 +732,6 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+       return err;
+ }
+-
+ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
+ {
+       int alternate, err;
+@@ -739,7 +748,8 @@ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
+               snd_usbmidi_input_stop(p);
+       }
+       usb_kill_urb(usx2y->in04_urb);
+-      if ((err = usb_set_interface(usx2y->dev, 0, alternate))) {
++      err = usb_set_interface(usx2y->dev, 0, alternate);
++      if (err) {
+               snd_printk(KERN_ERR "usb_set_interface error\n");
+               return err;
+       }
+@@ -762,6 +772,8 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
+       snd_pcm_format_t        format = params_format(hw_params);
+       struct snd_card *card = substream->pstr->pcm->card;
+       struct usx2ydev *dev = usx2y(card);
++      struct snd_usx2y_substream *subs;
++      struct snd_pcm_substream *test_substream;
+       int i;
+       mutex_lock(&usx2y(card)->pcm_mutex);
+@@ -770,9 +782,7 @@ static int snd_usx2y_pcm_hw_params(struct snd_pcm_substream *substream,
+        * rate & format
+        */
+       for (i = 0; i < dev->pcm_devs * 2; i++) {
+-              struct snd_usx2y_substream *subs = dev->subs[i];
+-              struct snd_pcm_substream *test_substream;
+-
++              subs = dev->subs[i];
+               if (!subs)
+                       continue;
+               test_substream = subs->pcm_substream;
+@@ -800,13 +810,13 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_usx2y_substream *subs = runtime->private_data;
++      struct snd_usx2y_substream *cap_subs, *playback_subs;
+       mutex_lock(&subs->usx2y->pcm_mutex);
+       snd_printdd("snd_usx2y_hw_free(%p)\n", substream);
+-      if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
+-              struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+-
++      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++              cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+               atomic_set(&subs->state, STATE_STOPPED);
+               usx2y_urbs_release(subs);
+               if (!cap_subs->pcm_substream ||
+@@ -817,8 +827,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
+                       usx2y_urbs_release(cap_subs);
+               }
+       } else {
+-              struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+-
++              playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+               if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+                       atomic_set(&subs->state, STATE_STOPPED);
+                       usx2y_urbs_release(subs);
+@@ -841,21 +850,26 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
+       struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+       int err = 0;
+-      snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream);
++      snd_printdd("%s(%p)\n", __func__, substream);
+       mutex_lock(&usx2y->pcm_mutex);
+       usx2y_subs_prepare(subs);
+       // Start hardware streams
+       // SyncStream first....
+       if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+-              if (usx2y->format != runtime->format)
+-                      if ((err = usx2y_format_set(usx2y, runtime->format)) < 0)
++              if (usx2y->format != runtime->format) {
++                      err = usx2y_format_set(usx2y, runtime->format);
++                      if (err < 0)
+                               goto up_prepare_mutex;
+-              if (usx2y->rate != runtime->rate)
+-                      if ((err = usx2y_rate_set(usx2y, runtime->rate)) < 0)
++              }
++              if (usx2y->rate != runtime->rate) {
++                      err = usx2y_rate_set(usx2y, runtime->rate);
++                      if (err < 0)
+                               goto up_prepare_mutex;
++              }
+               snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
+-              if (0 > (err = usx2y_urbs_start(capsubs)))
++              err = usx2y_urbs_start(capsubs);
++              if (err < 0)
+                       goto up_prepare_mutex;
+       }
+@@ -888,8 +902,9 @@ static const struct snd_pcm_hardware snd_usx2y_2c = {
+ static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
+ {
+-      struct snd_usx2y_substream      *subs = ((struct snd_usx2y_substream **)
+-                                       snd_pcm_substream_chip(substream))[substream->stream];
++      struct snd_usx2y_substream      *subs =
++              ((struct snd_usx2y_substream **)
++               snd_pcm_substream_chip(substream))[substream->stream];
+       struct snd_pcm_runtime  *runtime = substream->runtime;
+       if (subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
+@@ -1006,11 +1021,14 @@ int usx2y_audio_create(struct snd_card *card)
+       INIT_LIST_HEAD(&usx2y(card)->pcm_list);
+-      if (0 > (err = usx2y_audio_stream_new(card, 0xA, 0x8)))
++      err = usx2y_audio_stream_new(card, 0xA, 0x8);
++      if (err < 0)
+               return err;
+-      if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428)
+-              if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA)))
++      if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428) {
++              err = usx2y_audio_stream_new(card, 0, 0xA);
++              if (err < 0)
+                       return err;
++      }
+       if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122)
+               err = usx2y_rate_set(usx2y(card), 44100);       // Lets us428 recognize output-volume settings, disturbs us122.
+       return err;
+diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
+index b7e15fc3d1b48..9219341d71c79 100644
+--- a/sound/usb/usx2y/usx2yhwdeppcm.c
++++ b/sound/usb/usx2y/usx2yhwdeppcm.c
+@@ -52,10 +52,10 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+       int             i, lens = 0, hwptr_done = subs->hwptr_done;
+       struct usx2ydev *usx2y = subs->usx2y;
++      int head;
+-      if (0 > usx2y->hwdep_pcm_shm->capture_iso_start) { //FIXME
+-              int head = usx2y->hwdep_pcm_shm->captured_iso_head + 1;
+-
++      if (usx2y->hwdep_pcm_shm->capture_iso_start < 0) { //FIXME
++              head = usx2y->hwdep_pcm_shm->captured_iso_head + 1;
+               if (head >= ARRAY_SIZE(usx2y->hwdep_pcm_shm->captured_iso))
+                       head = 0;
+               usx2y->hwdep_pcm_shm->capture_iso_start = head;
+@@ -70,7 +70,8 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+               }
+               lens += urb->iso_frame_desc[i].actual_length / usx2y->stride;
+       }
+-      if ((hwptr_done += lens) >= runtime->buffer_size)
++      hwptr_done += lens;
++      if (hwptr_done >= runtime->buffer_size)
+               hwptr_done -= runtime->buffer_size;
+       subs->hwptr_done = hwptr_done;
+       subs->transfer_done += lens;
+@@ -82,7 +83,7 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+       return 0;
+ }
+-static inline int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
++static int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
+                                             struct usx2ydev *usx2y)
+ {
+       return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
+@@ -106,10 +107,10 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs,
+       struct snd_usx2y_hwdep_pcm_shm *shm = usx2y->hwdep_pcm_shm;
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+-      if (0 > shm->playback_iso_start) {
++      if (shm->playback_iso_start < 0) {
+               shm->playback_iso_start = shm->captured_iso_head -
+                       usx2y_iso_frames_per_buffer(runtime, usx2y);
+-              if (0 > shm->playback_iso_start)
++              if (shm->playback_iso_start < 0)
+                       shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
+               shm->playback_iso_head = shm->playback_iso_start;
+       }
+@@ -136,18 +137,18 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs,
+       return 0;
+ }
+-static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs,
+-                                                   struct urb *urb)
++static void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs,
++                                            struct urb *urb)
+ {
+-      int pack;
++      struct usb_iso_packet_descriptor *desc;
++      struct snd_usx2y_hwdep_pcm_shm *shm;
++      int pack, head;
+       for (pack = 0; pack < nr_of_packs(); ++pack) {
+-              struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
+-
+-              if (NULL != subs) {
+-                      struct snd_usx2y_hwdep_pcm_shm *shm = subs->usx2y->hwdep_pcm_shm;
+-                      int head = shm->captured_iso_head + 1;
+-
++              desc = urb->iso_frame_desc + pack;
++              if (subs) {
++                      shm = subs->usx2y->hwdep_pcm_shm;
++                      head = shm->captured_iso_head + 1;
+                       if (head >= ARRAY_SIZE(shm->captured_iso))
+                               head = 0;
+                       shm->captured_iso[head].frame = urb->start_frame + pack;
+@@ -156,22 +157,22 @@ static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream
+                       shm->captured_iso_head = head;
+                       shm->captured_iso_frames++;
+               }
+-              if ((desc->offset += desc->length * NRURBS*nr_of_packs()) +
+-                  desc->length >= SSS)
++              desc->offset += desc->length * NRURBS * nr_of_packs();
++              if (desc->offset + desc->length >= SSS)
+                       desc->offset -= (SSS - desc->length);
+       }
+ }
+-static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *capsubs,
+-                                               struct snd_usx2y_substream *capsubs2,
+-                                               struct snd_usx2y_substream *playbacksubs,
+-                                               int frame)
++static int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *capsubs,
++                                        struct snd_usx2y_substream *capsubs2,
++                                        struct snd_usx2y_substream *playbacksubs,
++                                        int frame)
+ {
+       int err, state;
+       struct urb *urb = playbacksubs->completed_urb;
+       state = atomic_read(&playbacksubs->state);
+-      if (NULL != urb) {
++      if (urb) {
+               if (state == STATE_RUNNING)
+                       usx2y_urb_play_retire(playbacksubs, urb);
+               else if (state >= STATE_PRERUNNING)
+@@ -189,10 +190,12 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap
+               }
+       }
+       if (urb) {
+-              if ((err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
+-                  (err = usx2y_urb_submit(playbacksubs, urb, frame))) {
++              err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb);
++              if (err)
++                      return err;
++              err = usx2y_hwdep_urb_play_prepare(playbacksubs, urb);
++              if (err)
+                       return err;
+-              }
+       }
+       playbacksubs->completed_urb = NULL;
+@@ -200,21 +203,26 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap
+       state = atomic_read(&capsubs->state);
+       if (state >= STATE_PREPARED) {
+               if (state == STATE_RUNNING) {
+-                      if ((err = usx2y_usbpcm_urb_capt_retire(capsubs)))
++                      err = usx2y_usbpcm_urb_capt_retire(capsubs);
++                      if (err)
+                               return err;
+-              } else if (state >= STATE_PRERUNNING)
++              } else if (state >= STATE_PRERUNNING) {
+                       atomic_inc(&capsubs->state);
++              }
+               usx2y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
+-              if (NULL != capsubs2)
++              if (capsubs2)
+                       usx2y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
+-              if ((err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame)))
++              err = usx2y_urb_submit(capsubs, capsubs->completed_urb, frame);
++              if (err)
+                       return err;
+-              if (NULL != capsubs2)
+-                      if ((err = usx2y_urb_submit(capsubs2, capsubs2->completed_urb, frame)))
++              if (capsubs2) {
++                      err = usx2y_urb_submit(capsubs2, capsubs2->completed_urb, frame);
++                      if (err)
+                               return err;
++              }
+       }
+       capsubs->completed_urb = NULL;
+-      if (NULL != capsubs2)
++      if (capsubs2)
+               capsubs2->completed_urb = NULL;
+       return 0;
+ }
+@@ -242,11 +250,11 @@ static void i_usx2y_usbpcm_urb_complete(struct urb *urb)
+       capsubs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+       playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+       if (capsubs->completed_urb && atomic_read(&capsubs->state) >= STATE_PREPARED &&
+-          (NULL == capsubs2 || capsubs2->completed_urb) &&
++          (!capsubs2 || capsubs2->completed_urb) &&
+           (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < STATE_PREPARED)) {
+-              if (!usx2y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
++              if (!usx2y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
+                       usx2y->wait_iso_frame += nr_of_packs();
+-              else {
++              } else {
+                       snd_printdd("\n");
+                       usx2y_clients_stop(usx2y);
+               }
+@@ -283,14 +291,14 @@ static void i_usx2y_usbpcm_subs_startup(struct urb *urb)
+       struct snd_usx2y_substream *subs = urb->context;
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
++      struct snd_usx2y_substream *cap_subs2;
+-      if (NULL != prepare_subs &&
++      if (prepare_subs &&
+           urb->start_frame == prepare_subs->urb[0]->start_frame) {
+               atomic_inc(&prepare_subs->state);
+               if (prepare_subs == usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
+-                      struct snd_usx2y_substream *cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+-
+-                      if (cap_subs2 != NULL)
++                      cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
++                      if (cap_subs2)
+                               atomic_inc(&cap_subs2->state);
+               }
+               usx2y_usbpcm_subs_startup_finish(usx2y);
+@@ -309,6 +317,7 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs)
+       unsigned int pipe;
+       int is_playback = subs == subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+       struct usb_device *dev = subs->usx2y->dev;
++      struct urb **purb;
+       pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
+                       usb_rcvisocpipe(dev, subs->endpoint);
+@@ -318,14 +327,13 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs)
+       /* allocate and initialize data urbs */
+       for (i = 0; i < NRURBS; i++) {
+-              struct urb **purb = subs->urb + i;
+-
++              purb = subs->urb + i;
+               if (*purb) {
+                       usb_kill_urb(*purb);
+                       continue;
+               }
+               *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
+-              if (NULL == *purb) {
++              if (!*purb) {
+                       usx2y_usbpcm_urbs_release(subs);
+                       return -ENOMEM;
+               }
+@@ -351,15 +359,17 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs)
+ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+-      struct snd_usx2y_substream *subs = runtime->private_data,
+-              *cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
++      struct snd_usx2y_substream *subs = runtime->private_data;
++      struct snd_usx2y_substream *cap_subs;
++      struct snd_usx2y_substream *playback_subs;
++      struct snd_usx2y_substream *cap_subs2;
+       mutex_lock(&subs->usx2y->pcm_mutex);
+-      snd_printdd("snd_usx2y_usbpcm_hw_free(%p)\n", substream);
+-
+-      if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
+-              struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
++      snd_printdd("%s(%p)\n", __func__, substream);
++      cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
++      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++              cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+               atomic_set(&subs->state, STATE_STOPPED);
+               usx2y_usbpcm_urbs_release(subs);
+               if (!cap_subs->pcm_substream ||
+@@ -367,21 +377,20 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+                   !cap_subs->pcm_substream->runtime->status ||
+                   cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
+                       atomic_set(&cap_subs->state, STATE_STOPPED);
+-                      if (NULL != cap_subs2)
++                      if (cap_subs2)
+                               atomic_set(&cap_subs2->state, STATE_STOPPED);
+                       usx2y_usbpcm_urbs_release(cap_subs);
+-                      if (NULL != cap_subs2)
++                      if (cap_subs2)
+                               usx2y_usbpcm_urbs_release(cap_subs2);
+               }
+       } else {
+-              struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+-
++              playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+               if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+                       atomic_set(&subs->state, STATE_STOPPED);
+-                      if (NULL != cap_subs2)
++                      if (cap_subs2)
+                               atomic_set(&cap_subs2->state, STATE_STOPPED);
+                       usx2y_usbpcm_urbs_release(subs);
+-                      if (NULL != cap_subs2)
++                      if (cap_subs2)
+                               usx2y_usbpcm_urbs_release(cap_subs2);
+               }
+       }
+@@ -403,16 +412,19 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+ {
+       int     p, u, err, stream = subs->pcm_substream->stream;
+       struct usx2ydev *usx2y = subs->usx2y;
++      struct urb *urb;
++      unsigned long pack;
+-      if (SNDRV_PCM_STREAM_CAPTURE == stream) {
++      if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+               usx2y->hwdep_pcm_shm->captured_iso_head = -1;
+               usx2y->hwdep_pcm_shm->captured_iso_frames = 0;
+       }
+       for (p = 0; 3 >= (stream + p); p += 2) {
+               struct snd_usx2y_substream *subs = usx2y->subs[stream + p];
+-              if (subs != NULL) {
+-                      if ((err = usx2y_usbpcm_urbs_allocate(subs)) < 0)
++              if (subs) {
++                      err = usx2y_usbpcm_urbs_allocate(subs);
++                      if (err < 0)
+                               return err;
+                       subs->completed_urb = NULL;
+               }
+@@ -421,7 +433,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+       for (p = 0; p < 4; p++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[p];
+-              if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED)
++              if (subs && atomic_read(&subs->state) >= STATE_PREPARED)
+                       goto start;
+       }
+@@ -431,39 +443,37 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+               for (p = 0; 3 >= (stream + p); p += 2) {
+                       struct snd_usx2y_substream *subs = usx2y->subs[stream + p];
+-                      if (subs != NULL) {
+-                              struct urb *urb = subs->urb[u];
+-
+-                              if (usb_pipein(urb->pipe)) {
+-                                      unsigned long pack;
+-
+-                                      if (0 == u)
+-                                              atomic_set(&subs->state, STATE_STARTING3);
+-                                      urb->dev = usx2y->dev;
+-                                      for (pack = 0; pack < nr_of_packs(); pack++) {
+-                                              urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
+-                                              urb->iso_frame_desc[pack].length = subs->maxpacksize;
+-                                      }
+-                                      urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+-                                      if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
+-                                              snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
+-                                              err = -EPIPE;
+-                                              goto cleanup;
+-                                      }  else {
+-                                              snd_printdd("%i\n", urb->start_frame);
+-                                              if (u == 0)
+-                                                      usx2y->wait_iso_frame = urb->start_frame;
+-                                      }
+-                                      urb->transfer_flags = 0;
+-                              } else {
+-                                      atomic_set(&subs->state, STATE_STARTING1);
+-                                      break;
++                      if (!subs)
++                              continue;
++                      urb = subs->urb[u];
++                      if (usb_pipein(urb->pipe)) {
++                              if (!u)
++                                      atomic_set(&subs->state, STATE_STARTING3);
++                              urb->dev = usx2y->dev;
++                              for (pack = 0; pack < nr_of_packs(); pack++) {
++                                      urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
++                                      urb->iso_frame_desc[pack].length = subs->maxpacksize;
+                               }
++                              urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
++                              err = usb_submit_urb(urb, GFP_KERNEL);
++                              if (err < 0) {
++                                      snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
++                                      err = -EPIPE;
++                                      goto cleanup;
++                              }  else {
++                                      snd_printdd("%i\n", urb->start_frame);
++                                      if (!u)
++                                              usx2y->wait_iso_frame = urb->start_frame;
++                              }
++                              urb->transfer_flags = 0;
++                      } else {
++                              atomic_set(&subs->state, STATE_STARTING1);
++                              break;
+                       }
+               }
+       }
+       err = 0;
+-      wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs);
++      wait_event(usx2y->prepare_wait_queue, !usx2y->prepare_subs);
+       if (atomic_read(&subs->state) != STATE_PREPARED)
+               err = -EPIPE;
+@@ -490,7 +500,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+       snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream);
+-      if (NULL == usx2y->hwdep_pcm_shm) {
++      if (!usx2y->hwdep_pcm_shm) {
+               usx2y->hwdep_pcm_shm = alloc_pages_exact(sizeof(struct snd_usx2y_hwdep_pcm_shm),
+                                                        GFP_KERNEL);
+               if (!usx2y->hwdep_pcm_shm)
+@@ -503,15 +513,20 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+       // Start hardware streams
+       // SyncStream first....
+       if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+-              if (usx2y->format != runtime->format)
+-                      if ((err = usx2y_format_set(usx2y, runtime->format)) < 0)
++              if (usx2y->format != runtime->format) {
++                      err = usx2y_format_set(usx2y, runtime->format);
++                      if (err < 0)
+                               goto up_prepare_mutex;
+-              if (usx2y->rate != runtime->rate)
+-                      if ((err = usx2y_rate_set(usx2y, runtime->rate)) < 0)
++              }
++              if (usx2y->rate != runtime->rate) {
++                      err = usx2y_rate_set(usx2y, runtime->rate);
++                      if (err < 0)
+                               goto up_prepare_mutex;
++              }
+               snd_printdd("starting capture pipe for %s\n", subs == capsubs ?
+                           "self" : "playpipe");
+-              if (0 > (err = usx2y_usbpcm_urbs_start(capsubs)))
++              err = usx2y_usbpcm_urbs_start(capsubs);
++              if (err < 0)
+                       goto up_prepare_mutex;
+       }
+@@ -528,14 +543,16 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+                                       goto up_prepare_mutex;
+                               }
+                       }
+-                      if (0 > (err = usx2y_usbpcm_urbs_start(subs)))
++                      err = usx2y_usbpcm_urbs_start(subs);
++                      if (err < 0)
+                               goto up_prepare_mutex;
+               }
+               snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
+                           usx2y_iso_frames_per_buffer(runtime, usx2y),
+                           usx2y->hwdep_pcm_shm->captured_iso_frames);
+-      } else
++      } else {
+               usx2y->hwdep_pcm_shm->capture_iso_start = -1;
++      }
+  up_prepare_mutex:
+       mutex_unlock(&usx2y->pcm_mutex);
+@@ -562,15 +579,18 @@ static const struct snd_pcm_hardware snd_usx2y_4c = {
+ static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream)
+ {
+-      struct snd_usx2y_substream      *subs = ((struct snd_usx2y_substream **)
+-                                       snd_pcm_substream_chip(substream))[substream->stream];
++      struct snd_usx2y_substream      *subs =
++              ((struct snd_usx2y_substream **)
++               snd_pcm_substream_chip(substream))[substream->stream];
+       struct snd_pcm_runtime  *runtime = substream->runtime;
+       if (!(subs->usx2y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
+               return -EBUSY;
+-      runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usx2y_2c :
+-              (subs->usx2y->subs[3] ? snd_usx2y_4c : snd_usx2y_2c);
++      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++              runtime->hw = snd_usx2y_2c;
++      else
++              runtime->hw = (subs->usx2y->subs[3] ? snd_usx2y_4c : snd_usx2y_2c);
+       runtime->private_data = subs;
+       subs->pcm_substream = substream;
+       snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
+@@ -599,11 +619,11 @@ static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = {
+ static int usx2y_pcms_busy_check(struct snd_card *card)
+ {
+       struct usx2ydev *dev = usx2y(card);
++      struct snd_usx2y_substream *subs;
+       int i;
+       for (i = 0; i < dev->pcm_devs * 2; i++) {
+-              struct snd_usx2y_substream *subs = dev->subs[i];
+-
++              subs = dev->subs[i];
+               if (subs && subs->pcm_substream &&
+                   SUBSTREAM_BUSY(subs->pcm_substream))
+                       return -EBUSY;
+@@ -677,9 +697,9 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep *hw, struct file *filp, str
+               return -EINVAL;
+       }
+-      if (!usx2y->hwdep_pcm_shm) {
++      if (!usx2y->hwdep_pcm_shm)
+               return -ENODEV;
+-      }
++
+       area->vm_ops = &snd_usx2y_hwdep_pcm_vm_ops;
+       area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+       area->vm_private_data = hw->private_data;
+@@ -690,7 +710,7 @@ static void snd_usx2y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
+ {
+       struct usx2ydev *usx2y = hwdep->private_data;
+-      if (NULL != usx2y->hwdep_pcm_shm)
++      if (usx2y->hwdep_pcm_shm)
+               free_pages_exact(usx2y->hwdep_pcm_shm, sizeof(struct snd_usx2y_hwdep_pcm_shm));
+ }
+@@ -701,10 +721,11 @@ int usx2y_hwdep_pcm_new(struct snd_card *card)
+       struct snd_pcm *pcm;
+       struct usb_device *dev = usx2y(card)->dev;
+-      if (1 != nr_of_packs())
++      if (nr_of_packs() != 1)
+               return 0;
+-      if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0)
++      err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw);
++      if (err < 0)
+               return err;
+       hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
+@@ -717,9 +738,9 @@ int usx2y_hwdep_pcm_new(struct snd_card *card)
+       sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
+       err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
+-      if (err < 0) {
++      if (err < 0)
+               return err;
+-      }
++
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usx2y_usbpcm_ops);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usx2y_usbpcm_ops);
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-usx2y-fix-spaces.patch b/queue-5.10/alsa-usx2y-fix-spaces.patch
new file mode 100644 (file)
index 0000000..78d8b70
--- /dev/null
@@ -0,0 +1,1893 @@
+From 877527906fecc26a01520a937061ca7e0e7a3019 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 15:15:36 +0200
+Subject: ALSA: usx2y: Fix spaces
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 4c0a58ef36f3de1be0d1c8565ca854bcabd37e2b ]
+
+This patch corrects merely the spaces in the usx2y code, including the
+superfluous trailing space in the debug prints and a slight reformat
+of some comment lines.  Nothing really touches about the code itself.
+
+Link: https://lore.kernel.org/r/20210517131545.27252-3-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: dafb28f02be4 ("ALSA: usx2y: Use snd_card_free_when_closed() at disconnection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/usx2y/us122l.c          |  38 ++++----
+ sound/usb/usx2y/usX2Yhwdep.c      |  52 ++++++-----
+ sound/usb/usx2y/usX2Yhwdep.h      |   2 +-
+ sound/usb/usx2y/usb_stream.c      |  43 ++++++---
+ sound/usb/usx2y/usbus428ctldefs.h |  18 ++--
+ sound/usb/usx2y/usbusx2y.c        |  78 ++++++++---------
+ sound/usb/usx2y/usbusx2y.h        |   6 +-
+ sound/usb/usx2y/usbusx2yaudio.c   | 140 +++++++++++++++++-------------
+ sound/usb/usx2y/usx2yhwdeppcm.c   |  90 +++++++++----------
+ 9 files changed, 256 insertions(+), 211 deletions(-)
+
+diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
+index 6e1bfe894dd5d..53e7eb4480b30 100644
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -49,7 +49,7 @@ static int us122l_create_usbmidi(struct snd_card *card)
+       static const struct snd_usb_audio_quirk quirk = {
+               .vendor_name =  "US122L",
+               .product_name = NAME_ALLCAPS,
+-              .ifnum =        1,
++              .ifnum =        1,
+               .type = QUIRK_MIDI_US122L,
+               .data = &quirk_data
+       };
+@@ -71,7 +71,7 @@ static int us144_create_usbmidi(struct snd_card *card)
+       static const struct snd_usb_audio_quirk quirk = {
+               .vendor_name =  "US144",
+               .product_name = NAME_ALLCAPS,
+-              .ifnum =        0,
++              .ifnum =        0,
+               .type = QUIRK_MIDI_US122L,
+               .data = &quirk_data
+       };
+@@ -95,6 +95,7 @@ static void pt_info_set(struct usb_device *dev, u8 v)
+ static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
+ {
+       struct us122l *us122l = area->vm_private_data;
++
+       atomic_inc(&us122l->mmap_count);
+       snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
+ }
+@@ -138,6 +139,7 @@ static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
+ static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
+ {
+       struct us122l *us122l = area->vm_private_data;
++
+       atomic_dec(&us122l->mmap_count);
+       snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
+ }
+@@ -148,11 +150,11 @@ static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
+       .close = usb_stream_hwdep_vm_close,
+ };
+-
+ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
+ {
+       struct us122l   *us122l = hw->private_data;
+       struct usb_interface *iface;
++
+       snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
+       if (hw->used >= 2)
+               return -EBUSY;
+@@ -173,6 +175,7 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
+ {
+       struct us122l   *us122l = hw->private_data;
+       struct usb_interface *iface;
++
+       snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
+       if (us122l->is_us144) {
+@@ -243,6 +246,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
+       mask = EPOLLIN | EPOLLOUT | EPOLLWRNORM | EPOLLERR;
+       if (mutex_trylock(&us122l->mutex)) {
+               struct usb_stream *s = us122l->sk.s;
++
+               if (s && s->state == usb_stream_ready) {
+                       if (us122l->first == file)
+                               polled = &s->periods_polled;
+@@ -262,6 +266,7 @@ static __poll_t usb_stream_hwdep_poll(struct snd_hwdep *hw,
+ static void us122l_stop(struct us122l *us122l)
+ {
+       struct list_head *p;
++
+       list_for_each(p, &us122l->midi_list)
+               snd_usbmidi_input_stop(p);
+@@ -320,13 +325,13 @@ static bool us122l_start(struct us122l *us122l,
+       err = us122l_set_sample_rate(us122l->dev, rate);
+       if (err < 0) {
+               us122l_stop(us122l);
+-              snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
++              snd_printk(KERN_ERR "us122l_set_sample_rate error\n");
+               goto out;
+       }
+       err = usb_stream_start(&us122l->sk);
+       if (err < 0) {
+               us122l_stop(us122l);
+-              snd_printk(KERN_ERR "us122l_start error %i \n", err);
++              snd_printk(KERN_ERR "us122l_start error %i\n", err);
+               goto out;
+       }
+       list_for_each(p, &us122l->midi_list)
+@@ -431,7 +436,6 @@ static int usb_stream_hwdep_new(struct snd_card *card)
+       return 0;
+ }
+-
+ static bool us122l_create_card(struct snd_card *card)
+ {
+       int err;
+@@ -440,13 +444,13 @@ static bool us122l_create_card(struct snd_card *card)
+       if (us122l->is_us144) {
+               err = usb_set_interface(us122l->dev, 0, 1);
+               if (err) {
+-                      snd_printk(KERN_ERR "usb_set_interface error \n");
++                      snd_printk(KERN_ERR "usb_set_interface error\n");
+                       return false;
+               }
+       }
+       err = usb_set_interface(us122l->dev, 1, 1);
+       if (err) {
+-              snd_printk(KERN_ERR "usb_set_interface error \n");
++              snd_printk(KERN_ERR "usb_set_interface error\n");
+               return false;
+       }
+@@ -461,13 +465,14 @@ static bool us122l_create_card(struct snd_card *card)
+       else
+               err = us122l_create_usbmidi(card);
+       if (err < 0) {
+-              snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
++              snd_printk(KERN_ERR "us122l_create_usbmidi error %i\n", err);
+               goto stop;
+       }
+       err = usb_stream_hwdep_new(card);
+       if (err < 0) {
+-/* release the midi resources */
++              /* release the midi resources */
+               struct list_head *p;
++
+               list_for_each(p, &us122l->midi_list)
+                       snd_usbmidi_disconnect(p);
+@@ -484,6 +489,7 @@ static void snd_us122l_free(struct snd_card *card)
+ {
+       struct us122l   *us122l = US122L(card);
+       int             index = us122l->card_index;
++
+       if (index >= 0  &&  index < SNDRV_CARDS)
+               snd_us122l_card_used[index] = 0;
+ }
+@@ -565,7 +571,7 @@ static int snd_us122l_probe(struct usb_interface *intf,
+       if (id->driver_info & US122L_FLAG_US144 &&
+                       device->speed == USB_SPEED_HIGH) {
+-              snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
++              snd_printk(KERN_ERR "disable ehci-hcd to run US-144\n");
+               return -ENODEV;
+       }
+@@ -601,7 +607,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
+       us122l_stop(us122l);
+       mutex_unlock(&us122l->mutex);
+-/* release the midi resources */
++      /* release the midi resources */
+       list_for_each(p, &us122l->midi_list) {
+               snd_usbmidi_disconnect(p);
+       }
+@@ -661,13 +667,13 @@ static int snd_us122l_resume(struct usb_interface *intf)
+       if (us122l->is_us144) {
+               err = usb_set_interface(us122l->dev, 0, 1);
+               if (err) {
+-                      snd_printk(KERN_ERR "usb_set_interface error \n");
++                      snd_printk(KERN_ERR "usb_set_interface error\n");
+                       goto unlock;
+               }
+       }
+       err = usb_set_interface(us122l->dev, 1, 1);
+       if (err) {
+-              snd_printk(KERN_ERR "usb_set_interface error \n");
++              snd_printk(KERN_ERR "usb_set_interface error\n");
+               goto unlock;
+       }
+@@ -677,7 +683,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
+       err = us122l_set_sample_rate(us122l->dev,
+                                    us122l->sk.s->cfg.sample_rate);
+       if (err < 0) {
+-              snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
++              snd_printk(KERN_ERR "us122l_set_sample_rate error\n");
+               goto unlock;
+       }
+       err = usb_stream_start(&us122l->sk);
+@@ -717,8 +723,8 @@ static const struct usb_device_id snd_us122l_usb_id_table[] = {
+       },
+       { /* terminator */ }
+ };
+-
+ MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
++
+ static struct usb_driver snd_us122l_usb_driver = {
+       .name =         "snd-usb-us122l",
+       .probe =        snd_us122l_probe,
+diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
+index 10868c3fb6561..90246518dbddb 100644
+--- a/sound/usb/usx2y/usX2Yhwdep.c
++++ b/sound/usb/usx2y/usX2Yhwdep.c
+@@ -21,13 +21,13 @@
+ static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
+ {
+       unsigned long offset;
+-      struct page * page;
++      struct page *page;
+       void *vaddr;
+       snd_printdd("ENTER, start %lXh, pgoff %ld\n",
+                  vmf->vma->vm_start,
+                  vmf->pgoff);
+-      
++
+       offset = vmf->pgoff << PAGE_SHIFT;
+       vaddr = (char *)((struct usx2ydev *)vmf->vma->vm_private_data)->us428ctls_sharedmem + offset;
+       page = virt_to_page(vaddr);
+@@ -44,20 +44,20 @@ static const struct vm_operations_struct us428ctls_vm_ops = {
+       .fault = snd_us428ctls_vm_fault,
+ };
+-static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
++static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area)
+ {
+       unsigned long   size = (unsigned long)(area->vm_end - area->vm_start);
+       struct usx2ydev *us428 = hw->private_data;
+       // FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs?
+       // so as long as the device isn't fully initialised yet we return -EBUSY here.
+-      if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
++      if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
+               return -EBUSY;
+-      /* if userspace tries to mmap beyond end of our buffer, fail */ 
+-        if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
+-              snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem)); 
+-                return -EINVAL;
++      /* if userspace tries to mmap beyond end of our buffer, fail */
++      if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
++              snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem));
++              return -EINVAL;
+       }
+       if (!us428->us428ctls_sharedmem) {
+@@ -79,6 +79,7 @@ static __poll_t snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll
+       __poll_t        mask = 0;
+       struct usx2ydev *us428 = hw->private_data;
+       struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem;
++
+       if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
+               return EPOLLHUP;
+@@ -123,7 +124,6 @@ static int snd_usx2y_hwdep_dsp_status(struct snd_hwdep *hw,
+       return 0;
+ }
+-
+ static int usx2y_create_usbmidi(struct snd_card *card)
+ {
+       static const struct snd_usb_midi_endpoint_info quirk_data_1 = {
+@@ -135,8 +135,8 @@ static int usx2y_create_usbmidi(struct snd_card *card)
+       static const struct snd_usb_audio_quirk quirk_1 = {
+               .vendor_name =  "TASCAM",
+               .product_name = NAME_ALLCAPS,
+-              .ifnum =        0,
+-                      .type = QUIRK_MIDI_FIXED_ENDPOINT,
++              .ifnum =        0,
++              .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = &quirk_data_1
+       };
+       static const struct snd_usb_midi_endpoint_info quirk_data_2 = {
+@@ -148,8 +148,8 @@ static int usx2y_create_usbmidi(struct snd_card *card)
+       static const struct snd_usb_audio_quirk quirk_2 = {
+               .vendor_name =  "TASCAM",
+               .product_name = "US428",
+-              .ifnum =        0,
+-                      .type = QUIRK_MIDI_FIXED_ENDPOINT,
++              .ifnum =        0,
++              .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = &quirk_data_2
+       };
+       struct usb_device *dev = usx2y(card)->dev;
+@@ -158,7 +158,7 @@ static int usx2y_create_usbmidi(struct snd_card *card)
+               le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
+               &quirk_2 : &quirk_1;
+-      snd_printdd("usx2y_create_usbmidi \n");
++      snd_printdd("usx2y_create_usbmidi\n");
+       return snd_usbmidi_create(card, iface, &usx2y(card)->midi_list, quirk);
+ }
+@@ -168,10 +168,10 @@ static int usx2y_create_alsa_devices(struct snd_card *card)
+       do {
+               if ((err = usx2y_create_usbmidi(card)) < 0) {
+-                      snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i \n", err);
++                      snd_printk(KERN_ERR "usx2y_create_alsa_devices: usx2y_create_usbmidi error %i\n", err);
+                       break;
+               }
+-              if ((err = usx2y_audio_create(card)) < 0) 
++              if ((err = usx2y_audio_create(card)) < 0)
+                       break;
+               if ((err = usx2y_hwdep_pcm_new(card)) < 0)
+                       break;
+@@ -180,17 +180,17 @@ static int usx2y_create_alsa_devices(struct snd_card *card)
+       } while (0);
+       return err;
+-} 
++}
+ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
+                                   struct snd_hwdep_dsp_image *dsp)
+ {
+       struct usx2ydev *priv = hw->private_data;
+-      struct usb_device* dev = priv->dev;
++      struct usb_device *dev = priv->dev;
+       int lret, err;
+       char *buf;
+-      snd_printdd( "dsp_load %s\n", dsp->name);
++      snd_printdd("dsp_load %s\n", dsp->name);
+       buf = memdup_user(dsp->image, dsp->length);
+       if (IS_ERR(buf))
+@@ -198,7 +198,7 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
+       err = usb_set_interface(dev, 0, 1);
+       if (err)
+-              snd_printk(KERN_ERR "usb_set_interface error \n");
++              snd_printk(KERN_ERR "usb_set_interface error\n");
+       else
+               err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
+       kfree(buf);
+@@ -208,28 +208,27 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
+               msleep(250);                            // give the device some time
+               err = usx2y_async_seq04_init(priv);
+               if (err) {
+-                      snd_printk(KERN_ERR "usx2y_async_seq04_init error \n");
++                      snd_printk(KERN_ERR "usx2y_async_seq04_init error\n");
+                       return err;
+               }
+               err = usx2y_in04_init(priv);
+               if (err) {
+-                      snd_printk(KERN_ERR "usx2y_in04_init error \n");
++                      snd_printk(KERN_ERR "usx2y_in04_init error\n");
+                       return err;
+               }
+               err = usx2y_create_alsa_devices(hw->card);
+               if (err) {
+-                      snd_printk(KERN_ERR "usx2y_create_alsa_devices error %i \n", err);
++                      snd_printk(KERN_ERR "usx2y_create_alsa_devices error %i\n", err);
+                       snd_card_free(hw->card);
+                       return err;
+               }
+-              priv->chip_status |= USX2Y_STAT_CHIP_INIT; 
++              priv->chip_status |= USX2Y_STAT_CHIP_INIT;
+               snd_printdd("%s: alsa all started\n", hw->name);
+       }
+       return err;
+ }
+-
+-int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device)
++int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device)
+ {
+       int err;
+       struct snd_hwdep *hw;
+@@ -247,4 +246,3 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device)
+       sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
+       return 0;
+ }
+-
+diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h
+index 34cef625712c6..0c9946d9cd999 100644
+--- a/sound/usb/usx2y/usX2Yhwdep.h
++++ b/sound/usb/usx2y/usX2Yhwdep.h
+@@ -2,6 +2,6 @@
+ #ifndef USX2YHWDEP_H
+ #define USX2YHWDEP_H
+-int usx2y_hwdep_new(struct snd_card *card, struct usb_device* device);
++int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device);
+ #endif
+diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
+index cff684942c4f0..5726466c53257 100644
+--- a/sound/usb/usx2y/usb_stream.c
++++ b/sound/usb/usx2y/usb_stream.c
+@@ -8,12 +8,12 @@
+ #include "usb_stream.h"
+-
+ /*                             setup                                  */
+ static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
+ {
+       struct usb_stream *s = sk->s;
++
+       sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
+       return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
+ }
+@@ -25,6 +25,7 @@ static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
+       for (pack = 0; pack < sk->n_o_ps; pack++) {
+               int l = usb_stream_next_packet_size(sk);
++
+               if (s->idle_outsize + lb + l > s->period_size)
+                       goto check;
+@@ -56,6 +57,7 @@ static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+            ++u, transfer += transfer_length) {
+               struct urb *urb = urbs[u];
+               struct usb_iso_packet_descriptor *desc;
++
+               urb->transfer_buffer = transfer;
+               urb->dev = dev;
+               urb->pipe = pipe;
+@@ -84,9 +86,8 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+                     struct usb_device *dev, int in_pipe, int out_pipe)
+ {
+       struct usb_stream       *s = sk->s;
+-      char                    *indata = (char *)s + sizeof(*s) +
+-                                      sizeof(struct usb_stream_packet) *
+-                                      s->inpackets;
++      char                    *indata =
++              (char *)s + sizeof(*s) + sizeof(struct usb_stream_packet) * s->inpackets;
+       int                     u;
+       for (u = 0; u < USB_STREAM_NURBS; ++u) {
+@@ -107,7 +108,6 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
+       return 0;
+ }
+-
+ /*
+  * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
+  * this will overflow at approx 524 kHz
+@@ -234,12 +234,12 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
+       return sk->s;
+ }
+-
+ /*                             start                                  */
+ static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
+ {
+       bool r;
++
+       if (unlikely(urb->status)) {
+               if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
+                       snd_printk(KERN_WARNING "status=%i\n", urb->status);
+@@ -270,6 +270,7 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
+       for (u = 0; u < USB_STREAM_NURBS; u++) {
+               struct urb *urb = urbs[u];
++
+               urb->complete = complete;
+       }
+ }
+@@ -287,6 +288,7 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
+       for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
+               struct urb *ii = sk->completed_inurb;
++
+               id = ii->iso_frame_desc +
+                       ii->number_of_packets + s->sync_packet;
+               l = id->actual_length;
+@@ -354,6 +356,7 @@ static int submit_urbs(struct usb_stream_kernel *sk,
+                      struct urb *inurb, struct urb *outurb)
+ {
+       int err;
++
+       prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
+       err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
+       if (err < 0)
+@@ -450,6 +453,7 @@ static void stream_idle(struct usb_stream_kernel *sk,
+       for (p = 0; p < inurb->number_of_packets; ++p) {
+               struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
++
+               l = id[p].actual_length;
+               if (unlikely(l == 0 || id[p].status)) {
+                       snd_printk(KERN_WARNING "underrun, status=%u\n",
+@@ -506,6 +510,7 @@ static void stream_idle(struct usb_stream_kernel *sk,
+ static void i_capture_idle(struct urb *urb)
+ {
+       struct usb_stream_kernel *sk = urb->context;
++
+       if (balance_capture(sk, urb))
+               stream_idle(sk, urb, sk->i_urb);
+ }
+@@ -513,6 +518,7 @@ static void i_capture_idle(struct urb *urb)
+ static void i_playback_idle(struct urb *urb)
+ {
+       struct usb_stream_kernel *sk = urb->context;
++
+       if (balance_playback(sk, urb))
+               stream_idle(sk, sk->i_urb, urb);
+ }
+@@ -521,10 +527,12 @@ static void stream_start(struct usb_stream_kernel *sk,
+                        struct urb *inurb, struct urb *outurb)
+ {
+       struct usb_stream *s = sk->s;
++
+       if (s->state >= usb_stream_sync1) {
+               int l, p, max_diff, max_diff_0;
+               int urb_size = 0;
+               unsigned frames_per_packet, min_frames = 0;
++
+               frames_per_packet = (s->period_size - s->idle_insize);
+               frames_per_packet <<= 8;
+               frames_per_packet /=
+@@ -539,6 +547,7 @@ static void stream_start(struct usb_stream_kernel *sk,
+               max_diff = max_diff_0;
+               for (p = 0; p < inurb->number_of_packets; ++p) {
+                       int diff;
++
+                       l = inurb->iso_frame_desc[p].actual_length;
+                       urb_size += l;
+@@ -565,6 +574,7 @@ static void stream_start(struct usb_stream_kernel *sk,
+                       s->next_inpacket_split_at = 0;
+               } else {
+                       unsigned split = s->inpacket_head;
++
+                       l = s->idle_insize;
+                       while (l > s->inpacket[split].length) {
+                               l -= s->inpacket[split].length;
+@@ -612,6 +622,7 @@ static void i_capture_start(struct urb *urb)
+       for (p = 0; p < urb->number_of_packets; ++p) {
+               int l = id[p].actual_length;
++
+               if (l < s->cfg.frame_size) {
+                       ++empty;
+                       if (s->state >= usb_stream_sync0) {
+@@ -631,6 +642,7 @@ static void i_capture_start(struct urb *urb)
+                      urb->iso_frame_desc[0].actual_length);
+               for (pack = 1; pack < urb->number_of_packets; ++pack) {
+                       int l = urb->iso_frame_desc[pack].actual_length;
++
+                       printk(KERN_CONT " %i", l);
+               }
+               printk(KERN_CONT "\n");
+@@ -646,6 +658,7 @@ static void i_capture_start(struct urb *urb)
+ static void i_playback_start(struct urb *urb)
+ {
+       struct usb_stream_kernel *sk = urb->context;
++
+       if (balance_playback(sk, urb))
+               stream_start(sk, sk->i_urb, urb);
+ }
+@@ -674,6 +687,7 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+       for (u = 0; u < 2; u++) {
+               struct urb *inurb = sk->inurb[u];
+               struct urb *outurb = sk->outurb[u];
++
+               playback_prep_freqn(sk, outurb);
+               inurb->number_of_packets = outurb->number_of_packets;
+               inurb->transfer_buffer_length =
+@@ -683,6 +697,7 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+               if (u == 0) {
+                       int now;
+                       struct usb_device *dev = inurb->dev;
++
+                       frame = usb_get_current_frame_number(dev);
+                       do {
+                               now = usb_get_current_frame_number(dev);
+@@ -691,14 +706,16 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+               }
+               err = usb_submit_urb(inurb, GFP_ATOMIC);
+               if (err < 0) {
+-                      snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
+-                                 " returned %i\n", u, err);
++                      snd_printk(KERN_ERR
++                                 "usb_submit_urb(sk->inurb[%i]) returned %i\n",
++                                 u, err);
+                       return err;
+               }
+               err = usb_submit_urb(outurb, GFP_ATOMIC);
+               if (err < 0) {
+-                      snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
+-                                 " returned %i\n", u, err);
++                      snd_printk(KERN_ERR
++                                 "usb_submit_urb(sk->outurb[%i]) returned %i\n",
++                                 u, err);
+                       return err;
+               }
+@@ -719,8 +736,8 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+                       snd_printd(KERN_DEBUG "goto dotry;\n");
+                       goto dotry;
+               }
+-              snd_printk(KERN_WARNING"couldn't start"
+-                         " all urbs on the same start_frame.\n");
++              snd_printk(KERN_WARNING
++                         "couldn't start all urbs on the same start_frame.\n");
+               return -EFAULT;
+       }
+@@ -732,6 +749,7 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+ /* wait, check */
+       {
+               int wait_ms = 3000;
++
+               while (s->state != usb_stream_ready && wait_ms > 0) {
+                       snd_printdd(KERN_DEBUG "%i\n", s->state);
+                       msleep(200);
+@@ -748,6 +766,7 @@ int usb_stream_start(struct usb_stream_kernel *sk)
+ void usb_stream_stop(struct usb_stream_kernel *sk)
+ {
+       int u;
++
+       if (!sk->s)
+               return;
+       for (u = 0; u < USB_STREAM_NURBS; ++u) {
+diff --git a/sound/usb/usx2y/usbus428ctldefs.h b/sound/usb/usx2y/usbus428ctldefs.h
+index 7366a940ffbba..06b27d23d3c22 100644
+--- a/sound/usb/usx2y/usbus428ctldefs.h
++++ b/sound/usb/usx2y/usbus428ctldefs.h
+@@ -39,15 +39,15 @@ enum E_IN84 {
+ struct us428_ctls {
+-      unsigned char   fader[9];
+-      unsigned char   transport;
+-      unsigned char   modifier;
+-      unsigned char   filters_elect;
+-      unsigned char   select;
+-      unsigned char   mute;
+-      unsigned char   unknown;
+-      unsigned char   wswitch;             
+-      unsigned char   wheel[5];
++      unsigned char   fader[9];
++      unsigned char   transport;
++      unsigned char   modifier;
++      unsigned char   filters_elect;
++      unsigned char   select;
++      unsigned char   mute;
++      unsigned char   unknown;
++      unsigned char   wswitch;
++      unsigned char   wheel[5];
+ };
+ struct us428_set_byte {
+diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
+index 6d910f23da0d0..9bd2ade8f9b5b 100644
+--- a/sound/usb/usx2y/usbusx2y.c
++++ b/sound/usb/usx2y/usbusx2y.c
+@@ -70,7 +70,7 @@
+ 2003-11-03 Karsten Wiese
+       Version 0.3:
+-      24Bit support. 
++      24Bit support.
+       "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works.
+ 2003-08-22 Karsten Wiese
+@@ -94,16 +94,15 @@
+       This helped me much on my slowish PII 400 & PIII 500.
+       ACPI yet untested but might cause the same bad behaviour.
+       Use a kernel with lowlatency and preemptiv patches applied.
+-      To autoload snd-usb-midi append a line 
++      To autoload snd-usb-midi append a line
+               post-install snd-usb-us428 modprobe snd-usb-midi
+       to /etc/modules.conf.
+       known problems:
+       sliders, knobs, lights not yet handled except MASTER Volume slider.
+-              "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
++      "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
+       KDE3: "Enable full duplex operation" deadlocks.
+-      
+ 2002-08-31 Karsten Wiese
+       Version 0.0.3: audio also simplex;
+       simplifying: iso urbs only 1 packet, melted structs.
+@@ -115,7 +114,7 @@
+       The firmware has been sniffed from win2k us-428 driver 3.09.
+  *   Copyright (c) 2002 - 2004 Karsten Wiese
+-*/
++ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+@@ -132,15 +131,13 @@
+ #include "usbusx2y.h"
+ #include "usX2Yhwdep.h"
+-
+-
+ MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
+ MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
+ MODULE_LICENSE("GPL");
+ MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604),"NAME_ALLCAPS"(0x8001)(0x8005)(0x8007)}}");
+ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
+-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
++static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
+ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+ module_param_array(index, int, NULL, 0444);
+@@ -150,22 +147,23 @@ MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
+ module_param_array(enable, bool, NULL, 0444);
+ MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
+-
+ static int snd_usx2y_card_used[SNDRV_CARDS];
+-static void usx2y_usb_disconnect(struct usb_device* usb_device, void* ptr);
++static void usx2y_usb_disconnect(struct usb_device *usb_device, void *ptr);
+ static void snd_usx2y_card_private_free(struct snd_card *card);
+-/* 
+- * pipe 4 is used for switching the lamps, setting samplerate, volumes ....   
++/*
++ * pipe 4 is used for switching the lamps, setting samplerate, volumes ....
+  */
+ static void i_usx2y_out04_int(struct urb *urb)
+ {
+ #ifdef CONFIG_SND_DEBUG
+       if (urb->status) {
+-              int             i;
++              int i;
+               struct usx2ydev *usx2y = urb->context;
+-              for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++);
++
++              for (i = 0; i < 10 && usx2y->as04.urb[i] != urb; i++)
++                      ;
+               snd_printdd("i_usx2y_out04_int() urb %i status=%i\n", i, urb->status);
+       }
+ #endif
+@@ -187,22 +185,25 @@ static void i_usx2y_in04_int(struct urb *urb)
+       //      printk("%i:0x%02X ", 8, (int)((unsigned char*)usx2y->in04_buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
+       if (us428ctls) {
+               int diff = -1;
++
+               if (-2 == us428ctls->ctl_snapshot_last) {
+                       diff = 0;
+                       memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
+                       us428ctls->ctl_snapshot_last = -1;
+               } else {
+                       int i;
++
+                       for (i = 0; i < 21; i++) {
+-                              if (usx2y->in04_last[i] != ((char*)usx2y->in04_buf)[i]) {
++                              if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {
+                                       if (diff < 0)
+                                               diff = i;
+-                                      usx2y->in04_last[i] = ((char*)usx2y->in04_buf)[i];
++                                      usx2y->in04_last[i] = ((char *)usx2y->in04_buf)[i];
+                               }
+                       }
+               }
+               if (0 <= diff) {
+                       int n = us428ctls->ctl_snapshot_last + 1;
++
+                       if (n >= N_US428_CTL_BUFS  ||  n < 0)
+                               n = 0;
+                       memcpy(us428ctls->ctl_snapshot + n, usx2y->in04_buf, sizeof(us428ctls->ctl_snapshot[0]));
+@@ -211,8 +212,7 @@ static void i_usx2y_in04_int(struct urb *urb)
+                       wake_up(&usx2y->us428ctls_wait_queue_head);
+               }
+       }
+-      
+-      
++
+       if (usx2y->us04) {
+               if (0 == usx2y->us04->submitted)
+                       do {
+@@ -222,11 +222,13 @@ static void i_usx2y_in04_int(struct urb *urb)
+               if (us428ctls && us428ctls->p4out_last >= 0 && us428ctls->p4out_last < N_US428_P4OUT_BUFS) {
+                       if (us428ctls->p4out_last != us428ctls->p4out_sent) {
+                               int j, send = us428ctls->p4out_sent + 1;
++
+                               if (send >= N_US428_P4OUT_BUFS)
+                                       send = 0;
+                               for (j = 0; j < URBS_ASYNC_SEQ  &&  !err; ++j)
+                                       if (0 == usx2y->as04.urb[j]->status) {
+                                               struct us428_p4out *p4out = us428ctls->p4out + send;    // FIXME if more than 1 p4out is new, 1 gets lost.
++
+                                               usb_fill_bulk_urb(usx2y->as04.urb[j], usx2y->dev,
+                                                                 usb_sndbulkpipe(usx2y->dev, 0x04), &p4out->val.vol,
+                                                                 p4out->type == ELT_LIGHT ? sizeof(struct us428_lights) : 5,
+@@ -250,8 +252,7 @@ static void i_usx2y_in04_int(struct urb *urb)
+  */
+ int usx2y_async_seq04_init(struct usx2ydev *usx2y)
+ {
+-      int     err = 0,
+-              i;
++      int     err = 0, i;
+       usx2y->as04.buffer = kmalloc_array(URBS_ASYNC_SEQ,
+                                          URB_DATA_LEN_ASYNC_SEQ, GFP_KERNEL);
+@@ -263,11 +264,10 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y)
+                               err = -ENOMEM;
+                               break;
+                       }
+-                      usb_fill_bulk_urb(      usx2y->as04.urb[i], usx2y->dev,
+-                                              usb_sndbulkpipe(usx2y->dev, 0x04),
+-                                              usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0,
+-                                              i_usx2y_out04_int, usx2y
+-                              );
++                      usb_fill_bulk_urb(usx2y->as04.urb[i], usx2y->dev,
++                                        usb_sndbulkpipe(usx2y->dev, 0x04),
++                                        usx2y->as04.buffer + URB_DATA_LEN_ASYNC_SEQ*i, 0,
++                                        i_usx2y_out04_int, usx2y);
+                       err = usb_urb_ep_type_check(usx2y->as04.urb[i]);
+                       if (err < 0)
+                               break;
+@@ -277,12 +277,12 @@ int usx2y_async_seq04_init(struct usx2ydev *usx2y)
+ int usx2y_in04_init(struct usx2ydev *usx2y)
+ {
+-      if (! (usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL)))
++      if (!(usx2y->in04_urb = usb_alloc_urb(0, GFP_KERNEL)))
+               return -ENOMEM;
+-      if (! (usx2y->in04_buf = kmalloc(21, GFP_KERNEL)))
++      if (!(usx2y->in04_buf = kmalloc(21, GFP_KERNEL)))
+               return -ENOMEM;
+-       
++
+       init_waitqueue_head(&usx2y->in04_wait_queue);
+       usb_fill_int_urb(usx2y->in04_urb, usx2y->dev, usb_rcvintpipe(usx2y->dev, 0x4),
+                        usx2y->in04_buf, 21,
+@@ -296,6 +296,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y)
+ static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s)
+ {
+       int     i;
++
+       for (i = 0; i < URBS_ASYNC_SEQ; ++i) {
+               usb_kill_urb(s->urb[i]);
+               usb_free_urb(s->urb[i]);
+@@ -304,32 +305,32 @@ static void usx2y_unlinkseq(struct snd_usx2y_async_seq *s)
+       kfree(s->buffer);
+ }
+-
+ static const struct usb_device_id snd_usx2y_usb_id_table[] = {
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     0x1604,
+-              .idProduct =    USB_ID_US428 
++              .idProduct =    USB_ID_US428
+       },
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     0x1604,
+-              .idProduct =    USB_ID_US122 
++              .idProduct =    USB_ID_US122
+       },
+-      {
++      {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     0x1604,
+               .idProduct =    USB_ID_US224
+       },
+       { /* terminator */ }
+ };
++MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table);
+ static int usx2y_create_card(struct usb_device *device,
+                            struct usb_interface *intf,
+                            struct snd_card **cardp)
+ {
+       int             dev;
+-      struct snd_card *       card;
++      struct snd_card *card;
+       int err;
+       for (dev = 0; dev < SNDRV_CARDS; ++dev)
+@@ -350,7 +351,7 @@ static int usx2y_create_card(struct usb_device *device,
+       strcpy(card->driver, "USB "NAME_ALLCAPS"");
+       sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
+       sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
+-              card->shortname, 
++              card->shortname,
+               le16_to_cpu(device->descriptor.idVendor),
+               le16_to_cpu(device->descriptor.idProduct),
+               0,//us428(card)->usbmidi.ifnum,
+@@ -360,14 +361,13 @@ static int usx2y_create_card(struct usb_device *device,
+       return 0;
+ }
+-
+ static int usx2y_usb_probe(struct usb_device *device,
+                          struct usb_interface *intf,
+                          const struct usb_device_id *device_id,
+                          struct snd_card **cardp)
+ {
+       int             err;
+-      struct snd_card *       card;
++      struct snd_card *card;
+       *cardp = NULL;
+       if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
+@@ -409,7 +409,6 @@ static void snd_usx2y_disconnect(struct usb_interface *intf)
+                                usb_get_intfdata(intf));
+ }
+-MODULE_DEVICE_TABLE(usb, snd_usx2y_usb_id_table);
+ static struct usb_driver snd_usx2y_usb_driver = {
+       .name =         "snd-usb-usx2y",
+       .probe =        snd_usx2y_probe,
+@@ -431,12 +430,13 @@ static void snd_usx2y_card_private_free(struct snd_card *card)
+ /*
+  * Frees the device.
+  */
+-static void usx2y_usb_disconnect(struct usb_device *device, void* ptr)
++static void usx2y_usb_disconnect(struct usb_device *device, void *ptr)
+ {
+       if (ptr) {
+               struct snd_card *card = ptr;
+               struct usx2ydev *usx2y = usx2y(card);
+               struct list_head *p;
++
+               usx2y->chip_status = USX2Y_STAT_CHIP_HUP;
+               usx2y_unlinkseq(&usx2y->as04);
+               usb_kill_urb(usx2y->in04_urb);
+@@ -445,7 +445,7 @@ static void usx2y_usb_disconnect(struct usb_device *device, void* ptr)
+               list_for_each(p, &usx2y->midi_list) {
+                       snd_usbmidi_disconnect(p);
+               }
+-              if (usx2y->us428ctls_sharedmem) 
++              if (usx2y->us428ctls_sharedmem)
+                       wake_up(&usx2y->us428ctls_wait_queue_head);
+               snd_card_free(card);
+       }
+diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
+index c330af628bccd..5ad6e3767621c 100644
+--- a/sound/usb/usx2y/usbusx2y.h
++++ b/sound/usb/usx2y/usbusx2y.h
+@@ -3,9 +3,9 @@
+ #define USBUSX2Y_H
+ #include "../usbaudio.h"
+ #include "../midi.h"
+-#include "usbus428ctldefs.h" 
++#include "usbus428ctldefs.h"
+-#define NRURBS                2       
++#define NRURBS                2
+ #define URBS_ASYNC_SEQ 10
+@@ -55,7 +55,7 @@ struct snd_usx2y_substream {
+       struct usx2ydev *usx2y;
+       struct snd_pcm_substream *pcm_substream;
+-      int                     endpoint;               
++      int                     endpoint;
+       unsigned int            maxpacksize;            /* max packet size in bytes */
+       atomic_t                state;
+diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
+index 8033bb7255d5c..f92a9d52ea332 100644
+--- a/sound/usb/usx2y/usbusx2yaudio.c
++++ b/sound/usb/usx2y/usbusx2yaudio.c
+@@ -11,7 +11,7 @@
+  *
+  *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
+  *
+- *   Many codes borrowed from audio.c by 
++ *   Many codes borrowed from audio.c by
+  *        Alan Cox (alan@lxorguk.ukuu.org.uk)
+  *        Thomas Sailer (sailer@ife.ee.ethz.ch)
+  */
+@@ -28,50 +28,51 @@
+ #include "usx2y.h"
+ #include "usbusx2y.h"
+-#define USX2Y_NRPACKS 4                       /* Default value used for nr of packs per urb.
+-                                        1 to 4 have been tested ok on uhci.
+-                                        To use 3 on ohci, you'd need a patch:
+-                                        look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
+-                                        "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
+-                                        .
+-                                        1, 2 and 4 work out of the box on ohci, if I recall correctly.
+-                                        Bigger is safer operation,
+-                                        smaller gives lower latencies.
+-                                      */
+-#define USX2Y_NRPACKS_VARIABLE y      /* If your system works ok with this module's parameter
+-                                         nrpacks set to 1, you might as well comment 
+-                                         this #define out, and thereby produce smaller, faster code.
+-                                         You'd also set USX2Y_NRPACKS to 1 then.
+-                                      */
++/* Default value used for nr of packs per urb.
++ * 1 to 4 have been tested ok on uhci.
++ * To use 3 on ohci, you'd need a patch:
++ * look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
++ * "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
++ *
++ * 1, 2 and 4 work out of the box on ohci, if I recall correctly.
++ * Bigger is safer operation, smaller gives lower latencies.
++ */
++#define USX2Y_NRPACKS 4
++
++/* If your system works ok with this module's parameter
++ * nrpacks set to 1, you might as well comment
++ * this define out, and thereby produce smaller, faster code.
++ * You'd also set USX2Y_NRPACKS to 1 then.
++ */
++#define USX2Y_NRPACKS_VARIABLE 1
+ #ifdef USX2Y_NRPACKS_VARIABLE
+- static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
+- #define  nr_of_packs() nrpacks
+- module_param(nrpacks, int, 0444);
+- MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
++static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
++#define  nr_of_packs() nrpacks
++module_param(nrpacks, int, 0444);
++MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
+ #else
+- #define nr_of_packs() USX2Y_NRPACKS
++#define nr_of_packs() USX2Y_NRPACKS
+ #endif
+-
+ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+ {
+       struct urb      *urb = subs->completed_urb;
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+       unsigned char   *cp;
+-      int             i, len, lens = 0, hwptr_done = subs->hwptr_done;
++      int             i, len, lens = 0, hwptr_done = subs->hwptr_done;
+       struct usx2ydev *usx2y = subs->usx2y;
+       for (i = 0; i < nr_of_packs(); i++) {
+-              cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
++              cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+               if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
+-                      snd_printk(KERN_ERR "active frame status %i. "
+-                                 "Most probably some hardware problem.\n",
++                      snd_printk(KERN_ERR
++                                 "active frame status %i. Most probably some hardware problem.\n",
+                                  urb->iso_frame_desc[i].status);
+                       return urb->iso_frame_desc[i].status;
+               }
+               len = urb->iso_frame_desc[i].actual_length / usx2y->stride;
+-              if (! len) {
++              if (!len) {
+                       snd_printd("0 == len ERROR!\n");
+                       continue;
+               }
+@@ -80,6 +81,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+               if ((hwptr_done + len) > runtime->buffer_size) {
+                       int cnt = runtime->buffer_size - hwptr_done;
+                       int blen = cnt * usx2y->stride;
++
+                       memcpy(runtime->dma_area + hwptr_done * usx2y->stride, cp, blen);
+                       memcpy(runtime->dma_area, cp + blen, len * usx2y->stride - blen);
+               } else {
+@@ -100,6 +102,7 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
+       }
+       return 0;
+ }
++
+ /*
+  * prepare urb for playback data pipe
+  *
+@@ -140,6 +143,7 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
+                        * copy the data to the temp buffer.
+                        */
+                       int len;
++
+                       len = runtime->buffer_size - subs->hwptr;
+                       urb->transfer_buffer = subs->tmpbuf;
+                       memcpy(subs->tmpbuf, runtime->dma_area +
+@@ -183,6 +187,7 @@ static void usx2y_urb_play_retire(struct snd_usx2y_substream *subs, struct urb *
+ static int usx2y_urb_submit(struct snd_usx2y_substream *subs, struct urb *urb, int frame)
+ {
+       int err;
++
+       if (!urb)
+               return -ENODEV;
+       urb->start_frame = (frame + NRURBS * nr_of_packs());  // let hcd do rollover sanity checks
+@@ -243,13 +248,13 @@ static inline int usx2y_usbframe_complete(struct snd_usx2y_substream *capsubs,
+       return 0;
+ }
+-
+ static void usx2y_clients_stop(struct usx2ydev *usx2y)
+ {
+       int s, u;
+       for (s = 0; s < 4; s++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[s];
++
+               if (subs) {
+                       snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
+                       atomic_set(&subs->state, STATE_STOPPED);
+@@ -257,11 +262,13 @@ static void usx2y_clients_stop(struct usx2ydev *usx2y)
+       }
+       for (s = 0; s < 4; s++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[s];
++
+               if (subs) {
+                       if (atomic_read(&subs->state) >= STATE_PRERUNNING)
+                               snd_pcm_stop_xrun(subs->pcm_substream);
+                       for (u = 0; u < NRURBS; u++) {
+                               struct urb *urb = subs->urb[u];
++
+                               if (NULL != urb)
+                                       snd_printdd("%i status=%i start_frame=%i\n",
+                                                   u, urb->status, urb->start_frame);
+@@ -302,6 +309,7 @@ static void i_usx2y_urb_complete(struct urb *urb)
+       {
+               struct snd_usx2y_substream *capsubs = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE],
+                       *playbacksubs = usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
++
+               if (capsubs->completed_urb &&
+                   atomic_read(&capsubs->state) >= STATE_PREPARED &&
+                   (playbacksubs->completed_urb ||
+@@ -316,22 +324,25 @@ static void i_usx2y_urb_complete(struct urb *urb)
+       }
+ }
+-static void usx2y_urbs_set_complete(struct usx2ydev * usx2y,
++static void usx2y_urbs_set_complete(struct usx2ydev *usx2y,
+                                   void (*complete)(struct urb *))
+ {
+       int s, u;
++
+       for (s = 0; s < 4; s++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[s];
++
+               if (NULL != subs)
+                       for (u = 0; u < NRURBS; u++) {
+-                              struct urb * urb = subs->urb[u];
++                              struct urb *urb = subs->urb[u];
++
+                               if (NULL != urb)
+                                       urb->complete = complete;
+                       }
+       }
+ }
+-static void usx2y_subs_startup_finish(struct usx2ydev * usx2y)
++static void usx2y_subs_startup_finish(struct usx2ydev *usx2y)
+ {
+       usx2y_urbs_set_complete(usx2y, i_usx2y_urb_complete);
+       usx2y->prepare_subs = NULL;
+@@ -342,6 +353,7 @@ static void i_usx2y_subs_startup(struct urb *urb)
+       struct snd_usx2y_substream *subs = urb->context;
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
++
+       if (NULL != prepare_subs)
+               if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
+                       usx2y_subs_startup_finish(usx2y);
+@@ -362,7 +374,6 @@ static void usx2y_subs_prepare(struct snd_usx2y_substream *subs)
+       subs->transfer_done = 0;
+ }
+-
+ static void usx2y_urb_release(struct urb **urb, int free_tb)
+ {
+       if (*urb) {
+@@ -373,12 +384,14 @@ static void usx2y_urb_release(struct urb **urb, int free_tb)
+               *urb = NULL;
+       }
+ }
++
+ /*
+  * release a substreams urbs
+  */
+ static void usx2y_urbs_release(struct snd_usx2y_substream *subs)
+ {
+       int i;
++
+       snd_printdd("usx2y_urbs_release() %i\n", subs->endpoint);
+       for (i = 0; i < NRURBS; i++)
+               usx2y_urb_release(subs->urb + i,
+@@ -387,6 +400,7 @@ static void usx2y_urbs_release(struct snd_usx2y_substream *subs)
+       kfree(subs->tmpbuf);
+       subs->tmpbuf = NULL;
+ }
++
+ /*
+  * initialize a substream's urbs
+  */
+@@ -411,6 +425,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
+       /* allocate and initialize data urbs */
+       for (i = 0; i < NRURBS; i++) {
+               struct urb **purb = subs->urb + i;
++
+               if (*purb) {
+                       usb_kill_urb(*purb);
+                       continue;
+@@ -443,6 +458,7 @@ static int usx2y_urbs_allocate(struct snd_usx2y_substream *subs)
+ static void usx2y_subs_startup(struct snd_usx2y_substream *subs)
+ {
+       struct usx2ydev *usx2y = subs->usx2y;
++
+       usx2y->prepare_subs = subs;
+       subs->urb[0]->start_frame = -1;
+       wmb();
+@@ -459,6 +475,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+       subs->completed_urb = NULL;
+       for (i = 0; i < 4; i++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[i];
++
+               if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED)
+                       goto start;
+       }
+@@ -467,8 +484,10 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+       usx2y_subs_startup(subs);
+       for (i = 0; i < NRURBS; i++) {
+               struct urb *urb = subs->urb[i];
++
+               if (usb_pipein(urb->pipe)) {
+                       unsigned long pack;
++
+                       if (0 == i)
+                               atomic_set(&subs->state, STATE_STARTING3);
+                       urb->dev = usx2y->dev;
+@@ -476,9 +495,9 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+                               urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
+                               urb->iso_frame_desc[pack].length = subs->maxpacksize;
+                       }
+-                      urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
++                      urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+                       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+-                              snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
++                              snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+                               err = -EPIPE;
+                               goto cleanup;
+                       } else
+@@ -509,8 +528,10 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
+ static snd_pcm_uframes_t snd_usx2y_pcm_pointer(struct snd_pcm_substream *substream)
+ {
+       struct snd_usx2y_substream *subs = substream->runtime->private_data;
++
+       return subs->hwptr_done;
+ }
++
+ /*
+  * start/stop substream
+  */
+@@ -540,7 +561,6 @@ static int snd_usx2y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+       return 0;
+ }
+-
+ /*
+  * allocate a buffer, setup samplerate
+  *
+@@ -553,8 +573,7 @@ static const struct s_c2
+ {
+       char c1, c2;
+ }
+-      setrate_44100[] =
+-{
++      setrate_44100[] = {
+       { 0x14, 0x08},  // this line sets 44100, well actually a little less
+       { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
+       { 0x18, 0x42},
+@@ -589,8 +608,8 @@ static const struct s_c2
+       { 0x18, 0x7C},
+       { 0x18, 0x7E}
+ };
+-static const struct s_c2 setrate_48000[] =
+-{
++
++static const struct s_c2 setrate_48000[] = {
+       { 0x14, 0x09},  // this line sets 48000, well actually a little less
+       { 0x18, 0x40},  // only tascam / frontier design knows the further lines .......
+       { 0x18, 0x42},
+@@ -625,12 +644,13 @@ static const struct s_c2 setrate_48000[] =
+       { 0x18, 0x7C},
+       { 0x18, 0x7E}
+ };
++
+ #define NOOF_SETRATE_URBS ARRAY_SIZE(setrate_48000)
+ static void i_usx2y_04int(struct urb *urb)
+ {
+       struct usx2ydev *usx2y = urb->context;
+-      
++
+       if (urb->status)
+               snd_printk(KERN_ERR "snd_usx2y_04int() urb->status=%i\n", urb->status);
+       if (0 == --usx2y->us04->len)
+@@ -645,7 +665,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+       const struct s_c2       *ra = rate == 48000 ? setrate_48000 : setrate_44100;
+       if (usx2y->rate != rate) {
+-              us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
++              us = kzalloc(sizeof(*us) + sizeof(struct urb *) * NOOF_SETRATE_URBS, GFP_KERNEL);
+               if (NULL == us) {
+                       err = -ENOMEM;
+                       goto cleanup;
+@@ -661,8 +681,8 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+                               err = -ENOMEM;
+                               goto cleanup;
+                       }
+-                      ((char*)(usbdata + i))[0] = ra[i].c1;
+-                      ((char*)(usbdata + i))[1] = ra[i].c2;
++                      ((char *)(usbdata + i))[0] = ra[i].c1;
++                      ((char *)(usbdata + i))[1] = ra[i].c2;
+                       usb_fill_bulk_urb(us->urb[i], usx2y->dev, usb_sndbulkpipe(usx2y->dev, 4),
+                                         usbdata + i, 2, i_usx2y_04int, usx2y);
+               }
+@@ -681,6 +701,7 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+                       us->submitted = 2*NOOF_SETRATE_URBS;
+                       for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
+                               struct urb *urb = us->urb[i];
++
+                               if (!urb)
+                                       continue;
+                               if (urb->status) {
+@@ -705,7 +726,8 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate)
+ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
+ {
+       int alternate, err;
+-      struct list_head* p;
++      struct list_head *p;
++
+       if (format == SNDRV_PCM_FORMAT_S24_3LE) {
+               alternate = 2;
+               usx2y->stride = 6;
+@@ -718,7 +740,7 @@ static int usx2y_format_set(struct usx2ydev *usx2y, snd_pcm_format_t format)
+       }
+       usb_kill_urb(usx2y->in04_urb);
+       if ((err = usb_set_interface(usx2y->dev, 0, alternate))) {
+-              snd_printk(KERN_ERR "usb_set_interface error \n");
++              snd_printk(KERN_ERR "usb_set_interface error\n");
+               return err;
+       }
+       usx2y->in04_urb->dev = usx2y->dev;
+@@ -778,11 +800,13 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_usx2y_substream *subs = runtime->private_data;
++
+       mutex_lock(&subs->usx2y->pcm_mutex);
+       snd_printdd("snd_usx2y_hw_free(%p)\n", substream);
+       if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
+               struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
++
+               atomic_set(&subs->state, STATE_STOPPED);
+               usx2y_urbs_release(subs);
+               if (!cap_subs->pcm_substream ||
+@@ -794,6 +818,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
+               }
+       } else {
+               struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
++
+               if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+                       atomic_set(&subs->state, STATE_STOPPED);
+                       usx2y_urbs_release(subs);
+@@ -802,6 +827,7 @@ static int snd_usx2y_pcm_hw_free(struct snd_pcm_substream *substream)
+       mutex_unlock(&subs->usx2y->pcm_mutex);
+       return 0;
+ }
++
+ /*
+  * prepare callback
+  *
+@@ -814,12 +840,13 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+       int err = 0;
++
+       snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream);
+       mutex_lock(&usx2y->pcm_mutex);
+       usx2y_subs_prepare(subs);
+-// Start hardware streams
+-// SyncStream first....
++      // Start hardware streams
++      // SyncStream first....
+       if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+               if (usx2y->format != runtime->format)
+                       if ((err = usx2y_format_set(usx2y, runtime->format)) < 0)
+@@ -840,8 +867,7 @@ static int snd_usx2y_pcm_prepare(struct snd_pcm_substream *substream)
+       return err;
+ }
+-static const struct snd_pcm_hardware snd_usx2y_2c =
+-{
++static const struct snd_pcm_hardware snd_usx2y_2c = {
+       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                SNDRV_PCM_INFO_MMAP_VALID |
+@@ -860,8 +886,6 @@ static const struct snd_pcm_hardware snd_usx2y_2c =
+       .fifo_size =              0
+ };
+-
+-
+ static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
+ {
+       struct snd_usx2y_substream      *subs = ((struct snd_usx2y_substream **)
+@@ -878,8 +902,6 @@ static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
+       return 0;
+ }
+-
+-
+ static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+@@ -890,9 +912,7 @@ static int snd_usx2y_pcm_close(struct snd_pcm_substream *substream)
+       return 0;
+ }
+-
+-static const struct snd_pcm_ops snd_usx2y_pcm_ops =
+-{
++static const struct snd_pcm_ops snd_usx2y_pcm_ops = {
+       .open =         snd_usx2y_pcm_open,
+       .close =        snd_usx2y_pcm_close,
+       .hw_params =    snd_usx2y_pcm_hw_params,
+@@ -902,7 +922,6 @@ static const struct snd_pcm_ops snd_usx2y_pcm_ops =
+       .pointer =      snd_usx2y_pcm_pointer,
+ };
+-
+ /*
+  * free a usb stream instance
+  */
+@@ -919,6 +938,7 @@ static void usx2y_audio_stream_free(struct snd_usx2y_substream **usx2y_substream
+ static void snd_usx2y_pcm_private_free(struct snd_pcm *pcm)
+ {
+       struct snd_usx2y_substream **usx2y_stream = pcm->private_data;
++
+       if (usx2y_stream)
+               usx2y_audio_stream_free(usx2y_stream);
+ }
+@@ -983,14 +1003,14 @@ static int usx2y_audio_stream_new(struct snd_card *card, int playback_endpoint,
+ int usx2y_audio_create(struct snd_card *card)
+ {
+       int err = 0;
+-      
++
+       INIT_LIST_HEAD(&usx2y(card)->pcm_list);
+       if (0 > (err = usx2y_audio_stream_new(card, 0xA, 0x8)))
+               return err;
+       if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) == USB_ID_US428)
+-           if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA)))
+-                   return err;
++              if (0 > (err = usx2y_audio_stream_new(card, 0, 0xA)))
++                      return err;
+       if (le16_to_cpu(usx2y(card)->dev->descriptor.idProduct) != USB_ID_US122)
+               err = usx2y_rate_set(usx2y(card), 44100);       // Lets us428 recognize output-volume settings, disturbs us122.
+       return err;
+diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
+index 399470e51c411..b7e15fc3d1b48 100644
+--- a/sound/usb/usx2y/usx2yhwdeppcm.c
++++ b/sound/usb/usx2y/usx2yhwdeppcm.c
+@@ -6,7 +6,7 @@
+  Its usb's unableness to atomically handle power of 2 period sized data chuncs
+  at standard samplerates,
+- what led to this part of the usx2y module: 
++ what led to this part of the usx2y module:
+  It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
+  The pair uses a hardware dependent alsa-device for mmaped pcm transport.
+  Advantage achieved:
+@@ -35,7 +35,7 @@
+  Kernel:
+  - rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio
+    devices can use it.
+-   Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. 
++   Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y.
+ */
+ #include <linux/delay.h>
+@@ -46,15 +46,16 @@
+ #include <sound/hwdep.h>
+-
+ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+ {
+       struct urb      *urb = subs->completed_urb;
+       struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+-      int             i, lens = 0, hwptr_done = subs->hwptr_done;
++      int             i, lens = 0, hwptr_done = subs->hwptr_done;
+       struct usx2ydev *usx2y = subs->usx2y;
++
+       if (0 > usx2y->hwdep_pcm_shm->capture_iso_start) { //FIXME
+               int head = usx2y->hwdep_pcm_shm->captured_iso_head + 1;
++
+               if (head >= ARRAY_SIZE(usx2y->hwdep_pcm_shm->captured_iso))
+                       head = 0;
+               usx2y->hwdep_pcm_shm->capture_iso_start = head;
+@@ -62,7 +63,9 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+       }
+       for (i = 0; i < nr_of_packs(); i++) {
+               if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
+-                      snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
++                      snd_printk(KERN_ERR
++                                 "active frame status %i. Most probably some hardware problem.\n",
++                                 urb->iso_frame_desc[i].status);
+                       return urb->iso_frame_desc[i].status;
+               }
+               lens += urb->iso_frame_desc[i].actual_length / usx2y->stride;
+@@ -80,7 +83,7 @@ static int usx2y_usbpcm_urb_capt_retire(struct snd_usx2y_substream *subs)
+ }
+ static inline int usx2y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
+-                                            struct usx2ydev * usx2y)
++                                            struct usx2ydev *usx2y)
+ {
+       return (runtime->buffer_size * 1000) / usx2y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
+ }
+@@ -133,16 +136,18 @@ static int usx2y_hwdep_urb_play_prepare(struct snd_usx2y_substream *subs,
+       return 0;
+ }
+-
+ static inline void usx2y_usbpcm_urb_capt_iso_advance(struct snd_usx2y_substream *subs,
+                                                    struct urb *urb)
+ {
+       int pack;
++
+       for (pack = 0; pack < nr_of_packs(); ++pack) {
+               struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
++
+               if (NULL != subs) {
+                       struct snd_usx2y_hwdep_pcm_shm *shm = subs->usx2y->hwdep_pcm_shm;
+                       int head = shm->captured_iso_head + 1;
++
+                       if (head >= ARRAY_SIZE(shm->captured_iso))
+                               head = 0;
+                       shm->captured_iso[head].frame = urb->start_frame + pack;
+@@ -189,7 +194,7 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap
+                       return err;
+               }
+       }
+-      
++
+       playbacksubs->completed_urb = NULL;
+       state = atomic_read(&capsubs->state);
+@@ -214,7 +219,6 @@ static inline int usx2y_usbpcm_usbframe_complete(struct snd_usx2y_substream *cap
+       return 0;
+ }
+-
+ static void i_usx2y_usbpcm_urb_complete(struct urb *urb)
+ {
+       struct snd_usx2y_substream *subs = urb->context;
+@@ -249,7 +253,6 @@ static void i_usx2y_usbpcm_urb_complete(struct urb *urb)
+       }
+ }
+-
+ static void usx2y_hwdep_urb_release(struct urb **urb)
+ {
+       usb_kill_urb(*urb);
+@@ -263,12 +266,13 @@ static void usx2y_hwdep_urb_release(struct urb **urb)
+ static void usx2y_usbpcm_urbs_release(struct snd_usx2y_substream *subs)
+ {
+       int i;
++
+       snd_printdd("snd_usx2y_urbs_release() %i\n", subs->endpoint);
+       for (i = 0; i < NRURBS; i++)
+               usx2y_hwdep_urb_release(subs->urb + i);
+ }
+-static void usx2y_usbpcm_subs_startup_finish(struct usx2ydev * usx2y)
++static void usx2y_usbpcm_subs_startup_finish(struct usx2ydev *usx2y)
+ {
+       usx2y_urbs_set_complete(usx2y, i_usx2y_usbpcm_urb_complete);
+       usx2y->prepare_subs = NULL;
+@@ -279,11 +283,13 @@ static void i_usx2y_usbpcm_subs_startup(struct urb *urb)
+       struct snd_usx2y_substream *subs = urb->context;
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *prepare_subs = usx2y->prepare_subs;
++
+       if (NULL != prepare_subs &&
+           urb->start_frame == prepare_subs->urb[0]->start_frame) {
+               atomic_inc(&prepare_subs->state);
+               if (prepare_subs == usx2y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
+                       struct snd_usx2y_substream *cap_subs2 = usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
++
+                       if (cap_subs2 != NULL)
+                               atomic_inc(&cap_subs2->state);
+               }
+@@ -313,6 +319,7 @@ static int usx2y_usbpcm_urbs_allocate(struct snd_usx2y_substream *subs)
+       /* allocate and initialize data urbs */
+       for (i = 0; i < NRURBS; i++) {
+               struct urb **purb = subs->urb + i;
++
+               if (*purb) {
+                       usb_kill_urb(*purb);
+                       continue;
+@@ -346,11 +353,13 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_usx2y_substream *subs = runtime->private_data,
+               *cap_subs2 = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
++
+       mutex_lock(&subs->usx2y->pcm_mutex);
+       snd_printdd("snd_usx2y_usbpcm_hw_free(%p)\n", substream);
+       if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
+               struct snd_usx2y_substream *cap_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
++
+               atomic_set(&subs->state, STATE_STOPPED);
+               usx2y_usbpcm_urbs_release(subs);
+               if (!cap_subs->pcm_substream ||
+@@ -366,6 +375,7 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+               }
+       } else {
+               struct snd_usx2y_substream *playback_subs = subs->usx2y->subs[SNDRV_PCM_STREAM_PLAYBACK];
++
+               if (atomic_read(&playback_subs->state) < STATE_PREPARED) {
+                       atomic_set(&subs->state, STATE_STOPPED);
+                       if (NULL != cap_subs2)
+@@ -381,7 +391,8 @@ static int snd_usx2y_usbpcm_hw_free(struct snd_pcm_substream *substream)
+ static void usx2y_usbpcm_subs_startup(struct snd_usx2y_substream *subs)
+ {
+-      struct usx2ydev * usx2y = subs->usx2y;
++      struct usx2ydev *usx2y = subs->usx2y;
++
+       usx2y->prepare_subs = subs;
+       subs->urb[0]->start_frame = -1;
+       smp_wmb();      // Make sure above modifications are seen by i_usx2y_subs_startup()
+@@ -390,8 +401,7 @@ static void usx2y_usbpcm_subs_startup(struct snd_usx2y_substream *subs)
+ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+ {
+-      int     p, u, err,
+-              stream = subs->pcm_substream->stream;
++      int     p, u, err, stream = subs->pcm_substream->stream;
+       struct usx2ydev *usx2y = subs->usx2y;
+       if (SNDRV_PCM_STREAM_CAPTURE == stream) {
+@@ -410,6 +420,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+       for (p = 0; p < 4; p++) {
+               struct snd_usx2y_substream *subs = usx2y->subs[p];
++
+               if (subs != NULL && atomic_read(&subs->state) >= STATE_PREPARED)
+                       goto start;
+       }
+@@ -419,10 +430,13 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+       for (u = 0; u < NRURBS; u++) {
+               for (p = 0; 3 >= (stream + p); p += 2) {
+                       struct snd_usx2y_substream *subs = usx2y->subs[stream + p];
++
+                       if (subs != NULL) {
+                               struct urb *urb = subs->urb[u];
++
+                               if (usb_pipein(urb->pipe)) {
+                                       unsigned long pack;
++
+                                       if (0 == u)
+                                               atomic_set(&subs->state, STATE_STARTING3);
+                                       urb->dev = usx2y->dev;
+@@ -430,9 +444,9 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+                                               urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
+                                               urb->iso_frame_desc[pack].length = subs->maxpacksize;
+                                       }
+-                                      urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
++                                      urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
+                                       if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
+-                                              snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
++                                              snd_printk(KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
+                                               err = -EPIPE;
+                                               goto cleanup;
+                                       }  else {
+@@ -444,7 +458,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+                               } else {
+                                       atomic_set(&subs->state, STATE_STARTING1);
+                                       break;
+-                              }                       
++                              }
+                       }
+               }
+       }
+@@ -452,11 +466,11 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
+       wait_event(usx2y->prepare_wait_queue, NULL == usx2y->prepare_subs);
+       if (atomic_read(&subs->state) != STATE_PREPARED)
+               err = -EPIPE;
+-              
++
+  cleanup:
+       if (err) {
+               usx2y_subs_startup_finish(usx2y);       // Call it now
+-              usx2y_clients_stop(usx2y);              // something is completely wroong > stop evrything                      
++              usx2y_clients_stop(usx2y);              // something is completely wroong > stop evrything
+       }
+       return err;
+ }
+@@ -473,6 +487,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+       struct usx2ydev *usx2y = subs->usx2y;
+       struct snd_usx2y_substream *capsubs = subs->usx2y->subs[SNDRV_PCM_STREAM_CAPTURE];
+       int err = 0;
++
+       snd_printdd("snd_usx2y_pcm_prepare(%p)\n", substream);
+       if (NULL == usx2y->hwdep_pcm_shm) {
+@@ -485,8 +500,8 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+       mutex_lock(&usx2y->pcm_mutex);
+       usx2y_subs_prepare(subs);
+-// Start hardware streams
+-// SyncStream first....
++      // Start hardware streams
++      // SyncStream first....
+       if (atomic_read(&capsubs->state) < STATE_PREPARED) {
+               if (usx2y->format != runtime->format)
+                       if ((err = usx2y_format_set(usx2y, runtime->format)) < 0)
+@@ -505,15 +520,14 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+               if (atomic_read(&subs->state) < STATE_PREPARED) {
+                       while (usx2y_iso_frames_per_buffer(runtime, usx2y) >
+                              usx2y->hwdep_pcm_shm->captured_iso_frames) {
+-                              snd_printdd("Wait: iso_frames_per_buffer=%i,"
+-                                          "captured_iso_frames=%i\n",
++                              snd_printdd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
+                                           usx2y_iso_frames_per_buffer(runtime, usx2y),
+                                           usx2y->hwdep_pcm_shm->captured_iso_frames);
+                               if (msleep_interruptible(10)) {
+                                       err = -ERESTARTSYS;
+                                       goto up_prepare_mutex;
+                               }
+-                      } 
++                      }
+                       if (0 > (err = usx2y_usbpcm_urbs_start(subs)))
+                               goto up_prepare_mutex;
+               }
+@@ -528,8 +542,7 @@ static int snd_usx2y_usbpcm_prepare(struct snd_pcm_substream *substream)
+       return err;
+ }
+-static const struct snd_pcm_hardware snd_usx2y_4c =
+-{
++static const struct snd_pcm_hardware snd_usx2y_4c = {
+       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                SNDRV_PCM_INFO_MMAP_VALID),
+@@ -547,8 +560,6 @@ static const struct snd_pcm_hardware snd_usx2y_4c =
+       .fifo_size =              0
+ };
+-
+-
+ static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream)
+ {
+       struct snd_usx2y_substream      *subs = ((struct snd_usx2y_substream **)
+@@ -566,7 +577,6 @@ static int snd_usx2y_usbpcm_open(struct snd_pcm_substream *substream)
+       return 0;
+ }
+-
+ static int snd_usx2y_usbpcm_close(struct snd_pcm_substream *substream)
+ {
+       struct snd_pcm_runtime *runtime = substream->runtime;
+@@ -576,9 +586,7 @@ static int snd_usx2y_usbpcm_close(struct snd_pcm_substream *substream)
+       return 0;
+ }
+-
+-static const struct snd_pcm_ops snd_usx2y_usbpcm_ops =
+-{
++static const struct snd_pcm_ops snd_usx2y_usbpcm_ops = {
+       .open =         snd_usx2y_usbpcm_open,
+       .close =        snd_usx2y_usbpcm_close,
+       .hw_params =    snd_usx2y_pcm_hw_params,
+@@ -588,7 +596,6 @@ static const struct snd_pcm_ops snd_usx2y_usbpcm_ops =
+       .pointer =      snd_usx2y_pcm_pointer,
+ };
+-
+ static int usx2y_pcms_busy_check(struct snd_card *card)
+ {
+       struct usx2ydev *dev = usx2y(card);
+@@ -596,6 +603,7 @@ static int usx2y_pcms_busy_check(struct snd_card *card)
+       for (i = 0; i < dev->pcm_devs * 2; i++) {
+               struct snd_usx2y_substream *subs = dev->subs[i];
++
+               if (subs && subs->pcm_substream &&
+                   SUBSTREAM_BUSY(subs->pcm_substream))
+                       return -EBUSY;
+@@ -616,7 +624,6 @@ static int snd_usx2y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
+       return err;
+ }
+-
+ static int snd_usx2y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
+ {
+       struct snd_card *card = hw->card;
+@@ -630,17 +637,14 @@ static int snd_usx2y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
+       return err;
+ }
+-
+ static void snd_usx2y_hwdep_pcm_vm_open(struct vm_area_struct *area)
+ {
+ }
+-
+ static void snd_usx2y_hwdep_pcm_vm_close(struct vm_area_struct *area)
+ {
+ }
+-
+ static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
+ {
+       unsigned long offset;
+@@ -653,15 +657,13 @@ static vm_fault_t snd_usx2y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
+       return 0;
+ }
+-
+ static const struct vm_operations_struct snd_usx2y_hwdep_pcm_vm_ops = {
+       .open = snd_usx2y_hwdep_pcm_vm_open,
+       .close = snd_usx2y_hwdep_pcm_vm_close,
+       .fault = snd_usx2y_hwdep_pcm_vm_fault,
+ };
+-
+-static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
++static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep *hw, struct file *filp, struct vm_area_struct *area)
+ {
+       unsigned long   size = (unsigned long)(area->vm_end - area->vm_start);
+       struct usx2ydev *usx2y = hw->private_data;
+@@ -669,9 +671,9 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st
+       if (!(usx2y->chip_status & USX2Y_STAT_CHIP_INIT))
+               return -EBUSY;
+-      /* if userspace tries to mmap beyond end of our buffer, fail */ 
++      /* if userspace tries to mmap beyond end of our buffer, fail */
+       if (size > PAGE_ALIGN(sizeof(struct snd_usx2y_hwdep_pcm_shm))) {
+-              snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usx2y_hwdep_pcm_shm)); 
++              snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usx2y_hwdep_pcm_shm));
+               return -EINVAL;
+       }
+@@ -684,21 +686,21 @@ static int snd_usx2y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st
+       return 0;
+ }
+-
+ static void snd_usx2y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
+ {
+       struct usx2ydev *usx2y = hwdep->private_data;
++
+       if (NULL != usx2y->hwdep_pcm_shm)
+               free_pages_exact(usx2y->hwdep_pcm_shm, sizeof(struct snd_usx2y_hwdep_pcm_shm));
+ }
+-
+ int usx2y_hwdep_pcm_new(struct snd_card *card)
+ {
+       int err;
+       struct snd_hwdep *hw;
+       struct snd_pcm *pcm;
+       struct usb_device *dev = usx2y(card)->dev;
++
+       if (1 != nr_of_packs())
+               return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch b/queue-5.10/alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch
new file mode 100644 (file)
index 0000000..c7dd1e6
--- /dev/null
@@ -0,0 +1,46 @@
+From b146c74b4c01b457ce96df7d55ac3d4c700ff2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 12:10:35 +0100
+Subject: ALSA: usx2y: Use snd_card_free_when_closed() at disconnection
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit dafb28f02be407e07a6f679e922a626592b481b0 ]
+
+The USB disconnect callback is supposed to be short and not too-long
+waiting.  OTOH, the current code uses snd_card_free() at
+disconnection, but this waits for the close of all used fds, hence it
+can take long.  It eventually blocks the upper layer USB ioctls, which
+may trigger a soft lockup.
+
+An easy workaround is to replace snd_card_free() with
+snd_card_free_when_closed().  This variant returns immediately while
+the release of resources is done asynchronously by the card device
+release at the last close.
+
+Fixes: 230cd5e24853 ("[ALSA] prevent oops & dead keyboard on usb unplugging while the device is be ing used")
+Reported-by: syzbot+73582d08864d8268b6fd@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=73582d08864d8268b6fd
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20241113111042.15058-2-tiwai@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/usx2y/usbusx2y.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
+index 9d5a33c4ff2f3..c567e58ceb4fd 100644
+--- a/sound/usb/usx2y/usbusx2y.c
++++ b/sound/usb/usx2y/usbusx2y.c
+@@ -396,7 +396,7 @@ static void snd_usx2y_disconnect(struct usb_interface *intf)
+       }
+       if (usx2y->us428ctls_sharedmem)
+               wake_up(&usx2y->us428ctls_wait_queue_head);
+-      snd_card_free(card);
++      snd_card_free_when_closed(card);
+ }
+ static int snd_usx2y_probe(struct usb_interface *intf,
+-- 
+2.43.0
+
diff --git a/queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch b/queue-5.10/apparmor-fix-do-simple-duplicate-message-elimination.patch
new file mode 100644 (file)
index 0000000..1a806ee
--- /dev/null
@@ -0,0 +1,35 @@
+From a23ae483e5ee5942b4cef3b39a1e5bfa50b5bc71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 10:03:16 +0800
+Subject: apparmor: fix 'Do simple duplicate message elimination'
+
+From: chao liu <liuzgyid@outlook.com>
+
+[ Upstream commit 9b897132424fe76bf6c61f22f9cf12af7f1d1e6a ]
+
+Multiple profiles shared 'ent->caps', so some logs missed.
+
+Fixes: 0ed3b28ab8bf ("AppArmor: mediation of non file objects")
+Signed-off-by: chao liu <liuzgyid@outlook.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/capability.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
+index deccea8654ad8..1b13fd89d5a9f 100644
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -94,6 +94,8 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
+               return error;
+       } else {
+               aa_put_profile(ent->profile);
++              if (profile != ent->profile)
++                      cap_clear(ent->caps);
+               ent->profile = aa_get_profile(profile);
+               cap_raise(ent->caps, cap);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch b/queue-5.10/arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch
new file mode 100644 (file)
index 0000000..0d9bb82
--- /dev/null
@@ -0,0 +1,56 @@
+From 0eab979807dd498d6142b3d0b0fe27724effaf51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 23:29:16 +0100
+Subject: ARM: dts: cubieboard4: Fix DCDC5 regulator constraints
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit dd36ad71ad65968f97630808bc8d605c929b128e ]
+
+The DCDC5 voltage rail in the X-Powers AXP809 PMIC has a resolution of
+50mV, so the currently enforced limits of 1.475 and 1.525 volts cannot
+be set, when the existing regulator value is beyond this range.
+
+This will lead to the whole regulator driver to give up and fail
+probing, which in turn will hang the system, as essential devices depend
+on the PMIC.
+In this case a bug in U-Boot set the voltage to 1.75V (meant for DCDC4),
+and the AXP driver's attempt to correct this lead to this error:
+==================
+[    4.447653] axp20x-rsb sunxi-rsb-3a3: AXP20X driver loaded
+[    4.450066] vcc-dram: Bringing 1750000uV into 1575000-1575000uV
+[    4.460272] vcc-dram: failed to apply 1575000-1575000uV constraint: -EINVAL
+[    4.474788] axp20x-regulator axp20x-regulator.0: Failed to register dcdc5
+[    4.482276] axp20x-regulator axp20x-regulator.0: probe with driver axp20x-regulator failed with error -22
+==================
+
+Set the limits to values that can be programmed, so any correction will
+be successful.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Fixes: 1e1dea72651b ("ARM: dts: sun9i: cubieboard4: Add AXP809 PMIC device node and regulators")
+Link: https://patch.msgid.link/20241007222916.19013-1-andre.przywara@arm.com
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/sun9i-a80-cubieboard4.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+index 484b93df20cb6..c7a3bf3cc3407 100644
+--- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
++++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
+@@ -280,8 +280,8 @@ reg_dcdc4: dcdc4 {
+                       reg_dcdc5: dcdc5 {
+                               regulator-always-on;
+-                              regulator-min-microvolt = <1425000>;
+-                              regulator-max-microvolt = <1575000>;
++                              regulator-min-microvolt = <1450000>;
++                              regulator-max-microvolt = <1550000>;
+                               regulator-name = "vcc-dram";
+                       };
+-- 
+2.43.0
+
diff --git a/queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch b/queue-5.10/arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch
new file mode 100644 (file)
index 0000000..e72aee7
--- /dev/null
@@ -0,0 +1,50 @@
+From 4a237cd3d0266305ddb1eb8783d90d0535ee8f67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 16:20:00 +0800
+Subject: arm64: dts: mediatek: mt8173-elm-hana: Add vdd-supply to second
+ source trackpad
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit f766fae08f6a2eaeb45d8d2c053724c91526835c ]
+
+The Hana device has a second source option trackpad, but it is missing
+its regulator supply. It only works because the regulator is marked as
+always-on.
+
+Add the regulator supply, but leave out the post-power-on delay. Instead,
+document the post-power-on delay along with the reason for not adding
+it in a comment.
+
+Fixes: 689b937bedde ("arm64: dts: mediatek: add mt8173 elm and hana board")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241018082001.1296963-1-wenst@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+index bdcd35cecad90..fd6230352f4fd 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+@@ -43,6 +43,14 @@ trackpad2: trackpad@2c {
+               interrupts = <117 IRQ_TYPE_LEVEL_LOW>;
+               reg = <0x2c>;
+               hid-descr-addr = <0x0020>;
++              /*
++               * The trackpad needs a post-power-on delay of 100ms,
++               * but at time of writing, the power supply for it on
++               * this board is always on. The delay is therefore not
++               * added to avoid impacting the readiness of the
++               * trackpad.
++               */
++              vdd-supply = <&mt6397_vgp6_reg>;
+               wakeup-source;
+       };
+ };
+-- 
+2.43.0
+
diff --git a/queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch b/queue-5.10/arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch
new file mode 100644 (file)
index 0000000..e0e8442
--- /dev/null
@@ -0,0 +1,41 @@
+From a12eaa3d7f09abc829f0c11c22ffe2b217622b3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2024 08:33:46 +0000
+Subject: arm64: dts: mt8183: krane: Fix the address of eeprom at i2c4
+
+From: Hsin-Te Yuan <yuanhsinte@chromium.org>
+
+[ Upstream commit e9c60c34948662b5d47573490ee538439b29e462 ]
+
+The address of eeprom should be 50.
+
+Fixes: cd894e274b74 ("arm64: dts: mt8183: Add krane-sku176 board")
+Signed-off-by: Hsin-Te Yuan <yuanhsinte@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Link: https://lore.kernel.org/r/20240909-eeprom-v1-1-1ed2bc5064f4@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+index fbc471ccf805f..e61ec0229992e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+@@ -85,9 +85,9 @@ &i2c4 {
+       status = "okay";
+       clock-frequency = <400000>;
+-      eeprom@54 {
++      eeprom@50 {
+               compatible = "atmel,24c32";
+-              reg = <0x54>;
++              reg = <0x50>;
+               pagesize = <32>;
+       };
+ };
+-- 
+2.43.0
+
diff --git a/queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch b/queue-5.10/arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch
new file mode 100644 (file)
index 0000000..79b8cd7
--- /dev/null
@@ -0,0 +1,56 @@
+From 37b7b178802f9ad94ee1ada3ac5c1883fe83679f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 01:18:42 +0900
+Subject: arm64: fix .data.rel.ro size assertion when CONFIG_LTO_CLANG
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 340fd66c856651d8c1d29f392dd26ad674d2db0e ]
+
+Commit be2881824ae9 ("arm64/build: Assert for unwanted sections")
+introduced an assertion to ensure that the .data.rel.ro section does
+not exist.
+
+However, this check does not work when CONFIG_LTO_CLANG is enabled,
+because .data.rel.ro matches the .data.[0-9a-zA-Z_]* pattern in the
+DATA_MAIN macro.
+
+Move the ASSERT() above the RW_DATA() line.
+
+Fixes: be2881824ae9 ("arm64/build: Assert for unwanted sections")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20241106161843.189927-1-masahiroy@kernel.org
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/vmlinux.lds.S | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
+index 71f4b5f24d15f..6922c4b3e974f 100644
+--- a/arch/arm64/kernel/vmlinux.lds.S
++++ b/arch/arm64/kernel/vmlinux.lds.S
+@@ -228,6 +228,9 @@ SECTIONS
+       __initdata_end = .;
+       __init_end = .;
++      .data.rel.ro : { *(.data.rel.ro) }
++      ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
++
+       _data = .;
+       _sdata = .;
+       RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
+@@ -279,9 +282,6 @@ SECTIONS
+               *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
+       }
+       ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
+-
+-      .data.rel.ro : { *(.data.rel.ro) }
+-      ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
+ }
+ #include "image-vars.h"
+-- 
+2.43.0
+
diff --git a/queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch b/queue-5.10/asoc-dt-bindings-mt6359-update-generic-node-name-and.patch
new file mode 100644 (file)
index 0000000..62cc82f
--- /dev/null
@@ -0,0 +1,77 @@
+From 2708266f8ccacba54c90b9a60f3aa189d5d6841b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 15:54:50 +0800
+Subject: ASoC: dt-bindings: mt6359: Update generic node name and dmic-mode
+
+From: Macpaul Lin <macpaul.lin@mediatek.com>
+
+[ Upstream commit 4649cbd97fdae5069e9a71cd7669b62b90e03669 ]
+
+Some fix and updates in the following items:
+1. examples:
+   Update generic node name to 'audio-codec' to comply with the
+   coming change in 'mt6359.dtsi'. This change is necessary to fix the
+   dtbs_check error:
+   pmic: 'mt6359codec' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+2. mediatek,dmic-mode:
+   After inspecting the .dts and .dtsi files using 'mt6359-codec', it was
+   discovered that the definitions of 'two wires' and 'one wire' are
+   inverted compared to the DT schema.
+   For example, the following boards using MT6359 PMIC:
+    - mt8192-asurada.dtsi
+    - mt8195-cherry.dtsi
+   These boards use the same definitions of 'dmic-mode' as other boards
+   using MT6358 PMIC. The meaning of '0' or '1' has been noted as comments
+   in the device trees.
+
+   Upon examining the code in [1] and [2], it was confirmed that the
+   definitions of 'dmic-mode' are consistent between "MT6359 PMIC" and
+   "MT6358 PMIC". Therefore, the DT Schema should be correct as is.
+
+References:
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/codecs/mt6358.c#n1875
+[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/codecs/mt6359.c#L1515
+
+Fixes: 539237d1c609 ("dt-bindings: mediatek: mt6359: add codec document")
+Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
+Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patch.msgid.link/20240930075451.14196-1-macpaul.lin@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/sound/mt6359.yaml | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/sound/mt6359.yaml b/Documentation/devicetree/bindings/sound/mt6359.yaml
+index a54f466f769d4..74330f54d6db4 100644
+--- a/Documentation/devicetree/bindings/sound/mt6359.yaml
++++ b/Documentation/devicetree/bindings/sound/mt6359.yaml
+@@ -23,8 +23,8 @@ properties:
+       Indicates how many data pins are used to transmit two channels of PDM
+       signal. 0 means two wires, 1 means one wire. Default value is 0.
+     enum:
+-      - 0 # one wire
+-      - 1 # two wires
++      - 0 # two wires
++      - 1 # one wire
+   mediatek,mic-type-0:
+     $ref: /schemas/types.yaml#/definitions/uint32
+@@ -53,9 +53,9 @@ additionalProperties: false
+ examples:
+   - |
+-    mt6359codec: mt6359codec {
+-      mediatek,dmic-mode = <0>;
+-      mediatek,mic-type-0 = <2>;
++    mt6359codec: audio-codec {
++        mediatek,dmic-mode = <0>;
++        mediatek,mic-type-0 = <2>;
+     };
+ ...
+-- 
+2.43.0
+
diff --git a/queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch b/queue-5.10/asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch
new file mode 100644 (file)
index 0000000..a8c2019
--- /dev/null
@@ -0,0 +1,275 @@
+From eed7e7dd8def432c060dd1aaa018f71f090b1d0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 18:22:32 +0200
+Subject: ASoC: fsl_micfil: do not define SHIFT/MASK for single bits
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit bd2cffd10d79eb9280cb8f5b7cb441f206c1e6ac ]
+
+No need to have defines for the mask of single bits. Also shift is
+unused. Drop all these unnecessary defines.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://lore.kernel.org/r/20220414162249.3934543-5-s.hauer@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c |  18 +++---
+ sound/soc/fsl/fsl_micfil.h | 125 +++++++++----------------------------
+ 2 files changed, 40 insertions(+), 103 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index fe6d6c87a1c42..13d963a840333 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -172,7 +172,7 @@ static int fsl_micfil_reset(struct device *dev)
+       ret = regmap_update_bits(micfil->regmap,
+                                REG_MICFIL_CTRL1,
+-                               MICFIL_CTRL1_MDIS_MASK,
++                               MICFIL_CTRL1_MDIS,
+                                0);
+       if (ret) {
+               dev_err(dev, "failed to clear MDIS bit %d\n", ret);
+@@ -181,7 +181,7 @@ static int fsl_micfil_reset(struct device *dev)
+       ret = regmap_update_bits(micfil->regmap,
+                                REG_MICFIL_CTRL1,
+-                               MICFIL_CTRL1_SRES_MASK,
++                               MICFIL_CTRL1_SRES,
+                                MICFIL_CTRL1_SRES);
+       if (ret) {
+               dev_err(dev, "failed to reset MICFIL: %d\n", ret);
+@@ -274,7 +274,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
+               /* Enable the module */
+               ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+-                                       MICFIL_CTRL1_PDMIEN_MASK,
++                                       MICFIL_CTRL1_PDMIEN,
+                                        MICFIL_CTRL1_PDMIEN);
+               if (ret) {
+                       dev_err(dev, "failed to enable the module\n");
+@@ -287,7 +287,7 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               /* Disable the module */
+               ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+-                                       MICFIL_CTRL1_PDMIEN_MASK,
++                                       MICFIL_CTRL1_PDMIEN,
+                                        0);
+               if (ret) {
+                       dev_err(dev, "failed to enable the module\n");
+@@ -353,7 +353,7 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
+       /* 1. Disable the module */
+       ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+-                               MICFIL_CTRL1_PDMIEN_MASK, 0);
++                               MICFIL_CTRL1_PDMIEN, 0);
+       if (ret) {
+               dev_err(dev, "failed to disable the module\n");
+               return ret;
+@@ -636,16 +636,16 @@ static irqreturn_t micfil_err_isr(int irq, void *devid)
+       regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg);
+-      if (stat_reg & MICFIL_STAT_BSY_FIL_MASK)
++      if (stat_reg & MICFIL_STAT_BSY_FIL)
+               dev_dbg(&pdev->dev, "isr: Decimation Filter is running\n");
+-      if (stat_reg & MICFIL_STAT_FIR_RDY_MASK)
++      if (stat_reg & MICFIL_STAT_FIR_RDY)
+               dev_dbg(&pdev->dev, "isr: FIR Filter Data ready\n");
+-      if (stat_reg & MICFIL_STAT_LOWFREQF_MASK) {
++      if (stat_reg & MICFIL_STAT_LOWFREQF) {
+               dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
+               regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
+-                                MICFIL_STAT_LOWFREQF_MASK, 1);
++                                MICFIL_STAT_LOWFREQF, 1);
+       }
+       return IRQ_HANDLED;
+diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h
+index bac825c3135a0..11ccc08523b2e 100644
+--- a/sound/soc/fsl/fsl_micfil.h
++++ b/sound/soc/fsl/fsl_micfil.h
+@@ -33,33 +33,17 @@
+ #define REG_MICFIL_VAD0_ZCD           0xA8
+ /* MICFIL Control Register 1 -- REG_MICFILL_CTRL1 0x00 */
+-#define MICFIL_CTRL1_MDIS_SHIFT               31
+-#define MICFIL_CTRL1_MDIS_MASK                BIT(MICFIL_CTRL1_MDIS_SHIFT)
+-#define MICFIL_CTRL1_MDIS             BIT(MICFIL_CTRL1_MDIS_SHIFT)
+-#define MICFIL_CTRL1_DOZEN_SHIFT      30
+-#define MICFIL_CTRL1_DOZEN_MASK               BIT(MICFIL_CTRL1_DOZEN_SHIFT)
+-#define MICFIL_CTRL1_DOZEN            BIT(MICFIL_CTRL1_DOZEN_SHIFT)
+-#define MICFIL_CTRL1_PDMIEN_SHIFT     29
+-#define MICFIL_CTRL1_PDMIEN_MASK      BIT(MICFIL_CTRL1_PDMIEN_SHIFT)
+-#define MICFIL_CTRL1_PDMIEN           BIT(MICFIL_CTRL1_PDMIEN_SHIFT)
+-#define MICFIL_CTRL1_DBG_SHIFT                28
+-#define MICFIL_CTRL1_DBG_MASK         BIT(MICFIL_CTRL1_DBG_SHIFT)
+-#define MICFIL_CTRL1_DBG              BIT(MICFIL_CTRL1_DBG_SHIFT)
+-#define MICFIL_CTRL1_SRES_SHIFT               27
+-#define MICFIL_CTRL1_SRES_MASK                BIT(MICFIL_CTRL1_SRES_SHIFT)
+-#define MICFIL_CTRL1_SRES             BIT(MICFIL_CTRL1_SRES_SHIFT)
+-#define MICFIL_CTRL1_DBGE_SHIFT               26
+-#define MICFIL_CTRL1_DBGE_MASK                BIT(MICFIL_CTRL1_DBGE_SHIFT)
+-#define MICFIL_CTRL1_DBGE             BIT(MICFIL_CTRL1_DBGE_SHIFT)
++#define MICFIL_CTRL1_MDIS             BIT(31)
++#define MICFIL_CTRL1_DOZEN            BIT(30)
++#define MICFIL_CTRL1_PDMIEN           BIT(29)
++#define MICFIL_CTRL1_DBG              BIT(28)
++#define MICFIL_CTRL1_SRES             BIT(27)
++#define MICFIL_CTRL1_DBGE             BIT(26)
+ #define MICFIL_CTRL1_DISEL_SHIFT      24
+ #define MICFIL_CTRL1_DISEL_WIDTH      2
+ #define MICFIL_CTRL1_DISEL_MASK               ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \
+                                        << MICFIL_CTRL1_DISEL_SHIFT)
+-#define MICFIL_CTRL1_DISEL(v)         (((v) << MICFIL_CTRL1_DISEL_SHIFT) \
+-                                       & MICFIL_CTRL1_DISEL_MASK)
+-#define MICFIL_CTRL1_ERREN_SHIFT      23
+-#define MICFIL_CTRL1_ERREN_MASK               BIT(MICFIL_CTRL1_ERREN_SHIFT)
+-#define MICFIL_CTRL1_ERREN            BIT(MICFIL_CTRL1_ERREN_SHIFT)
++#define MICFIL_CTRL1_ERREN            BIT(23)
+ #define MICFIL_CTRL1_CHEN_SHIFT               0
+ #define MICFIL_CTRL1_CHEN_WIDTH               8
+ #define MICFIL_CTRL1_CHEN_MASK(x)     (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT)
+@@ -91,15 +75,9 @@
+                                        & MICFIL_CTRL2_CLKDIV_MASK)
+ /* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */
+-#define MICFIL_STAT_BSY_FIL_SHIFT     31
+-#define MICFIL_STAT_BSY_FIL_MASK      BIT(MICFIL_STAT_BSY_FIL_SHIFT)
+-#define MICFIL_STAT_BSY_FIL           BIT(MICFIL_STAT_BSY_FIL_SHIFT)
+-#define MICFIL_STAT_FIR_RDY_SHIFT     30
+-#define MICFIL_STAT_FIR_RDY_MASK      BIT(MICFIL_STAT_FIR_RDY_SHIFT)
+-#define MICFIL_STAT_FIR_RDY           BIT(MICFIL_STAT_FIR_RDY_SHIFT)
+-#define MICFIL_STAT_LOWFREQF_SHIFT    29
+-#define MICFIL_STAT_LOWFREQF_MASK     BIT(MICFIL_STAT_LOWFREQF_SHIFT)
+-#define MICFIL_STAT_LOWFREQF          BIT(MICFIL_STAT_LOWFREQF_SHIFT)
++#define MICFIL_STAT_BSY_FIL           BIT(31)
++#define MICFIL_STAT_FIR_RDY           BIT(30)
++#define MICFIL_STAT_LOWFREQF          BIT(29)
+ #define MICFIL_STAT_CHXF_SHIFT(v)     (v)
+ #define MICFIL_STAT_CHXF_MASK(v)      BIT(MICFIL_STAT_CHXF_SHIFT(v))
+ #define MICFIL_STAT_CHXF(v)           BIT(MICFIL_STAT_CHXF_SHIFT(v))
+@@ -137,32 +115,16 @@
+                                        << MICFIL_VAD0_CTRL1_INITT_SHIFT)
+ #define MICFIL_VAD0_CTRL1_INITT(v)    (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \
+                                        & MICFIL_VAD0_CTRL1_INITT_MASK)
+-#define MICFIL_VAD0_CTRL1_ST10_SHIFT  4
+-#define MICFIL_VAD0_CTRL1_ST10_MASK   BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT)
+-#define MICFIL_VAD0_CTRL1_ST10                BIT(MICFIL_VAD0_CTRL1_ST10_SHIFT)
+-#define MICFIL_VAD0_CTRL1_ERIE_SHIFT  3
+-#define MICFIL_VAD0_CTRL1_ERIE_MASK   BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT)
+-#define MICFIL_VAD0_CTRL1_ERIE                BIT(MICFIL_VAD0_CTRL1_ERIE_SHIFT)
+-#define MICFIL_VAD0_CTRL1_IE_SHIFT    2
+-#define MICFIL_VAD0_CTRL1_IE_MASK     BIT(MICFIL_VAD0_CTRL1_IE_SHIFT)
+-#define MICFIL_VAD0_CTRL1_IE          BIT(MICFIL_VAD0_CTRL1_IE_SHIFT)
+-#define MICFIL_VAD0_CTRL1_RST_SHIFT   1
+-#define MICFIL_VAD0_CTRL1_RST_MASK    BIT(MICFIL_VAD0_CTRL1_RST_SHIFT)
+-#define MICFIL_VAD0_CTRL1_RST         BIT(MICFIL_VAD0_CTRL1_RST_SHIFT)
+-#define MICFIL_VAD0_CTRL1_EN_SHIFT    0
+-#define MICFIL_VAD0_CTRL1_EN_MASK     BIT(MICFIL_VAD0_CTRL1_EN_SHIFT)
+-#define MICFIL_VAD0_CTRL1_EN          BIT(MICFIL_VAD0_CTRL1_EN_SHIFT)
++#define MICFIL_VAD0_CTRL1_ST10                BIT(4)
++#define MICFIL_VAD0_CTRL1_ERIE                BIT(3)
++#define MICFIL_VAD0_CTRL1_IE          BIT(2)
++#define MICFIL_VAD0_CTRL1_RST         BIT(1)
++#define MICFIL_VAD0_CTRL1_EN          BIT(0)
+ /* MICFIL HWVAD0 Control 2 Register -- REG_MICFIL_VAD0_CTRL2*/
+-#define MICFIL_VAD0_CTRL2_FRENDIS_SHIFT       31
+-#define MICFIL_VAD0_CTRL2_FRENDIS_MASK        BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT)
+-#define MICFIL_VAD0_CTRL2_FRENDIS     BIT(MICFIL_VAD0_CTRL2_FRENDIS_SHIFT)
+-#define MICFIL_VAD0_CTRL2_PREFEN_SHIFT        30
+-#define MICFIL_VAD0_CTRL2_PREFEN_MASK BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT)
+-#define MICFIL_VAD0_CTRL2_PREFEN      BIT(MICFIL_VAD0_CTRL2_PREFEN_SHIFT)
+-#define MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT       28
+-#define MICFIL_VAD0_CTRL2_FOUTDIS_MASK        BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT)
+-#define MICFIL_VAD0_CTRL2_FOUTDIS     BIT(MICFIL_VAD0_CTRL2_FOUTDIS_SHIFT)
++#define MICFIL_VAD0_CTRL2_FRENDIS     BIT(31)
++#define MICFIL_VAD0_CTRL2_PREFEN      BIT(30)
++#define MICFIL_VAD0_CTRL2_FOUTDIS     BIT(28)
+ #define MICFIL_VAD0_CTRL2_FRAMET_SHIFT        16
+ #define MICFIL_VAD0_CTRL2_FRAMET_WIDTH        6
+ #define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \
+@@ -183,12 +145,8 @@
+                                        & MICFIL_VAD0_CTRL2_HPF_MASK)
+ /* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */
+-#define MICFIL_VAD0_SCONFIG_SFILEN_SHIFT      31
+-#define MICFIL_VAD0_SCONFIG_SFILEN_MASK               BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT)
+-#define MICFIL_VAD0_SCONFIG_SFILEN            BIT(MICFIL_VAD0_SCONFIG_SFILEN_SHIFT)
+-#define MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT      30
+-#define MICFIL_VAD0_SCONFIG_SMAXEN_MASK               BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT)
+-#define MICFIL_VAD0_SCONFIG_SMAXEN            BIT(MICFIL_VAD0_SCONFIG_SMAXEN_SHIFT)
++#define MICFIL_VAD0_SCONFIG_SFILEN            BIT(31)
++#define MICFIL_VAD0_SCONFIG_SMAXEN            BIT(30)
+ #define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT               0
+ #define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH               4
+ #define MICFIL_VAD0_SCONFIG_SGAIN_MASK                ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \
+@@ -197,17 +155,10 @@
+                                                & MICFIL_VAD0_SCONFIG_SGAIN_MASK)
+ /* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */
+-#define MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT     31
+-#define MICFIL_VAD0_NCONFIG_NFILAUT_MASK      BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NFILAUT           BIT(MICFIL_VAD0_NCONFIG_NFILAUT_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NMINEN_SHIFT      30
+-#define MICFIL_VAD0_NCONFIG_NMINEN_MASK               BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NMINEN            BIT(MICFIL_VAD0_NCONFIG_NMINEN_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NDECEN_SHIFT      29
+-#define MICFIL_VAD0_NCONFIG_NDECEN_MASK               BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NDECEN            BIT(MICFIL_VAD0_NCONFIG_NDECEN_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NOREN_SHIFT               28
+-#define MICFIL_VAD0_NCONFIG_NOREN             BIT(MICFIL_VAD0_NCONFIG_NOREN_SHIFT)
++#define MICFIL_VAD0_NCONFIG_NFILAUT           BIT(31)
++#define MICFIL_VAD0_NCONFIG_NMINEN            BIT(30)
++#define MICFIL_VAD0_NCONFIG_NDECEN            BIT(29)
++#define MICFIL_VAD0_NCONFIG_NOREN             BIT(28)
+ #define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT     8
+ #define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH     5
+ #define MICFIL_VAD0_NCONFIG_NFILADJ_MASK      ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \
+@@ -234,29 +185,15 @@
+                                        << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)
+ #define MICFIL_VAD0_ZCD_ZCDADJ(v)     (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\
+                                        & MICFIL_VAD0_ZCD_ZCDADJ_MASK)
+-#define MICFIL_VAD0_ZCD_ZCDAND_SHIFT  4
+-#define MICFIL_VAD0_ZCD_ZCDAND_MASK   BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDAND                BIT(MICFIL_VAD0_ZCD_ZCDAND_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDAUT_SHIFT  2
+-#define MICFIL_VAD0_ZCD_ZCDAUT_MASK   BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDAUT                BIT(MICFIL_VAD0_ZCD_ZCDAUT_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDEN_SHIFT   0
+-#define MICFIL_VAD0_ZCD_ZCDEN_MASK    BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDEN         BIT(MICFIL_VAD0_ZCD_ZCDEN_SHIFT)
++#define MICFIL_VAD0_ZCD_ZCDAND                BIT(4)
++#define MICFIL_VAD0_ZCD_ZCDAUT                BIT(2)
++#define MICFIL_VAD0_ZCD_ZCDEN         BIT(0)
+ /* MICFIL HWVAD0 Status Register - REG_MICFIL_VAD0_STAT */
+-#define MICFIL_VAD0_STAT_INITF_SHIFT  31
+-#define MICFIL_VAD0_STAT_INITF_MASK   BIT(MICFIL_VAD0_STAT_INITF_SHIFT)
+-#define MICFIL_VAD0_STAT_INITF                BIT(MICFIL_VAD0_STAT_INITF_SHIFT)
+-#define MICFIL_VAD0_STAT_INSATF_SHIFT 16
+-#define MICFIL_VAD0_STAT_INSATF_MASK  BIT(MICFIL_VAD0_STAT_INSATF_SHIFT)
+-#define MICFIL_VAD0_STAT_INSATF               BIT(MICFIL_VAD0_STAT_INSATF_SHIFT)
+-#define MICFIL_VAD0_STAT_EF_SHIFT     15
+-#define MICFIL_VAD0_STAT_EF_MASK      BIT(MICFIL_VAD0_STAT_EF_SHIFT)
+-#define MICFIL_VAD0_STAT_EF           BIT(MICFIL_VAD0_STAT_EF_SHIFT)
+-#define MICFIL_VAD0_STAT_IF_SHIFT     0
+-#define MICFIL_VAD0_STAT_IF_MASK      BIT(MICFIL_VAD0_STAT_IF_SHIFT)
+-#define MICFIL_VAD0_STAT_IF           BIT(MICFIL_VAD0_STAT_IF_SHIFT)
++#define MICFIL_VAD0_STAT_INITF                BIT(31)
++#define MICFIL_VAD0_STAT_INSATF               BIT(16)
++#define MICFIL_VAD0_STAT_EF           BIT(15)
++#define MICFIL_VAD0_STAT_IF           BIT(0)
+ /* MICFIL Output Control Register */
+ #define MICFIL_OUTGAIN_CHX_SHIFT(v)   (4 * (v))
+-- 
+2.43.0
+
diff --git a/queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch b/queue-5.10/asoc-fsl_micfil-drop-unnecessary-register-read.patch
new file mode 100644 (file)
index 0000000..a78763c
--- /dev/null
@@ -0,0 +1,37 @@
+From b5802445b960a6ebba764b39ab30f72e30934fbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 18:22:29 +0200
+Subject: ASoC: fsl_micfil: Drop unnecessary register read
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit c808e277bcdfce37aed80a443be305ac1aec1623 ]
+
+in get_pdm_clk() REG_MICFIL_CTRL2 is read twice. Drop second read.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://lore.kernel.org/r/20220414162249.3934543-2-s.hauer@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 826829e3ff7a2..fe6d6c87a1c42 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -117,8 +117,6 @@ static inline int get_pdm_clk(struct fsl_micfil *micfil,
+       regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+       osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK)
+                   >> MICFIL_CTRL2_CICOSR_SHIFT);
+-
+-      regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+       qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK;
+       switch (qsel) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch b/queue-5.10/asoc-fsl_micfil-fix-regmap_write_bits-usage.patch
new file mode 100644 (file)
index 0000000..02c4b57
--- /dev/null
@@ -0,0 +1,47 @@
+From 769e417c9a6314ae8e83522da2349c00777f233d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Sep 2024 16:00:29 +0800
+Subject: ASoC: fsl_micfil: fix regmap_write_bits usage
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 06df673d20230afb0e383e39235a4fa8b9a62464 ]
+
+The last parameter 1 means BIT(0), which should be the
+correct BIT(X).
+
+Fixes: 47a70e6fc9a8 ("ASoC: Add MICFIL SoC Digital Audio Interface driver.")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Link: https://patch.msgid.link/1727424031-19551-2-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 20215303fa34b..9c781d874c309 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -610,7 +610,7 @@ static irqreturn_t micfil_isr(int irq, void *devid)
+                       regmap_write_bits(micfil->regmap,
+                                         REG_MICFIL_STAT,
+                                         MICFIL_STAT_CHXF(i),
+-                                        1);
++                                        MICFIL_STAT_CHXF(i));
+       }
+       for (i = 0; i < MICFIL_FIFO_NUM; i++) {
+@@ -645,7 +645,7 @@ static irqreturn_t micfil_err_isr(int irq, void *devid)
+       if (stat_reg & MICFIL_STAT_LOWFREQF) {
+               dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n");
+               regmap_write_bits(micfil->regmap, REG_MICFIL_STAT,
+-                                MICFIL_STAT_LOWFREQF, 1);
++                                MICFIL_STAT_LOWFREQF, MICFIL_STAT_LOWFREQF);
+       }
+       return IRQ_HANDLED;
+-- 
+2.43.0
+
diff --git a/queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch b/queue-5.10/asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch
new file mode 100644 (file)
index 0000000..9b8d58d
--- /dev/null
@@ -0,0 +1,382 @@
+From c3762b3026edcd296e43f04c2a53f11857b03097 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 18:22:33 +0200
+Subject: ASoC: fsl_micfil: use GENMASK to define register bit fields
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit 17f2142bae4b6f2e27f19ce57d79fc42ba5ef659 ]
+
+Use GENMASK along with FIELD_PREP and FIELD_GET to access bitfields in
+registers to straighten register access and to drop a lot of defines.
+
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://lore.kernel.org/r/20220414162249.3934543-6-s.hauer@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 06df673d2023 ("ASoC: fsl_micfil: fix regmap_write_bits usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_micfil.c |  52 ++++++-------
+ sound/soc/fsl/fsl_micfil.h | 147 ++++++++-----------------------------
+ 2 files changed, 58 insertions(+), 141 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 13d963a840333..20215303fa34b 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright 2018 NXP
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+@@ -115,23 +116,22 @@ static inline int get_pdm_clk(struct fsl_micfil *micfil,
+       int bclk;
+       regmap_read(micfil->regmap, REG_MICFIL_CTRL2, &ctrl2_reg);
+-      osr = 16 - ((ctrl2_reg & MICFIL_CTRL2_CICOSR_MASK)
+-                  >> MICFIL_CTRL2_CICOSR_SHIFT);
+-      qsel = ctrl2_reg & MICFIL_CTRL2_QSEL_MASK;
++      osr = 16 - FIELD_GET(MICFIL_CTRL2_CICOSR, ctrl2_reg);
++      qsel = FIELD_GET(MICFIL_CTRL2_QSEL, ctrl2_reg);
+       switch (qsel) {
+-      case MICFIL_HIGH_QUALITY:
++      case MICFIL_QSEL_HIGH_QUALITY:
+               bclk = rate * 8 * osr / 2; /* kfactor = 0.5 */
+               break;
+-      case MICFIL_MEDIUM_QUALITY:
+-      case MICFIL_VLOW0_QUALITY:
++      case MICFIL_QSEL_MEDIUM_QUALITY:
++      case MICFIL_QSEL_VLOW0_QUALITY:
+               bclk = rate * 4 * osr * 1; /* kfactor = 1 */
+               break;
+-      case MICFIL_LOW_QUALITY:
+-      case MICFIL_VLOW1_QUALITY:
++      case MICFIL_QSEL_LOW_QUALITY:
++      case MICFIL_QSEL_VLOW1_QUALITY:
+               bclk = rate * 2 * osr * 2; /* kfactor = 2 */
+               break;
+-      case MICFIL_VLOW2_QUALITY:
++      case MICFIL_QSEL_VLOW2_QUALITY:
+               bclk = rate * osr * 4; /* kfactor = 4 */
+               break;
+       default:
+@@ -265,8 +265,8 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
+                * 11 - reserved
+                */
+               ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+-                                       MICFIL_CTRL1_DISEL_MASK,
+-                                       (1 << MICFIL_CTRL1_DISEL_SHIFT));
++                              MICFIL_CTRL1_DISEL,
++                              FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DMA));
+               if (ret) {
+                       dev_err(dev, "failed to update DISEL bits\n");
+                       return ret;
+@@ -295,8 +295,8 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
+               }
+               ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL1,
+-                                       MICFIL_CTRL1_DISEL_MASK,
+-                                       (0 << MICFIL_CTRL1_DISEL_SHIFT));
++                              MICFIL_CTRL1_DISEL,
++                              FIELD_PREP(MICFIL_CTRL1_DISEL, MICFIL_CTRL1_DISEL_DISABLE));
+               if (ret) {
+                       dev_err(dev, "failed to update DISEL bits\n");
+                       return ret;
+@@ -321,8 +321,8 @@ static int fsl_set_clock_params(struct device *dev, unsigned int rate)
+       /* set CICOSR */
+       ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+-                               MICFIL_CTRL2_CICOSR_MASK,
+-                               MICFIL_CTRL2_OSR_DEFAULT);
++                               MICFIL_CTRL2_CICOSR,
++                               FIELD_PREP(MICFIL_CTRL2_CICOSR, MICFIL_CTRL2_CICOSR_DEFAULT));
+       if (ret)
+               dev_err(dev, "failed to set CICOSR in reg 0x%X\n",
+                       REG_MICFIL_CTRL2);
+@@ -333,7 +333,8 @@ static int fsl_set_clock_params(struct device *dev, unsigned int rate)
+               ret = -EINVAL;
+       ret |= regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+-                               MICFIL_CTRL2_CLKDIV_MASK, clk_div);
++                               MICFIL_CTRL2_CLKDIV,
++                               FIELD_PREP(MICFIL_CTRL2_CLKDIV, clk_div));
+       if (ret)
+               dev_err(dev, "failed to set CLKDIV in reg 0x%X\n",
+                       REG_MICFIL_CTRL2);
+@@ -409,13 +410,13 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
+ {
+       struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
+       struct device *dev = cpu_dai->dev;
+-      unsigned int val;
+       int ret;
+       int i;
+       /* set qsel to medium */
+       ret = regmap_update_bits(micfil->regmap, REG_MICFIL_CTRL2,
+-                               MICFIL_CTRL2_QSEL_MASK, MICFIL_MEDIUM_QUALITY);
++                      MICFIL_CTRL2_QSEL,
++                      FIELD_PREP(MICFIL_CTRL2_QSEL, MICFIL_QSEL_MEDIUM_QUALITY));
+       if (ret) {
+               dev_err(dev, "failed to set quality mode bits, reg 0x%X\n",
+                       REG_MICFIL_CTRL2);
+@@ -431,10 +432,9 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
+                                 &micfil->dma_params_rx);
+       /* FIFO Watermark Control - FIFOWMK*/
+-      val = MICFIL_FIFO_CTRL_FIFOWMK(micfil->soc->fifo_depth) - 1;
+       ret = regmap_update_bits(micfil->regmap, REG_MICFIL_FIFO_CTRL,
+-                               MICFIL_FIFO_CTRL_FIFOWMK_MASK,
+-                               val);
++                      MICFIL_FIFO_CTRL_FIFOWMK,
++                      FIELD_PREP(MICFIL_FIFO_CTRL_FIFOWMK, micfil->soc->fifo_depth - 1));
+       if (ret) {
+               dev_err(dev, "failed to set FIFOWMK\n");
+               return ret;
+@@ -596,11 +596,11 @@ static irqreturn_t micfil_isr(int irq, void *devid)
+       regmap_read(micfil->regmap, REG_MICFIL_CTRL1, &ctrl1_reg);
+       regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg);
+-      dma_enabled = MICFIL_DMA_ENABLED(ctrl1_reg);
++      dma_enabled = FIELD_GET(MICFIL_CTRL1_DISEL, ctrl1_reg) == MICFIL_CTRL1_DISEL_DMA;
+       /* Channel 0-7 Output Data Flags */
+       for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) {
+-              if (stat_reg & MICFIL_STAT_CHXF_MASK(i))
++              if (stat_reg & MICFIL_STAT_CHXF(i))
+                       dev_dbg(&pdev->dev,
+                               "Data available in Data Channel %d\n", i);
+               /* if DMA is not enabled, field must be written with 1
+@@ -609,17 +609,17 @@ static irqreturn_t micfil_isr(int irq, void *devid)
+               if (!dma_enabled)
+                       regmap_write_bits(micfil->regmap,
+                                         REG_MICFIL_STAT,
+-                                        MICFIL_STAT_CHXF_MASK(i),
++                                        MICFIL_STAT_CHXF(i),
+                                         1);
+       }
+       for (i = 0; i < MICFIL_FIFO_NUM; i++) {
+-              if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER_MASK(i))
++              if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_OVER(i))
+                       dev_dbg(&pdev->dev,
+                               "FIFO Overflow Exception flag for channel %d\n",
+                               i);
+-              if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(i))
++              if (fifo_stat_reg & MICFIL_FIFO_STAT_FIFOX_UNDER(i))
+                       dev_dbg(&pdev->dev,
+                               "FIFO Underflow Exception flag for channel %d\n",
+                               i);
+diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h
+index 11ccc08523b2e..5cecae2519795 100644
+--- a/sound/soc/fsl/fsl_micfil.h
++++ b/sound/soc/fsl/fsl_micfil.h
+@@ -39,82 +39,45 @@
+ #define MICFIL_CTRL1_DBG              BIT(28)
+ #define MICFIL_CTRL1_SRES             BIT(27)
+ #define MICFIL_CTRL1_DBGE             BIT(26)
+-#define MICFIL_CTRL1_DISEL_SHIFT      24
+-#define MICFIL_CTRL1_DISEL_WIDTH      2
+-#define MICFIL_CTRL1_DISEL_MASK               ((BIT(MICFIL_CTRL1_DISEL_WIDTH) - 1) \
+-                                       << MICFIL_CTRL1_DISEL_SHIFT)
++
++#define MICFIL_CTRL1_DISEL_DISABLE    0
++#define MICFIL_CTRL1_DISEL_DMA                1
++#define MICFIL_CTRL1_DISEL_IRQ                2
++#define MICFIL_CTRL1_DISEL            GENMASK(25, 24)
+ #define MICFIL_CTRL1_ERREN            BIT(23)
+-#define MICFIL_CTRL1_CHEN_SHIFT               0
+-#define MICFIL_CTRL1_CHEN_WIDTH               8
+-#define MICFIL_CTRL1_CHEN_MASK(x)     (BIT(x) << MICFIL_CTRL1_CHEN_SHIFT)
+-#define MICFIL_CTRL1_CHEN(x)          (MICFIL_CTRL1_CHEN_MASK(x))
++#define MICFIL_CTRL1_CHEN(ch)         BIT(ch)
+ /* MICFIL Control Register 2 -- REG_MICFILL_CTRL2 0x04 */
+ #define MICFIL_CTRL2_QSEL_SHIFT               25
+-#define MICFIL_CTRL2_QSEL_WIDTH               3
+-#define MICFIL_CTRL2_QSEL_MASK                ((BIT(MICFIL_CTRL2_QSEL_WIDTH) - 1) \
+-                                       << MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_HIGH_QUALITY           BIT(MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_MEDIUM_QUALITY         (0 << MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_LOW_QUALITY            (7 << MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_VLOW0_QUALITY          (6 << MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_VLOW1_QUALITY          (5 << MICFIL_CTRL2_QSEL_SHIFT)
+-#define MICFIL_VLOW2_QUALITY          (4 << MICFIL_CTRL2_QSEL_SHIFT)
+-
+-#define MICFIL_CTRL2_CICOSR_SHIFT     16
+-#define MICFIL_CTRL2_CICOSR_WIDTH     4
+-#define MICFIL_CTRL2_CICOSR_MASK      ((BIT(MICFIL_CTRL2_CICOSR_WIDTH) - 1) \
+-                                       << MICFIL_CTRL2_CICOSR_SHIFT)
+-#define MICFIL_CTRL2_CICOSR(v)                (((v) << MICFIL_CTRL2_CICOSR_SHIFT) \
+-                                       & MICFIL_CTRL2_CICOSR_MASK)
+-#define MICFIL_CTRL2_CLKDIV_SHIFT     0
+-#define MICFIL_CTRL2_CLKDIV_WIDTH     8
+-#define MICFIL_CTRL2_CLKDIV_MASK      ((BIT(MICFIL_CTRL2_CLKDIV_WIDTH) - 1) \
+-                                       << MICFIL_CTRL2_CLKDIV_SHIFT)
+-#define MICFIL_CTRL2_CLKDIV(v)                (((v) << MICFIL_CTRL2_CLKDIV_SHIFT) \
+-                                       & MICFIL_CTRL2_CLKDIV_MASK)
++#define MICFIL_CTRL2_QSEL             GENMASK(27, 25)
++#define MICFIL_QSEL_MEDIUM_QUALITY    0
++#define MICFIL_QSEL_HIGH_QUALITY      1
++#define MICFIL_QSEL_LOW_QUALITY               7
++#define MICFIL_QSEL_VLOW0_QUALITY     6
++#define MICFIL_QSEL_VLOW1_QUALITY     5
++#define MICFIL_QSEL_VLOW2_QUALITY     4
++
++#define MICFIL_CTRL2_CICOSR           GENMASK(19, 16)
++#define MICFIL_CTRL2_CICOSR_DEFAULT   0
++#define MICFIL_CTRL2_CLKDIV           GENMASK(7, 0)
+ /* MICFIL Status Register -- REG_MICFIL_STAT 0x08 */
+ #define MICFIL_STAT_BSY_FIL           BIT(31)
+ #define MICFIL_STAT_FIR_RDY           BIT(30)
+ #define MICFIL_STAT_LOWFREQF          BIT(29)
+-#define MICFIL_STAT_CHXF_SHIFT(v)     (v)
+-#define MICFIL_STAT_CHXF_MASK(v)      BIT(MICFIL_STAT_CHXF_SHIFT(v))
+-#define MICFIL_STAT_CHXF(v)           BIT(MICFIL_STAT_CHXF_SHIFT(v))
++#define MICFIL_STAT_CHXF(ch)          BIT(ch)
+ /* MICFIL FIFO Control Register -- REG_MICFIL_FIFO_CTRL 0x10 */
+-#define MICFIL_FIFO_CTRL_FIFOWMK_SHIFT        0
+-#define MICFIL_FIFO_CTRL_FIFOWMK_WIDTH        3
+-#define MICFIL_FIFO_CTRL_FIFOWMK_MASK ((BIT(MICFIL_FIFO_CTRL_FIFOWMK_WIDTH) - 1) \
+-                                       << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT)
+-#define MICFIL_FIFO_CTRL_FIFOWMK(v)   (((v) << MICFIL_FIFO_CTRL_FIFOWMK_SHIFT) \
+-                                       & MICFIL_FIFO_CTRL_FIFOWMK_MASK)
++#define MICFIL_FIFO_CTRL_FIFOWMK      GENMASK(2, 0)
+ /* MICFIL FIFO Status Register -- REG_MICFIL_FIFO_STAT 0x14 */
+-#define MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v)  (v)
+-#define MICFIL_FIFO_STAT_FIFOX_OVER_MASK(v)   BIT(MICFIL_FIFO_STAT_FIFOX_OVER_SHIFT(v))
+-#define MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v) ((v) + 8)
+-#define MICFIL_FIFO_STAT_FIFOX_UNDER_MASK(v)  BIT(MICFIL_FIFO_STAT_FIFOX_UNDER_SHIFT(v))
++#define MICFIL_FIFO_STAT_FIFOX_OVER(ch)       BIT(ch)
++#define MICFIL_FIFO_STAT_FIFOX_UNDER(ch)      BIT((ch) + 8)
+ /* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/
+-#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT 24
+-#define MICFIL_VAD0_CTRL1_CHSEL_WIDTH 3
+-#define MICFIL_VAD0_CTRL1_CHSEL_MASK  ((BIT(MICFIL_VAD0_CTRL1_CHSEL_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL1_CHSEL_SHIFT)
+-#define MICFIL_VAD0_CTRL1_CHSEL(v)    (((v) << MICFIL_VAD0_CTRL1_CHSEL_SHIFT) \
+-                                       & MICFIL_VAD0_CTRL1_CHSEL_MASK)
+-#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT        16
+-#define MICFIL_VAD0_CTRL1_CICOSR_WIDTH        4
+-#define MICFIL_VAD0_CTRL1_CICOSR_MASK ((BIT(MICFIL_VAD0_CTRL1_CICOSR_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL1_CICOSR_SHIFT)
+-#define MICFIL_VAD0_CTRL1_CICOSR(v)   (((v) << MICFIL_VAD0_CTRL1_CICOSR_SHIFT) \
+-                                       & MICFIL_VAD0_CTRL1_CICOSR_MASK)
+-#define MICFIL_VAD0_CTRL1_INITT_SHIFT 8
+-#define MICFIL_VAD0_CTRL1_INITT_WIDTH 5
+-#define MICFIL_VAD0_CTRL1_INITT_MASK  ((BIT(MICFIL_VAD0_CTRL1_INITT_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL1_INITT_SHIFT)
+-#define MICFIL_VAD0_CTRL1_INITT(v)    (((v) << MICFIL_VAD0_CTRL1_INITT_SHIFT) \
+-                                       & MICFIL_VAD0_CTRL1_INITT_MASK)
++#define MICFIL_VAD0_CTRL1_CHSEL_SHIFT GENMASK(26, 24)
++#define MICFIL_VAD0_CTRL1_CICOSR_SHIFT        GENMASK(19, 16)
++#define MICFIL_VAD0_CTRL1_INITT_SHIFT GENMASK(12, 8)
+ #define MICFIL_VAD0_CTRL1_ST10                BIT(4)
+ #define MICFIL_VAD0_CTRL1_ERIE                BIT(3)
+ #define MICFIL_VAD0_CTRL1_IE          BIT(2)
+@@ -125,66 +88,26 @@
+ #define MICFIL_VAD0_CTRL2_FRENDIS     BIT(31)
+ #define MICFIL_VAD0_CTRL2_PREFEN      BIT(30)
+ #define MICFIL_VAD0_CTRL2_FOUTDIS     BIT(28)
+-#define MICFIL_VAD0_CTRL2_FRAMET_SHIFT        16
+-#define MICFIL_VAD0_CTRL2_FRAMET_WIDTH        6
+-#define MICFIL_VAD0_CTRL2_FRAMET_MASK ((BIT(MICFIL_VAD0_CTRL2_FRAMET_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL2_FRAMET_SHIFT)
+-#define MICFIL_VAD0_CTRL2_FRAMET(v)   (((v) << MICFIL_VAD0_CTRL2_FRAMET_SHIFT) \
+-                                       & MICFIL_VAD0_CTRL2_FRAMET_MASK)
+-#define MICFIL_VAD0_CTRL2_INPGAIN_SHIFT       8
+-#define MICFIL_VAD0_CTRL2_INPGAIN_WIDTH       4
+-#define MICFIL_VAD0_CTRL2_INPGAIN_MASK        ((BIT(MICFIL_VAD0_CTRL2_INPGAIN_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT)
+-#define MICFIL_VAD0_CTRL2_INPGAIN(v)  (((v) << MICFIL_VAD0_CTRL2_INPGAIN_SHIFT) \
+-                                      & MICFIL_VAD0_CTRL2_INPGAIN_MASK)
+-#define MICFIL_VAD0_CTRL2_HPF_SHIFT   0
+-#define MICFIL_VAD0_CTRL2_HPF_WIDTH   2
+-#define MICFIL_VAD0_CTRL2_HPF_MASK    ((BIT(MICFIL_VAD0_CTRL2_HPF_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_CTRL2_HPF_SHIFT)
+-#define MICFIL_VAD0_CTRL2_HPF(v)      (((v) << MICFIL_VAD0_CTRL2_HPF_SHIFT) \
+-                                       & MICFIL_VAD0_CTRL2_HPF_MASK)
++#define MICFIL_VAD0_CTRL2_FRAMET      GENMASK(21, 16)
++#define MICFIL_VAD0_CTRL2_INPGAIN     GENMASK(11, 8)
++#define MICFIL_VAD0_CTRL2_HPF         GENMASK(1, 0)
+ /* MICFIL HWVAD0 Signal CONFIG Register -- REG_MICFIL_VAD0_SCONFIG */
+ #define MICFIL_VAD0_SCONFIG_SFILEN            BIT(31)
+ #define MICFIL_VAD0_SCONFIG_SMAXEN            BIT(30)
+-#define MICFIL_VAD0_SCONFIG_SGAIN_SHIFT               0
+-#define MICFIL_VAD0_SCONFIG_SGAIN_WIDTH               4
+-#define MICFIL_VAD0_SCONFIG_SGAIN_MASK                ((BIT(MICFIL_VAD0_SCONFIG_SGAIN_WIDTH) - 1) \
+-                                              << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT)
+-#define MICFIL_VAD0_SCONFIG_SGAIN(v)          (((v) << MICFIL_VAD0_SCONFIG_SGAIN_SHIFT) \
+-                                               & MICFIL_VAD0_SCONFIG_SGAIN_MASK)
++#define MICFIL_VAD0_SCONFIG_SGAIN             GENMASK(3, 0)
+ /* MICFIL HWVAD0 Noise CONFIG Register -- REG_MICFIL_VAD0_NCONFIG */
+ #define MICFIL_VAD0_NCONFIG_NFILAUT           BIT(31)
+ #define MICFIL_VAD0_NCONFIG_NMINEN            BIT(30)
+ #define MICFIL_VAD0_NCONFIG_NDECEN            BIT(29)
+ #define MICFIL_VAD0_NCONFIG_NOREN             BIT(28)
+-#define MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT     8
+-#define MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH     5
+-#define MICFIL_VAD0_NCONFIG_NFILADJ_MASK      ((BIT(MICFIL_VAD0_NCONFIG_NFILADJ_WIDTH) - 1) \
+-                                               << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NFILADJ(v)                (((v) << MICFIL_VAD0_NCONFIG_NFILADJ_SHIFT) \
+-                                               & MICFIL_VAD0_NCONFIG_NFILADJ_MASK)
+-#define MICFIL_VAD0_NCONFIG_NGAIN_SHIFT               0
+-#define MICFIL_VAD0_NCONFIG_NGAIN_WIDTH               4
+-#define MICFIL_VAD0_NCONFIG_NGAIN_MASK                ((BIT(MICFIL_VAD0_NCONFIG_NGAIN_WIDTH) - 1) \
+-                                               << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT)
+-#define MICFIL_VAD0_NCONFIG_NGAIN(v)          (((v) << MICFIL_VAD0_NCONFIG_NGAIN_SHIFT) \
+-                                               & MICFIL_VAD0_NCONFIG_NGAIN_MASK)
++#define MICFIL_VAD0_NCONFIG_NFILADJ           GENMASK(12, 8)
++#define MICFIL_VAD0_NCONFIG_NGAIN             GENMASK(3, 0)
+ /* MICFIL HWVAD0 Zero-Crossing Detector - REG_MICFIL_VAD0_ZCD */
+-#define MICFIL_VAD0_ZCD_ZCDTH_SHIFT   16
+-#define MICFIL_VAD0_ZCD_ZCDTH_WIDTH   10
+-#define MICFIL_VAD0_ZCD_ZCDTH_MASK    ((BIT(MICFIL_VAD0_ZCD_ZCDTH_WIDTH) - 1) \
+-                                       << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDTH(v)      (((v) << MICFIL_VAD0_ZCD_ZCDTH_SHIFT)\
+-                                       & MICFIL_VAD0_ZCD_ZCDTH_MASK)
+-#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT  8
+-#define MICFIL_VAD0_ZCD_ZCDADJ_WIDTH  4
+-#define MICFIL_VAD0_ZCD_ZCDADJ_MASK   ((BIT(MICFIL_VAD0_ZCD_ZCDADJ_WIDTH) - 1)\
+-                                       << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)
+-#define MICFIL_VAD0_ZCD_ZCDADJ(v)     (((v) << MICFIL_VAD0_ZCD_ZCDADJ_SHIFT)\
+-                                       & MICFIL_VAD0_ZCD_ZCDADJ_MASK)
++#define MICFIL_VAD0_ZCD_ZCDTH         GENMASK(25, 16)
++#define MICFIL_VAD0_ZCD_ZCDADJ_SHIFT  GENMASK(11, 8)
+ #define MICFIL_VAD0_ZCD_ZCDAND                BIT(4)
+ #define MICFIL_VAD0_ZCD_ZCDAUT                BIT(2)
+ #define MICFIL_VAD0_ZCD_ZCDEN         BIT(0)
+@@ -199,11 +122,6 @@
+ #define MICFIL_OUTGAIN_CHX_SHIFT(v)   (4 * (v))
+ /* Constants */
+-#define MICFIL_DMA_IRQ_DISABLED(v)    ((v) & MICFIL_CTRL1_DISEL_MASK)
+-#define MICFIL_DMA_ENABLED(v)         ((0x1 << MICFIL_CTRL1_DISEL_SHIFT) \
+-                                       == ((v) & MICFIL_CTRL1_DISEL_MASK))
+-#define MICFIL_IRQ_ENABLED(v)         ((0x2 << MICFIL_CTRL1_DISEL_SHIFT) \
+-                                       == ((v) & MICFIL_CTRL1_DISEL_MASK))
+ #define MICFIL_OUTPUT_CHANNELS                8
+ #define MICFIL_FIFO_NUM                       8
+@@ -215,6 +133,5 @@
+ #define MICFIL_SLEEP_MIN              90000 /* in us */
+ #define MICFIL_SLEEP_MAX              100000 /* in us */
+ #define MICFIL_DMA_MAXBURST_RX                6
+-#define MICFIL_CTRL2_OSR_DEFAULT      (0 << MICFIL_CTRL2_CICOSR_SHIFT)
+ #endif /* _FSL_MICFIL_H */
+-- 
+2.43.0
+
diff --git a/queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch b/queue-5.10/bluetooth-fix-use-after-free-in-device_for_each_chil.patch
new file mode 100644 (file)
index 0000000..25e1df5
--- /dev/null
@@ -0,0 +1,150 @@
+From 34f70e4d88b7ce406521458dc9c174cb788dfa97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2024 14:44:10 +0300
+Subject: Bluetooth: fix use-after-free in device_for_each_child()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 27aabf27fd014ae037cc179c61b0bee7cff55b3d ]
+
+Syzbot has reported the following KASAN splat:
+
+BUG: KASAN: slab-use-after-free in device_for_each_child+0x18f/0x1a0
+Read of size 8 at addr ffff88801f605308 by task kbnepd bnep0/4980
+
+CPU: 0 UID: 0 PID: 4980 Comm: kbnepd bnep0 Not tainted 6.12.0-rc4-00161-gae90f6a6170d #1
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x100/0x190
+ ? device_for_each_child+0x18f/0x1a0
+ print_report+0x13a/0x4cb
+ ? __virt_addr_valid+0x5e/0x590
+ ? __phys_addr+0xc6/0x150
+ ? device_for_each_child+0x18f/0x1a0
+ kasan_report+0xda/0x110
+ ? device_for_each_child+0x18f/0x1a0
+ ? __pfx_dev_memalloc_noio+0x10/0x10
+ device_for_each_child+0x18f/0x1a0
+ ? __pfx_device_for_each_child+0x10/0x10
+ pm_runtime_set_memalloc_noio+0xf2/0x180
+ netdev_unregister_kobject+0x1ed/0x270
+ unregister_netdevice_many_notify+0x123c/0x1d80
+ ? __mutex_trylock_common+0xde/0x250
+ ? __pfx_unregister_netdevice_many_notify+0x10/0x10
+ ? trace_contention_end+0xe6/0x140
+ ? __mutex_lock+0x4e7/0x8f0
+ ? __pfx_lock_acquire.part.0+0x10/0x10
+ ? rcu_is_watching+0x12/0xc0
+ ? unregister_netdev+0x12/0x30
+ unregister_netdevice_queue+0x30d/0x3f0
+ ? __pfx_unregister_netdevice_queue+0x10/0x10
+ ? __pfx_down_write+0x10/0x10
+ unregister_netdev+0x1c/0x30
+ bnep_session+0x1fb3/0x2ab0
+ ? __pfx_bnep_session+0x10/0x10
+ ? __pfx_lock_release+0x10/0x10
+ ? __pfx_woken_wake_function+0x10/0x10
+ ? __kthread_parkme+0x132/0x200
+ ? __pfx_bnep_session+0x10/0x10
+ ? kthread+0x13a/0x370
+ ? __pfx_bnep_session+0x10/0x10
+ kthread+0x2b7/0x370
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x48/0x80
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Allocated by task 4974:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0xaa/0xb0
+ __kmalloc_noprof+0x1d1/0x440
+ hci_alloc_dev_priv+0x1d/0x2820
+ __vhci_create_device+0xef/0x7d0
+ vhci_write+0x2c7/0x480
+ vfs_write+0x6a0/0xfc0
+ ksys_write+0x12f/0x260
+ do_syscall_64+0xc7/0x250
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 4979:
+ kasan_save_stack+0x30/0x50
+ kasan_save_track+0x14/0x30
+ kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x4f/0x70
+ kfree+0x141/0x490
+ hci_release_dev+0x4d9/0x600
+ bt_host_release+0x6a/0xb0
+ device_release+0xa4/0x240
+ kobject_put+0x1ec/0x5a0
+ put_device+0x1f/0x30
+ vhci_release+0x81/0xf0
+ __fput+0x3f6/0xb30
+ task_work_run+0x151/0x250
+ do_exit+0xa79/0x2c30
+ do_group_exit+0xd5/0x2a0
+ get_signal+0x1fcd/0x2210
+ arch_do_signal_or_restart+0x93/0x780
+ syscall_exit_to_user_mode+0x140/0x290
+ do_syscall_64+0xd4/0x250
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+In 'hci_conn_del_sysfs()', 'device_unregister()' may be called when
+an underlying (kobject) reference counter is greater than 1. This
+means that reparenting (happened when the device is actually freed)
+is delayed and, during that delay, parent controller device (hciX)
+may be deleted. Since the latter may create a dangling pointer to
+freed parent, avoid that scenario by reparenting to NULL explicitly.
+
+Reported-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com
+Tested-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6cf5652d3df49fae2e3f
+Fixes: a85fb91e3d72 ("Bluetooth: Fix double free in hci_conn_cleanup")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sysfs.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
+index 266112c960ee8..1b4d81ffb4b5e 100644
+--- a/net/bluetooth/hci_sysfs.c
++++ b/net/bluetooth/hci_sysfs.c
+@@ -19,16 +19,6 @@ static const struct device_type bt_link = {
+       .release = bt_link_release,
+ };
+-/*
+- * The rfcomm tty device will possibly retain even when conn
+- * is down, and sysfs doesn't support move zombie device,
+- * so we should move the device before conn device is destroyed.
+- */
+-static int __match_tty(struct device *dev, void *data)
+-{
+-      return !strncmp(dev_name(dev), "rfcomm", 6);
+-}
+-
+ void hci_conn_init_sysfs(struct hci_conn *conn)
+ {
+       struct hci_dev *hdev = conn->hdev;
+@@ -71,10 +61,13 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
+               return;
+       }
++      /* If there are devices using the connection as parent reset it to NULL
++       * before unregistering the device.
++       */
+       while (1) {
+               struct device *dev;
+-              dev = device_find_child(&conn->dev, NULL, __match_tty);
++              dev = device_find_any_child(&conn->dev);
+               if (!dev)
+                       break;
+               device_move(dev, NULL, DPM_ORDER_DEV_LAST);
+-- 
+2.43.0
+
diff --git a/queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch b/queue-5.10/bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch
new file mode 100644 (file)
index 0000000..6f0f48c
--- /dev/null
@@ -0,0 +1,54 @@
+From e22afc5de7a54bc63db5601f7e5088366bd0a0a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 14:45:41 -0800
+Subject: bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is
+ down
+
+From: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
+
+[ Upstream commit 5311598f7f3293683cdc761df71ae3469327332c ]
+
+After successful PCIe AER recovery, FW will reset all resource
+reservations.  If it is IF_UP, the driver will call bnxt_open() and
+all resources will be reserved again.  It it is IF_DOWN, we should
+call bnxt_reserve_rings() so that we can reserve resources including
+RoCE resources to allow RoCE to resume after AER.  Without this
+patch, RoCE fails to resume in this IF_DOWN scenario.
+
+Later, if it becomes IF_UP, bnxt_open() will see that resources have
+been reserved and will not reserve again.
+
+Fixes: fb1e6e562b37 ("bnxt_en: Fix AER recovery.")
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Reviewed-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 059552f4154d1..40c53404bccbb 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -13107,8 +13107,12 @@ static void bnxt_io_resume(struct pci_dev *pdev)
+       rtnl_lock();
+       err = bnxt_hwrm_func_qcaps(bp);
+-      if (!err && netif_running(netdev))
+-              err = bnxt_open(netdev);
++      if (!err) {
++              if (netif_running(netdev))
++                      err = bnxt_open(netdev);
++              else
++                      err = bnxt_reserve_rings(bp, true);
++      }
+       bnxt_ulp_start(bp, err);
+       if (!err) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch b/queue-5.10/bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch
new file mode 100644 (file)
index 0000000..53dae82
--- /dev/null
@@ -0,0 +1,41 @@
+From 2a7f254ced814fe40e9a6e4e4d387797c214433b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 10:41:15 +0800
+Subject: bpf: Fix the xdp_adjust_tail sample prog issue
+
+From: Yuan Chen <chenyuan@kylinos.cn>
+
+[ Upstream commit 4236f114a3ffbbfd217436c08852e94cae372f57 ]
+
+During the xdp_adjust_tail test, probabilistic failure occurs and SKB package
+is discarded by the kernel. After checking the issues by tracking SKB package,
+it is identified that they were caused by checksum errors. Refer to checksum
+of the arch/arm64/include/asm/checksum.h for fixing.
+
+v2: Based on Alexei Starovoitov's suggestions, it is necessary to keep the code
+ implementation consistent.
+
+Fixes: c6ffd1ff7856 (bpf: add bpf_xdp_adjust_tail sample prog)
+Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20240930024115.52841-1-chenyuan_fl@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/bpf/xdp_adjust_tail_kern.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/samples/bpf/xdp_adjust_tail_kern.c b/samples/bpf/xdp_adjust_tail_kern.c
+index ffdd548627f0a..da67bcad1c638 100644
+--- a/samples/bpf/xdp_adjust_tail_kern.c
++++ b/samples/bpf/xdp_adjust_tail_kern.c
+@@ -57,6 +57,7 @@ static __always_inline void swap_mac(void *data, struct ethhdr *orig_eth)
+ static __always_inline __u16 csum_fold_helper(__u32 csum)
+ {
++      csum = (csum & 0xffff) + (csum >> 16);
+       return ~((csum & 0xffff) + (csum >> 16));
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch b/queue-5.10/bpf-sockmap-fix-sk_msg_reset_curr.patch
new file mode 100644 (file)
index 0000000..daf52ff
--- /dev/null
@@ -0,0 +1,70 @@
+From 67ec108ab8ba5d76050751216a9b5836345dbb35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:20 +0000
+Subject: bpf, sockmap: Fix sk_msg_reset_curr
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 955afd57dc4bf7e8c620a0a9e3af3c881c2c6dff ]
+
+Found in the test_txmsg_pull in test_sockmap,
+```
+txmsg_cork = 512; // corking is importrant here
+opt->iov_length = 3;
+opt->iov_count = 1;
+opt->rate = 512; // sendmsg will be invoked 512 times
+```
+The first sendmsg will send an sk_msg with size 3, and bpf_msg_pull_data
+will be invoked the first time. sk_msg_reset_curr will reset the copybreak
+from 3 to 0. In the second sendmsg, since we are in the stage of corking,
+psock->cork will be reused in func sk_msg_alloc. msg->sg.copybreak is 0
+now, the second msg will overwrite the first msg. As a result, we could
+not pass the data integrity test.
+
+The same problem happens in push and pop test. Thus, fix sk_msg_reset_curr
+to restore the correct copybreak.
+
+Fixes: bb9aefde5bba ("bpf: sockmap, updating the sg structure should also update curr")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-9-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 345e6c5c71f06..0b61575df86ee 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2600,18 +2600,16 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
+ static void sk_msg_reset_curr(struct sk_msg *msg)
+ {
+-      u32 i = msg->sg.start;
+-      u32 len = 0;
+-
+-      do {
+-              len += sk_msg_elem(msg, i)->length;
+-              sk_msg_iter_var_next(i);
+-              if (len >= msg->sg.size)
+-                      break;
+-      } while (i != msg->sg.end);
++      if (!msg->sg.size) {
++              msg->sg.curr = msg->sg.start;
++              msg->sg.copybreak = 0;
++      } else {
++              u32 i = msg->sg.end;
+-      msg->sg.curr = i;
+-      msg->sg.copybreak = 0;
++              sk_msg_iter_var_prev(i);
++              msg->sg.curr = i;
++              msg->sg.copybreak = msg->sg.data[i].length;
++      }
+ }
+ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
+-- 
+2.43.0
+
diff --git a/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch
new file mode 100644 (file)
index 0000000..5480733
--- /dev/null
@@ -0,0 +1,104 @@
+From d46d712c5139f3a3f97a82ba4998985c68d0c1a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:19 +0000
+Subject: bpf, sockmap: Several fixes to bpf_msg_pop_data
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 5d609ba262475db450ba69b8e8a557bd768ac07a ]
+
+Several fixes to bpf_msg_pop_data,
+1. In sk_msg_shift_left, we should put_page
+2. if (len == 0), return early is better
+3. pop the entire sk_msg (last == msg->sg.size) should be supported
+4. Fix for the value of variable "a"
+5. In sk_msg_shift_left, after shifting, i has already pointed to the next
+element. Addtional sk_msg_iter_var_next may result in BUG.
+
+Fixes: 7246d8ed4dcc ("bpf: helper to pop data from messages")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-8-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 0ef77fb72af78..345e6c5c71f06 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2900,8 +2900,10 @@ static const struct bpf_func_proto bpf_msg_push_data_proto = {
+ static void sk_msg_shift_left(struct sk_msg *msg, int i)
+ {
++      struct scatterlist *sge = sk_msg_elem(msg, i);
+       int prev;
++      put_page(sg_page(sge));
+       do {
+               prev = i;
+               sk_msg_iter_var_next(i);
+@@ -2938,6 +2940,9 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+       if (unlikely(flags))
+               return -EINVAL;
++      if (unlikely(len == 0))
++              return 0;
++
+       /* First find the starting scatterlist element */
+       i = msg->sg.start;
+       do {
+@@ -2950,7 +2955,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+       } while (i != msg->sg.end);
+       /* Bounds checks: start and pop must be inside message */
+-      if (start >= offset + l || last >= msg->sg.size)
++      if (start >= offset + l || last > msg->sg.size)
+               return -EINVAL;
+       space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
+@@ -2979,12 +2984,12 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+        */
+       if (start != offset) {
+               struct scatterlist *nsge, *sge = sk_msg_elem(msg, i);
+-              int a = start;
++              int a = start - offset;
+               int b = sge->length - pop - a;
+               sk_msg_iter_var_next(i);
+-              if (pop < sge->length - a) {
++              if (b > 0) {
+                       if (space) {
+                               sge->length = a;
+                               sk_msg_shift_right(msg, i);
+@@ -3003,7 +3008,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+                               if (unlikely(!page))
+                                       return -ENOMEM;
+-                              sge->length = a;
+                               orig = sg_page(sge);
+                               from = sg_virt(sge);
+                               to = page_address(page);
+@@ -3013,7 +3017,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+                               put_page(orig);
+                       }
+                       pop = 0;
+-              } else if (pop >= sge->length - a) {
++              } else {
+                       pop -= (sge->length - a);
+                       sge->length = a;
+               }
+@@ -3047,7 +3051,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
+                       pop -= sge->length;
+                       sk_msg_shift_left(msg, i);
+               }
+-              sk_msg_iter_var_next(i);
+       }
+       sk_mem_uncharge(msg->sk, len - pop);
+-- 
+2.43.0
+
diff --git a/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch b/queue-5.10/bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch
new file mode 100644 (file)
index 0000000..433f48a
--- /dev/null
@@ -0,0 +1,132 @@
+From 7e741fd88f8e01cc0bbfcbf410983c9892fc432e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:18 +0000
+Subject: bpf, sockmap: Several fixes to bpf_msg_push_data
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 15ab0548e3107665c34579ae523b2b6e7c22082a ]
+
+Several fixes to bpf_msg_push_data,
+1. test_sockmap has tests where bpf_msg_push_data is invoked to push some
+data at the end of a message, but -EINVAL is returned. In this case, in
+bpf_msg_push_data, after the first loop, i will be set to msg->sg.end, add
+the logic to handle it.
+2. In the code block of "if (start - offset)", it's possible that "i"
+points to the last of sk_msg_elem. In this case, "sk_msg_iter_next(msg,
+end)" might still be called twice, another invoking is in "if (!copy)"
+code block, but actually only one is needed. Add the logic to handle it,
+and reconstruct the code to make the logic more clear.
+
+Fixes: 6fff607e2f14 ("bpf: sk_msg program helper bpf_msg_push_data")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-7-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 53 +++++++++++++++++++++++++++++------------------
+ 1 file changed, 33 insertions(+), 20 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 99fdd8afeeda3..0ef77fb72af78 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2774,7 +2774,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+               sk_msg_iter_var_next(i);
+       } while (i != msg->sg.end);
+-      if (start >= offset + l)
++      if (start > offset + l)
+               return -EINVAL;
+       space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
+@@ -2799,6 +2799,8 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+               raw = page_address(page);
++              if (i == msg->sg.end)
++                      sk_msg_iter_var_prev(i);
+               psge = sk_msg_elem(msg, i);
+               front = start - offset;
+               back = psge->length - front;
+@@ -2815,7 +2817,13 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+               }
+               put_page(sg_page(psge));
+-      } else if (start - offset) {
++              new = i;
++              goto place_new;
++      }
++
++      if (start - offset) {
++              if (i == msg->sg.end)
++                      sk_msg_iter_var_prev(i);
+               psge = sk_msg_elem(msg, i);
+               rsge = sk_msg_elem_cpy(msg, i);
+@@ -2826,39 +2834,44 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
+               sk_msg_iter_var_next(i);
+               sg_unmark_end(psge);
+               sg_unmark_end(&rsge);
+-              sk_msg_iter_next(msg, end);
+       }
+       /* Slot(s) to place newly allocated data */
++      sk_msg_iter_next(msg, end);
+       new = i;
++      sk_msg_iter_var_next(i);
++
++      if (i == msg->sg.end) {
++              if (!rsge.length)
++                      goto place_new;
++              sk_msg_iter_next(msg, end);
++              goto place_new;
++      }
+       /* Shift one or two slots as needed */
+-      if (!copy) {
+-              sge = sk_msg_elem_cpy(msg, i);
++      sge = sk_msg_elem_cpy(msg, new);
++      sg_unmark_end(&sge);
++      nsge = sk_msg_elem_cpy(msg, i);
++      if (rsge.length) {
+               sk_msg_iter_var_next(i);
+-              sg_unmark_end(&sge);
++              nnsge = sk_msg_elem_cpy(msg, i);
+               sk_msg_iter_next(msg, end);
++      }
+-              nsge = sk_msg_elem_cpy(msg, i);
++      while (i != msg->sg.end) {
++              msg->sg.data[i] = sge;
++              sge = nsge;
++              sk_msg_iter_var_next(i);
+               if (rsge.length) {
+-                      sk_msg_iter_var_next(i);
++                      nsge = nnsge;
+                       nnsge = sk_msg_elem_cpy(msg, i);
+-              }
+-
+-              while (i != msg->sg.end) {
+-                      msg->sg.data[i] = sge;
+-                      sge = nsge;
+-                      sk_msg_iter_var_next(i);
+-                      if (rsge.length) {
+-                              nsge = nnsge;
+-                              nnsge = sk_msg_elem_cpy(msg, i);
+-                      } else {
+-                              nsge = sk_msg_elem_cpy(msg, i);
+-                      }
++              } else {
++                      nsge = sk_msg_elem_cpy(msg, i);
+               }
+       }
++place_new:
+       /* Place newly allocated data buffer */
+       sk_mem_charge(msg->sk, len);
+       msg->sg.size += len;
+-- 
+2.43.0
+
diff --git a/queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch b/queue-5.10/cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch
new file mode 100644 (file)
index 0000000..6f57379
--- /dev/null
@@ -0,0 +1,70 @@
+From 08aa2b37f0f4c310180b634aced6b162803cd609 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 08:15:20 +0000
+Subject: cgroup/bpf: only cgroup v2 can be attached by bpf programs
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit 2190df6c91373fdec6db9fc07e427084f232f57e ]
+
+Only cgroup v2 can be attached by bpf programs, so this patch introduces
+that cgroup_bpf_inherit and cgroup_bpf_offline can only be called in
+cgroup v2, and this can fix the memleak mentioned by commit 04f8ef5643bc
+("cgroup: Fix memory leak caused by missing cgroup_bpf_offline"), which
+has been reverted.
+
+Fixes: 2b0d3d3e4fcf ("percpu_ref: reduce memory footprint of percpu_ref in fast path")
+Fixes: 4bfc0bb2c60e ("bpf: decouple the lifetime of cgroup_bpf from cgroup itself")
+Link: https://lore.kernel.org/cgroups/aka2hk5jsel5zomucpwlxsej6iwnfw4qu5jkrmjhyfhesjlfdw@46zxhg5bdnr7/
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cgroup.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index c5e51bad62473..efeb0b7427501 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -2018,8 +2018,10 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
+       if (ret)
+               goto destroy_root;
+-      ret = cgroup_bpf_inherit(root_cgrp);
+-      WARN_ON_ONCE(ret);
++      if (root == &cgrp_dfl_root) {
++              ret = cgroup_bpf_inherit(root_cgrp);
++              WARN_ON_ONCE(ret);
++      }
+       trace_cgroup_setup_root(root);
+@@ -5355,9 +5357,11 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
+       if (ret)
+               goto out_kernfs_remove;
+-      ret = cgroup_bpf_inherit(cgrp);
+-      if (ret)
+-              goto out_psi_free;
++      if (cgrp->root == &cgrp_dfl_root) {
++              ret = cgroup_bpf_inherit(cgrp);
++              if (ret)
++                      goto out_psi_free;
++      }
+       /*
+        * New cgroup inherits effective freeze counter, and
+@@ -5676,7 +5680,8 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
+       cgroup1_check_for_release(parent);
+-      cgroup_bpf_offline(cgrp);
++      if (cgrp->root == &cgrp_dfl_root)
++              cgroup_bpf_offline(cgrp);
+       /* put the base reference */
+       percpu_ref_kill(&cgrp->self.refcnt);
+-- 
+2.43.0
+
diff --git a/queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch b/queue-5.10/clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch
new file mode 100644 (file)
index 0000000..9edb356
--- /dev/null
@@ -0,0 +1,47 @@
+From 7e6df323d0511605bd750c6016a8a2afbbe44aaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Feb 2021 17:12:45 +0200
+Subject: clk: axi-clkgen: use devm_platform_ioremap_resource() short-hand
+
+From: Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+[ Upstream commit 6ba7ea7630fb03c1ce01508bdf89f5bb39b38e54 ]
+
+No major functional change. Noticed while checking the driver code that
+this could be used.
+Saves two lines.
+
+Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Link: https://lore.kernel.org/r/20210201151245.21845-5-alexandru.ardelean@analog.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: c64ef7e4851d ("clk: clk-axi-clkgen: make sure to enable the AXI bus clock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-axi-clkgen.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
+index 14d803e6af623..1aa3d9fd8d0ac 100644
+--- a/drivers/clk/clk-axi-clkgen.c
++++ b/drivers/clk/clk-axi-clkgen.c
+@@ -497,7 +497,6 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+       struct clk_init_data init;
+       const char *parent_names[2];
+       const char *clk_name;
+-      struct resource *mem;
+       unsigned int i;
+       int ret;
+@@ -512,8 +511,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+       if (!axi_clkgen)
+               return -ENOMEM;
+-      mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
++      axi_clkgen->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(axi_clkgen->base))
+               return PTR_ERR(axi_clkgen->base);
+-- 
+2.43.0
+
diff --git a/queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch b/queue-5.10/clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch
new file mode 100644 (file)
index 0000000..64d7d92
--- /dev/null
@@ -0,0 +1,82 @@
+From bb5ca78ce0ee4e6fb3da5731b726a44cb4b9d668 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 14:59:42 +0100
+Subject: clk: clk-axi-clkgen: make sure to enable the AXI bus clock
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit c64ef7e4851d1a9abbb7f7833e4936973ac5ba79 ]
+
+In order to access the registers of the HW, we need to make sure that
+the AXI bus clock is enabled. Hence let's increase the number of clocks
+by one.
+
+In order to keep backward compatibility and make sure old DTs still work
+we check if clock-names is available or not. If it is, then we can
+disambiguate between really having the AXI clock or a parent clock and
+so we can enable the bus clock. If not, we fallback to what was done
+before and don't explicitly enable the AXI bus clock.
+
+Note that if clock-names is given, the axi clock must be the last one in
+the phandle array (also enforced in the DT bindings) so that we can reuse
+as much code as possible.
+
+Fixes: 0e646c52cf0e ("clk: Add axi-clkgen driver")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20241029-axi-clkgen-fix-axiclk-v2-2-bc5e0733ad76@analog.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-axi-clkgen.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
+index 1aa3d9fd8d0ac..3e2cf1fad262e 100644
+--- a/drivers/clk/clk-axi-clkgen.c
++++ b/drivers/clk/clk-axi-clkgen.c
+@@ -7,6 +7,7 @@
+  */
+ #include <linux/platform_device.h>
++#include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/slab.h>
+ #include <linux/io.h>
+@@ -497,6 +498,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+       struct clk_init_data init;
+       const char *parent_names[2];
+       const char *clk_name;
++      struct clk *axi_clk;
+       unsigned int i;
+       int ret;
+@@ -516,8 +518,24 @@ static int axi_clkgen_probe(struct platform_device *pdev)
+               return PTR_ERR(axi_clkgen->base);
+       init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
+-      if (init.num_parents < 1 || init.num_parents > 2)
+-              return -EINVAL;
++
++      axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
++      if (!IS_ERR(axi_clk)) {
++              if (init.num_parents < 2 || init.num_parents > 3)
++                      return -EINVAL;
++
++              init.num_parents -= 1;
++      } else {
++              /*
++               * Legacy... So that old DTs which do not have clock-names still
++               * work. In this case we don't explicitly enable the AXI bus
++               * clock.
++               */
++              if (PTR_ERR(axi_clk) != -ENOENT)
++                      return PTR_ERR(axi_clk);
++              if (init.num_parents < 1 || init.num_parents > 2)
++                      return -EINVAL;
++      }
+       for (i = 0; i < init.num_parents; i++) {
+               parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
+-- 
+2.43.0
+
diff --git a/queue-5.10/clkdev-remove-config_clkdev_lookup.patch b/queue-5.10/clkdev-remove-config_clkdev_lookup.patch
new file mode 100644 (file)
index 0000000..f685113
--- /dev/null
@@ -0,0 +1,286 @@
+From 1480321fd75393ab5c065a8b5aa424b228597e23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 May 2021 11:48:49 +0200
+Subject: clkdev: remove CONFIG_CLKDEV_LOOKUP
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 2f4574dd6dd19eb3e8ab0415a3ae960d04be3a65 ]
+
+This option is now synonymous with CONFIG_HAVE_CLK, so use
+the latter globally. Any out-of-tree platform ports that
+still use a private clk_get()/clk_put() implementation should
+move to CONFIG_COMMON_CLK.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Stable-dep-of: 0309f714a090 ("clocksource/drivers:sp804: Make user selectable")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/Kconfig              |  2 --
+ arch/mips/Kconfig             |  3 ---
+ arch/mips/pic32/Kconfig       |  1 -
+ arch/sh/Kconfig               |  1 -
+ drivers/clk/Kconfig           |  6 +-----
+ drivers/clk/Makefile          |  3 +--
+ drivers/clocksource/Kconfig   |  6 +++---
+ drivers/mmc/host/Kconfig      |  4 ++--
+ drivers/staging/board/Kconfig |  2 +-
+ sound/soc/dwc/Kconfig         |  2 +-
+ sound/soc/rockchip/Kconfig    | 14 +++++++-------
+ 11 files changed, 16 insertions(+), 28 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 335308aff6ce0..27db1bddfb6c5 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -366,7 +366,6 @@ config ARCH_EP93XX
+       imply ARM_PATCH_PHYS_VIRT
+       select ARM_VIC
+       select AUTO_ZRELADDR
+-      select CLKDEV_LOOKUP
+       select CLKSRC_MMIO
+       select CPU_ARM920T
+       select GENERIC_CLOCKEVENTS
+@@ -523,7 +522,6 @@ config ARCH_OMAP1
+       bool "TI OMAP1"
+       depends on MMU
+       select ARCH_OMAP
+-      select CLKDEV_LOOKUP
+       select CLKSRC_MMIO
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_IRQ_CHIP
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 57839f63074f7..7aeb3a7d4926d 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -327,7 +327,6 @@ config BCM63XX
+       select SWAP_IO_SPACE
+       select GPIOLIB
+       select MIPS_L1_CACHE_SHIFT_4
+-      select CLKDEV_LOOKUP
+       select HAVE_LEGACY_CLK
+       help
+         Support for BCM63XX based boards
+@@ -442,7 +441,6 @@ config LANTIQ
+       select GPIOLIB
+       select SWAP_IO_SPACE
+       select BOOT_RAW
+-      select CLKDEV_LOOKUP
+       select HAVE_LEGACY_CLK
+       select USE_OF
+       select PINCTRL
+@@ -627,7 +625,6 @@ config RALINK
+       select SYS_SUPPORTS_MIPS16
+       select SYS_SUPPORTS_ZBOOT
+       select SYS_HAS_EARLY_PRINTK
+-      select CLKDEV_LOOKUP
+       select ARCH_HAS_RESET_CONTROLLER
+       select RESET_CONTROLLER
+diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig
+index 7acbb50c1dcd5..bb6ab1f3e80dc 100644
+--- a/arch/mips/pic32/Kconfig
++++ b/arch/mips/pic32/Kconfig
+@@ -17,7 +17,6 @@ config PIC32MZDA
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select GPIOLIB
+       select COMMON_CLK
+-      select CLKDEV_LOOKUP
+       select LIBFDT
+       select USE_OF
+       select PINCTRL
+diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
+index 44dffe7ce50ad..51f9ca675c416 100644
+--- a/arch/sh/Kconfig
++++ b/arch/sh/Kconfig
+@@ -13,7 +13,6 @@ config SUPERH
+       select ARCH_HIBERNATION_POSSIBLE if MMU
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_WANT_IPC_PARSE_VERSION
+-      select CLKDEV_LOOKUP
+       select CPU_NO_EFFICIENT_FFS
+       select DMA_DECLARE_COHERENT
+       select GENERIC_ATOMIC64
+diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
+index df739665f2063..1a4cd684a4371 100644
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -6,10 +6,6 @@ config HAVE_CLK
+         The <linux/clk.h> calls support software clock gating and
+         thus are a key power management tool on many systems.
+-config CLKDEV_LOOKUP
+-      bool
+-      select HAVE_CLK
+-
+ config HAVE_CLK_PREPARE
+       bool
+@@ -26,7 +22,7 @@ menuconfig COMMON_CLK
+       bool "Common Clock Framework"
+       depends on !HAVE_LEGACY_CLK
+       select HAVE_CLK_PREPARE
+-      select CLKDEV_LOOKUP
++      select HAVE_CLK
+       select SRCU
+       select RATIONAL
+       help
+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
+index da8fcf147eb13..707b592333918 100644
+--- a/drivers/clk/Makefile
++++ b/drivers/clk/Makefile
+@@ -1,7 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+ # common clock types
+-obj-$(CONFIG_HAVE_CLK)                += clk-devres.o clk-bulk.o
+-obj-$(CONFIG_CLKDEV_LOOKUP)   += clkdev.o
++obj-$(CONFIG_HAVE_CLK)                += clk-devres.o clk-bulk.o clkdev.o
+ obj-$(CONFIG_COMMON_CLK)      += clk.o
+ obj-$(CONFIG_COMMON_CLK)      += clk-divider.o
+ obj-$(CONFIG_COMMON_CLK)      += clk-fixed-factor.o
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index a0c6e88bebe08..be4bb4008d6e6 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -399,7 +399,7 @@ config ARM_GLOBAL_TIMER
+ config ARM_TIMER_SP804
+       bool "Support for Dual Timer SP804 module" if COMPILE_TEST
+-      depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP
++      depends on GENERIC_SCHED_CLOCK && HAVE_CLK
+       select CLKSRC_MMIO
+       select TIMER_OF if OF
+@@ -617,12 +617,12 @@ config H8300_TPU
+ config CLKSRC_IMX_GPT
+       bool "Clocksource using i.MX GPT" if COMPILE_TEST
+-      depends on (ARM || ARM64) && CLKDEV_LOOKUP
++      depends on (ARM || ARM64) && HAVE_CLK
+       select CLKSRC_MMIO
+ config CLKSRC_IMX_TPM
+       bool "Clocksource using i.MX TPM" if COMPILE_TEST
+-      depends on (ARM || ARM64) && CLKDEV_LOOKUP
++      depends on (ARM || ARM64) && HAVE_CLK
+       select CLKSRC_MMIO
+       select TIMER_OF
+       help
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 8fe4a0fd6ef18..9a6a94d5bdbdb 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -326,7 +326,7 @@ config MMC_SDHCI_SIRF
+ config MMC_SDHCI_PXAV3
+       tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
+-      depends on CLKDEV_LOOKUP
++      depends on HAVE_CLK
+       depends on MMC_SDHCI_PLTFM
+       depends on ARCH_BERLIN || ARCH_MMP || ARCH_MVEBU || COMPILE_TEST
+       default CPU_MMP2
+@@ -339,7 +339,7 @@ config MMC_SDHCI_PXAV3
+ config MMC_SDHCI_PXAV2
+       tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
+-      depends on CLKDEV_LOOKUP
++      depends on HAVE_CLK
+       depends on MMC_SDHCI_PLTFM
+       depends on ARCH_MMP || COMPILE_TEST
+       default CPU_PXA910
+diff --git a/drivers/staging/board/Kconfig b/drivers/staging/board/Kconfig
+index d0c6e42eadda4..ff5e417dd8528 100644
+--- a/drivers/staging/board/Kconfig
++++ b/drivers/staging/board/Kconfig
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ config STAGING_BOARD
+       bool "Staging Board Support"
+-      depends on OF_ADDRESS && OF_IRQ && CLKDEV_LOOKUP
++      depends on OF_ADDRESS && OF_IRQ && HAVE_CLK
+       help
+         Select to enable per-board staging support code.
+diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
+index 0cd1a15f40aae..71a58f7ac13a9 100644
+--- a/sound/soc/dwc/Kconfig
++++ b/sound/soc/dwc/Kconfig
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ config SND_DESIGNWARE_I2S
+       tristate "Synopsys I2S Device Driver"
+-      depends on CLKDEV_LOOKUP
++      depends on HAVE_CLK
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       help
+        Say Y or M if you want to add support for I2S driver for
+diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
+index d610b553ea3b2..053097b73e28d 100644
+--- a/sound/soc/rockchip/Kconfig
++++ b/sound/soc/rockchip/Kconfig
+@@ -9,7 +9,7 @@ config SND_SOC_ROCKCHIP
+ config SND_SOC_ROCKCHIP_I2S
+       tristate "Rockchip I2S Device Driver"
+-      depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
++      depends on HAVE_CLK && SND_SOC_ROCKCHIP
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       help
+         Say Y or M if you want to add support for I2S driver for
+@@ -18,7 +18,7 @@ config SND_SOC_ROCKCHIP_I2S
+ config SND_SOC_ROCKCHIP_PDM
+       tristate "Rockchip PDM Controller Driver"
+-      depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
++      depends on HAVE_CLK && SND_SOC_ROCKCHIP
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       select RATIONAL
+       help
+@@ -28,7 +28,7 @@ config SND_SOC_ROCKCHIP_PDM
+ config SND_SOC_ROCKCHIP_SPDIF
+       tristate "Rockchip SPDIF Device Driver"
+-      depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
++      depends on HAVE_CLK && SND_SOC_ROCKCHIP
+       select SND_SOC_GENERIC_DMAENGINE_PCM
+       help
+         Say Y or M if you want to add support for SPDIF driver for
+@@ -36,7 +36,7 @@ config SND_SOC_ROCKCHIP_SPDIF
+ config SND_SOC_ROCKCHIP_MAX98090
+       tristate "ASoC support for Rockchip boards using a MAX98090 codec"
+-      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
++      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
+       select SND_SOC_ROCKCHIP_I2S
+       select SND_SOC_MAX98090
+       select SND_SOC_TS3A227E
+@@ -47,7 +47,7 @@ config SND_SOC_ROCKCHIP_MAX98090
+ config SND_SOC_ROCKCHIP_RT5645
+       tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
+-      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
++      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
+       select SND_SOC_ROCKCHIP_I2S
+       select SND_SOC_RT5645
+       help
+@@ -56,7 +56,7 @@ config SND_SOC_ROCKCHIP_RT5645
+ config SND_SOC_RK3288_HDMI_ANALOG
+       tristate "ASoC support multiple codecs for Rockchip RK3288 boards"
+-      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
++      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK
+       select SND_SOC_ROCKCHIP_I2S
+       select SND_SOC_HDMI_CODEC
+       select SND_SOC_ES8328_I2C
+@@ -68,7 +68,7 @@ config SND_SOC_RK3288_HDMI_ANALOG
+ config SND_SOC_RK3399_GRU_SOUND
+       tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards"
+-      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI
++      depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK && SPI
+       select SND_SOC_ROCKCHIP_I2S
+       select SND_SOC_MAX98357A
+       select SND_SOC_RT5514
+-- 
+2.43.0
+
diff --git a/queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch b/queue-5.10/clocksource-drivers-sp804-make-user-selectable.patch
new file mode 100644 (file)
index 0000000..8d41df9
--- /dev/null
@@ -0,0 +1,49 @@
+From a22a96cf7601952f4618faa58820296e17905cc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 12:23:56 +0100
+Subject: clocksource/drivers:sp804: Make user selectable
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 0309f714a0908e947af1c902cf6a330cb593e75e ]
+
+The sp804 is currently only user selectable if COMPILE_TEST, this was
+done by commit dfc82faad725 ("clocksource/drivers/sp804: Add
+COMPILE_TEST to CONFIG_ARM_TIMER_SP804") in order to avoid it being
+spuriously offered on platforms that won't have the hardware since it's
+generally only seen on Arm based platforms.  This config is overly
+restrictive, while platforms that rely on the SP804 do select it in
+their Kconfig there are others such as the Arm fast models which have a
+SP804 available but currently unused by Linux.  Relax the dependency to
+allow it to be user selectable on arm and arm64 to avoid surprises and
+in case someone comes up with a use for extra timer hardware.
+
+Fixes: dfc82faad725 ("clocksource/drivers/sp804: Add COMPILE_TEST to CONFIG_ARM_TIMER_SP804")
+Reported-by: Ross Burton <ross.burton@arm.com>
+Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20241001-arm64-vexpress-sp804-v3-1-0a2d3f7883e4@kernel.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index be4bb4008d6e6..8206158e637dc 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -398,7 +398,8 @@ config ARM_GLOBAL_TIMER
+         This option enables support for the ARM global timer unit.
+ config ARM_TIMER_SP804
+-      bool "Support for Dual Timer SP804 module" if COMPILE_TEST
++      bool "Support for Dual Timer SP804 module"
++      depends on ARM || ARM64 || COMPILE_TEST
+       depends on GENERIC_SCHED_CLOCK && HAVE_CLK
+       select CLKSRC_MMIO
+       select TIMER_OF if OF
+-- 
+2.43.0
+
diff --git a/queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch b/queue-5.10/clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch
new file mode 100644 (file)
index 0000000..32c69e8
--- /dev/null
@@ -0,0 +1,46 @@
+From 4be1996a4a9494744cb506b8563e3a8ba3961312 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Oct 2024 13:54:23 +0100
+Subject: clocksource/drivers/timer-ti-dm: Fix child node refcount handling
+
+From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+
+[ Upstream commit e5cfc0989d9a2849c51c720a16b90b2c061a1aeb ]
+
+of_find_compatible_node() increments the node's refcount, and it must be
+decremented again with a call to of_node_put() when the pointer is no
+longer required to avoid leaking the resource.
+
+Instead of adding the missing calls to of_node_put() in all execution
+paths, use the cleanup attribute for 'arm_timer' by means of the
+__free() macro, which automatically calls of_node_put() when the
+variable goes out of scope.
+
+Fixes: 25de4ce5ed02 ("clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940")
+Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Link: https://lore.kernel.org/r/20241031-timer-ti-dm-systimer-of_node_put-v3-1-063ee822b73a@gmail.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/timer-ti-dm-systimer.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index 632523c1232f6..734920e8c5759 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -688,9 +688,9 @@ subsys_initcall(dmtimer_percpu_timer_startup);
+ static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
+ {
+-      struct device_node *arm_timer;
++      struct device_node *arm_timer __free(device_node) =
++              of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+-      arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
+       if (of_device_is_available(arm_timer)) {
+               pr_warn_once("ARM architected timer wrap issue i940 detected\n");
+               return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch b/queue-5.10/cpufreq-loongson2-unregister-platform_driver-on-fail.patch
new file mode 100644 (file)
index 0000000..6f2cbd0
--- /dev/null
@@ -0,0 +1,39 @@
+From 2faf29d851fda4496050ff92892f9a965250f3b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 17:06:15 +0800
+Subject: cpufreq: loongson2: Unregister platform_driver on failure
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 5f856d71ccdf89b4bac0ff70ebb0bb582e7f7f18 ]
+
+When cpufreq_register_driver() returns error, the cpufreq_init() returns
+without unregister platform_driver, fix by add missing
+platform_driver_unregister() when cpufreq_register_driver() failed.
+
+Fixes: f8ede0f700f5 ("MIPS: Loongson 2F: Add CPU frequency scaling support")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/loongson2_cpufreq.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
+index d05e761d95721..e1893e33b1a94 100644
+--- a/drivers/cpufreq/loongson2_cpufreq.c
++++ b/drivers/cpufreq/loongson2_cpufreq.c
+@@ -155,7 +155,9 @@ static int __init cpufreq_init(void)
+       ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
+-      if (!ret && !nowait) {
++      if (ret) {
++              platform_driver_unregister(&platform_driver);
++      } else if (!nowait) {
+               saved_cpu_wait = cpu_wait;
+               cpu_wait = loongson2_cpu_wait;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch b/queue-5.10/crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch
new file mode 100644 (file)
index 0000000..702317b
--- /dev/null
@@ -0,0 +1,47 @@
+From 287c630fb7372b9204d9afb0ccf816f84322a7f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 12:17:45 +0000
+Subject: crypto: bcm - add error check in the ahash_hmac_init function
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit 19630cf57233e845b6ac57c9c969a4888925467b ]
+
+The ahash_init functions may return fails. The ahash_hmac_init should
+not return ok when ahash_init returns error. For an example, ahash_init
+will return -ENOMEM when allocation memory is error.
+
+Fixes: 9d12ba86f818 ("crypto: brcm - Add Broadcom SPU driver")
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/bcm/cipher.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c
+index 1cb310a133b3f..b13e33b88d68a 100644
+--- a/drivers/crypto/bcm/cipher.c
++++ b/drivers/crypto/bcm/cipher.c
+@@ -2417,6 +2417,7 @@ static int ahash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
+ static int ahash_hmac_init(struct ahash_request *req)
+ {
++      int ret;
+       struct iproc_reqctx_s *rctx = ahash_request_ctx(req);
+       struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+       struct iproc_ctx_s *ctx = crypto_ahash_ctx(tfm);
+@@ -2426,7 +2427,9 @@ static int ahash_hmac_init(struct ahash_request *req)
+       flow_log("ahash_hmac_init()\n");
+       /* init the context as a hash */
+-      ahash_init(req);
++      ret = ahash_init(req);
++      if (ret)
++              return ret;
+       if (!spu_no_incr_hash(ctx)) {
+               /* SPU-M can do incr hashing but needs sw for outer HMAC */
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch b/queue-5.10/crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch
new file mode 100644 (file)
index 0000000..495d2ba
--- /dev/null
@@ -0,0 +1,78 @@
+From e9f85f21da0c8037a9befeb1a9c4ccf547e7244d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 12:15:11 +0000
+Subject: crypto: caam - add error check to caam_rsa_set_priv_key_form
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit b64140c74e954f1db6eae5548ca3a1f41b6fad79 ]
+
+The caam_rsa_set_priv_key_form did not check for memory allocation errors.
+Add the checks to the caam_rsa_set_priv_key_form functions.
+
+Fixes: 52e26d77b8b3 ("crypto: caam - add support for RSA key form 2")
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Reviewed-by: Gaurav Jain <gaurav.jain@nxp.com>
+Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/caam/caampkc.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
+index 5bd70a59f4ce2..c3c47756f25fe 100644
+--- a/drivers/crypto/caam/caampkc.c
++++ b/drivers/crypto/caam/caampkc.c
+@@ -975,7 +975,7 @@ static int caam_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+       return -ENOMEM;
+ }
+-static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
++static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+                                      struct rsa_key *raw_key)
+ {
+       struct caam_rsa_key *rsa_key = &ctx->key;
+@@ -984,7 +984,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+       rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz);
+       if (!rsa_key->p)
+-              return;
++              return -ENOMEM;
+       rsa_key->p_sz = p_sz;
+       rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz);
+@@ -1017,7 +1017,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+       rsa_key->priv_form = FORM3;
+-      return;
++      return 0;
+ free_dq:
+       kfree_sensitive(rsa_key->dq);
+@@ -1031,6 +1031,7 @@ static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+       kfree_sensitive(rsa_key->q);
+ free_p:
+       kfree_sensitive(rsa_key->p);
++      return -ENOMEM;
+ }
+ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+@@ -1076,7 +1077,9 @@ static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
+       rsa_key->e_sz = raw_key.e_sz;
+       rsa_key->n_sz = raw_key.n_sz;
+-      caam_rsa_set_priv_key_form(ctx, &raw_key);
++      ret = caam_rsa_set_priv_key_form(ctx, &raw_key);
++      if (ret)
++              goto err;
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch b/queue-5.10/crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch
new file mode 100644 (file)
index 0000000..71bc2e4
--- /dev/null
@@ -0,0 +1,40 @@
+From 6f4eba739f56c2f8e7271e66af63a25a6fa48f48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Sep 2024 12:22:12 +0200
+Subject: crypto: caam - Fix the pointer passed to caam_qi_shutdown()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ad980b04f51f7fb503530bd1cb328ba5e75a250e ]
+
+The type of the last parameter given to devm_add_action_or_reset() is
+"struct caam_drv_private *", but in caam_qi_shutdown(), it is casted to
+"struct device *".
+
+Pass the correct parameter to devm_add_action_or_reset() so that the
+resources are released as expected.
+
+Fixes: f414de2e2fff ("crypto: caam - use devres to de-initialize QI")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/caam/qi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c
+index ec53528d82058..8e9f6097114e3 100644
+--- a/drivers/crypto/caam/qi.c
++++ b/drivers/crypto/caam/qi.c
+@@ -768,7 +768,7 @@ int caam_qi_init(struct platform_device *caam_pdev)
+       caam_debugfs_qi_init(ctrlpriv);
+-      err = devm_add_action_or_reset(qidev, caam_qi_shutdown, ctrlpriv);
++      err = devm_add_action_or_reset(qidev, caam_qi_shutdown, qidev);
+       if (err)
+               return err;
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch b/queue-5.10/crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch
new file mode 100644 (file)
index 0000000..24c98df
--- /dev/null
@@ -0,0 +1,38 @@
+From 7cd9d445b1cca31a5bd60be20eeb389b0a3a9197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2024 18:22:27 +0100
+Subject: crypto: cavium - Fix an error handling path in cpt_ucode_load_fw()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 572b7cf08403b6c67dfe0dc3e0f2efb42443254f ]
+
+If do_cpt_init() fails, a previous dma_alloc_coherent() call needs to be
+undone.
+
+Add the needed dma_free_coherent() before returning.
+
+Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/cavium/cpt/cptpf_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
+index b3db27b142afb..52101755d0ddf 100644
+--- a/drivers/crypto/cavium/cpt/cptpf_main.c
++++ b/drivers/crypto/cavium/cpt/cptpf_main.c
+@@ -303,6 +303,8 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+       ret = do_cpt_init(cpt, mcode);
+       if (ret) {
++              dma_free_coherent(&cpt->pdev->dev, mcode->code_size,
++                                mcode->code, mcode->phys_base);
+               dev_err(dev, "do_cpt_init failed with ret: %d\n", ret);
+               goto fw_release;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch b/queue-5.10/crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch
new file mode 100644 (file)
index 0000000..005360f
--- /dev/null
@@ -0,0 +1,53 @@
+From 9ea13ad38db8e09529846893cc4c8e0a7dacb843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 10:23:10 -0600
+Subject: crypto: cavium - Fix the if condition to exit loop after timeout
+
+From: Everest K.C <everestkc@everestkc.com.np>
+
+[ Upstream commit 53d91ca76b6c426c546542a44c78507b42008c9e ]
+
+The while loop breaks in the first run because of incorrect
+if condition. It also causes the statements after the if to
+appear dead.
+Fix this by changing the condition from if(timeout--) to
+if(!timeout--).
+
+This bug was reported by Coverity Scan.
+Report:
+CID 1600859: (#1 of 1): Logically dead code (DEADCODE)
+dead_error_line: Execution cannot reach this statement: udelay(30UL);
+
+Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine")
+Signed-off-by: Everest K.C. <everestkc@everestkc.com.np>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/cavium/cpt/cptpf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
+index d9362199423f2..b3db27b142afb 100644
+--- a/drivers/crypto/cavium/cpt/cptpf_main.c
++++ b/drivers/crypto/cavium/cpt/cptpf_main.c
+@@ -45,7 +45,7 @@ static void cpt_disable_cores(struct cpt_device *cpt, u64 coremask,
+               dev_err(dev, "Cores still busy %llx", coremask);
+               grp = cpt_read_csr64(cpt->reg_base,
+                                    CPTX_PF_EXEC_BUSY(0));
+-              if (timeout--)
++              if (!timeout--)
+                       break;
+               udelay(CSR_DELAY);
+@@ -395,7 +395,7 @@ static void cpt_disable_all_cores(struct cpt_device *cpt)
+               dev_err(dev, "Cores still busy");
+               grp = cpt_read_csr64(cpt->reg_base,
+                                    CPTX_PF_EXEC_BUSY(0));
+-              if (timeout--)
++              if (!timeout--)
+                       break;
+               udelay(CSR_DELAY);
+-- 
+2.43.0
+
diff --git a/queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch b/queue-5.10/crypto-pcrypt-call-crypto-layer-directly-when-padata.patch
new file mode 100644 (file)
index 0000000..e579c04
--- /dev/null
@@ -0,0 +1,59 @@
+From eb17901b606aafb42c5f7364dbd3bf9660593790 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 02:09:35 +0000
+Subject: crypto: pcrypt - Call crypto layer directly when padata_do_parallel()
+ return -EBUSY
+
+From: Yi Yang <yiyang13@huawei.com>
+
+[ Upstream commit 662f2f13e66d3883b9238b0b96b17886179e60e2 ]
+
+Since commit 8f4f68e788c3 ("crypto: pcrypt - Fix hungtask for
+PADATA_RESET"), the pcrypt encryption and decryption operations return
+-EAGAIN when the CPU goes online or offline. In alg_test(), a WARN is
+generated when pcrypt_aead_decrypt() or pcrypt_aead_encrypt() returns
+-EAGAIN, the unnecessary panic will occur when panic_on_warn set 1.
+Fix this issue by calling crypto layer directly without parallelization
+in that case.
+
+Fixes: 8f4f68e788c3 ("crypto: pcrypt - Fix hungtask for PADATA_RESET")
+Signed-off-by: Yi Yang <yiyang13@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/pcrypt.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
+index 005a36cb21bc4..2d7f98709e97c 100644
+--- a/crypto/pcrypt.c
++++ b/crypto/pcrypt.c
+@@ -117,8 +117,10 @@ static int pcrypt_aead_encrypt(struct aead_request *req)
+       err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu);
+       if (!err)
+               return -EINPROGRESS;
+-      if (err == -EBUSY)
+-              return -EAGAIN;
++      if (err == -EBUSY) {
++              /* try non-parallel mode */
++              return crypto_aead_encrypt(creq);
++      }
+       return err;
+ }
+@@ -166,8 +168,10 @@ static int pcrypt_aead_decrypt(struct aead_request *req)
+       err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu);
+       if (!err)
+               return -EINPROGRESS;
+-      if (err == -EBUSY)
+-              return -EAGAIN;
++      if (err == -EBUSY) {
++              /* try non-parallel mode */
++              return crypto_aead_decrypt(creq);
++      }
+       return err;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/driver-core-introduce-device_find_any_child-helper.patch b/queue-5.10/driver-core-introduce-device_find_any_child-helper.patch
new file mode 100644 (file)
index 0000000..ab782fb
--- /dev/null
@@ -0,0 +1,70 @@
+From 8e6b2d291e48d0f3a16cbf609269e4306801a0f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 15:02:18 +0300
+Subject: driver core: Introduce device_find_any_child() helper
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 82b070beae1ef55b0049768c8dc91d87565bb191 ]
+
+There are several places in the kernel where this kind of functionality is
+being used. Provide a generic helper for such cases.
+
+Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20220610120219.18988-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 27aabf27fd01 ("Bluetooth: fix use-after-free in device_for_each_child()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/core.c    | 20 ++++++++++++++++++++
+ include/linux/device.h |  2 ++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index b13a60de5a863..82eb25ad1c72e 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3419,6 +3419,26 @@ struct device *device_find_child_by_name(struct device *parent,
+ }
+ EXPORT_SYMBOL_GPL(device_find_child_by_name);
++static int match_any(struct device *dev, void *unused)
++{
++      return 1;
++}
++
++/**
++ * device_find_any_child - device iterator for locating a child device, if any.
++ * @parent: parent struct device
++ *
++ * This is similar to the device_find_child() function above, but it
++ * returns a reference to a child device, if any.
++ *
++ * NOTE: you will need to drop the reference with put_device() after use.
++ */
++struct device *device_find_any_child(struct device *parent)
++{
++      return device_find_child(parent, NULL, match_any);
++}
++EXPORT_SYMBOL_GPL(device_find_any_child);
++
+ int __init devices_init(void)
+ {
+       devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 9c9ce573c737f..d615719b19d4d 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -834,6 +834,8 @@ struct device *device_find_child(struct device *dev, void *data,
+                                int (*match)(struct device *dev, void *data));
+ struct device *device_find_child_by_name(struct device *parent,
+                                        const char *name);
++struct device *device_find_any_child(struct device *parent);
++
+ int device_rename(struct device *dev, const char *new_name);
+ int device_move(struct device *dev, struct device *new_parent,
+               enum dpm_order dpm_order);
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch b/queue-5.10/drm-amdkfd-fix-wrong-usage-of-init_work.patch
new file mode 100644 (file)
index 0000000..2a4d7f9
--- /dev/null
@@ -0,0 +1,49 @@
+From f4ac7800da912b82f1c74fc029b29dfb471a13d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 09:35:41 +0800
+Subject: drm/amdkfd: Fix wrong usage of INIT_WORK()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 21cae8debc6a1d243f64fa82cd1b41cb612b5c61 ]
+
+In kfd_procfs_show(), the sdma_activity_work_handler is a local variable
+and the sdma_activity_work_handler.sdma_activity_work should initialize
+with INIT_WORK_ONSTACK() instead of INIT_WORK().
+
+Fixes: 32cb59f31362 ("drm/amdkfd: Track SDMA utilization per process")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Signed-off-by: Felix Kuehling <felix.kuehling@amd.com>
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 534f2dec6356f..184527afe2bd5 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -312,8 +312,8 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
+                                                             attr_sdma);
+               struct kfd_sdma_activity_handler_workarea sdma_activity_work_handler;
+-              INIT_WORK(&sdma_activity_work_handler.sdma_activity_work,
+-                                      kfd_sdma_activity_worker);
++              INIT_WORK_ONSTACK(&sdma_activity_work_handler.sdma_activity_work,
++                                kfd_sdma_activity_worker);
+               sdma_activity_work_handler.pdd = pdd;
+               sdma_activity_work_handler.sdma_activity_counter = 0;
+@@ -321,6 +321,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
+               schedule_work(&sdma_activity_work_handler.sdma_activity_work);
+               flush_work(&sdma_activity_work_handler.sdma_activity_work);
++              destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work);
+               return snprintf(buffer, PAGE_SIZE, "%llu\n",
+                               (sdma_activity_work_handler.sdma_activity_counter)/
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch b/queue-5.10/drm-bridge-tc358767-fix-link-properties-discovery.patch
new file mode 100644 (file)
index 0000000..4a34400
--- /dev/null
@@ -0,0 +1,60 @@
+From f8c00b1b345f50b43800fb1574c463f9d8eefded Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 13:27:23 +0200
+Subject: drm/bridge: tc358767: Fix link properties discovery
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 2d343723c7e1f9f6d64f721f07cfdfc2993758d1 ]
+
+When a display controller driver uses DRM_BRIDGE_ATTACH_NO_CONNECTOR,
+tc358767 will behave properly and skip the creation of the connector.
+
+However, tc_get_display_props(), which is used to find out about the DP
+monitor and link, is only called from two places: .atomic_enable() and
+tc_connector_get_modes(). The latter is only used when tc358767 creates
+its own connector, i.e. when DRM_BRIDGE_ATTACH_NO_CONNECTOR is _not_
+set.
+
+Thus, the driver never finds out the link properties before get_edid()
+is called. With num_lanes of 0 and link_rate of 0 there are not many
+valid modes...
+
+Fix this by adding tc_get_display_props() call at the beginning of
+get_edid(), so that we have up to date information before looking at the
+modes.
+
+Reported-by: Jan Kiszka <jan.kiszka@siemens.com>
+Closes: https://lore.kernel.org/all/24282420-b4dd-45b3-bb1c-fc37fe4a8205@siemens.com/
+Fixes: de5e6c027ae6 ("drm/bridge: tc358767: add drm_panel_bridge support")
+Reviewed-by: Aradhya Bhatia <a-bhatia1@ti.com>
+Tested-by: Jan Kiszka <jan.kiszka@siemens.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231108-tc358767-v2-2-25c5f70a2159@ideasonboard.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358767.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 9c905634fec79..1c7dafb5dc088 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1319,6 +1319,13 @@ static struct edid *tc_get_edid(struct drm_bridge *bridge,
+                               struct drm_connector *connector)
+ {
+       struct tc_data *tc = bridge_to_tc(bridge);
++      int ret;
++
++      ret = tc_get_display_props(tc);
++      if (ret < 0) {
++              dev_err(tc->dev, "failed to read display props: %d\n", ret);
++              return 0;
++      }
+       return drm_get_edid(connector, &tc->aux.ddc);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch b/queue-5.10/drm-etnaviv-dump-fix-sparse-warnings.patch
new file mode 100644 (file)
index 0000000..7db4954
--- /dev/null
@@ -0,0 +1,67 @@
+From 3f0abfdf1165257c70e5589cedf59c40034ca3ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Dec 2020 20:51:10 +0100
+Subject: drm/etnaviv: dump: fix sparse warnings
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 03a2753936e85beb8239fd20ae3fb2ce90209212 ]
+
+This patch fixes the following sparse warnings, by adding the missing endianess
+conversion functions.
+
+| etnaviv/etnaviv_dump.c:78:26: warning: restricted __le32 degrades to integer
+| etnaviv/etnaviv_dump.c:88:26: warning: incorrect type in assignment (different base types)
+| etnaviv/etnaviv_dump.c:88:26:    expected restricted __le32 [usertype] reg
+| etnaviv/etnaviv_dump.c:88:26:    got unsigned short const
+| etnaviv/etnaviv_dump.c:89:28: warning: incorrect type in assignment (different base types)
+| etnaviv/etnaviv_dump.c:89:28:    expected restricted __le32 [usertype] value
+| etnaviv/etnaviv_dump.c:89:28:    got unsigned int
+| etnaviv/etnaviv_dump.c:210:43: warning: incorrect type in assignment (different base types)
+| etnaviv/etnaviv_dump.c:210:43:    expected restricted __le32
+| etnaviv/etnaviv_dump.c:210:43:    got long
+
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Stable-dep-of: 37dc4737447a ("drm/etnaviv: hold GPU lock across perfmon sampling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_dump.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+index 7b57d01ba865b..0edcf8ceb4a78 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+@@ -75,7 +75,7 @@ static void etnaviv_core_dump_header(struct core_dump_iterator *iter,
+       hdr->file_size = cpu_to_le32(data_end - iter->data);
+       iter->hdr++;
+-      iter->data += hdr->file_size;
++      iter->data += le32_to_cpu(hdr->file_size);
+ }
+ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
+@@ -85,8 +85,8 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
+       unsigned int i;
+       for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
+-              reg->reg = etnaviv_dump_registers[i];
+-              reg->value = gpu_read(gpu, etnaviv_dump_registers[i]);
++              reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
++              reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
+       }
+       etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);
+@@ -207,7 +207,7 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)
+               if (!IS_ERR(pages)) {
+                       int j;
+-                      iter.hdr->data[0] = bomap - bomap_start;
++                      iter.hdr->data[0] = cpu_to_le32((bomap - bomap_start));
+                       for (j = 0; j < obj->base.size >> PAGE_SHIFT; j++)
+                               *bomap++ = cpu_to_le64(page_to_phys(*pages++));
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch b/queue-5.10/drm-etnaviv-fix-power-register-offset-on-gc300.patch
new file mode 100644 (file)
index 0000000..db7deae
--- /dev/null
@@ -0,0 +1,158 @@
+From 3d153227946c2bd68524b32bff9b1ca0dade1c5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Sep 2022 13:29:39 -0700
+Subject: drm/etnaviv: fix power register offset on GC300
+
+From: Doug Brown <doug@schmorgal.com>
+
+[ Upstream commit 61a6920bb604df3a0e389a2a9479e1e233e4461d ]
+
+Older GC300 revisions have their power registers at an offset of 0x200
+rather than 0x100. Add new gpu_read_power and gpu_write_power functions
+to encapsulate accesses to the power addresses and fix the addresses.
+
+Signed-off-by: Doug Brown <doug@schmorgal.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Stable-dep-of: 37dc4737447a ("drm/etnaviv: hold GPU lock across perfmon sampling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_dump.c |  7 ++++++-
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c  | 20 ++++++++++----------
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.h  | 21 +++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+index 0edcf8ceb4a78..898f84a0fc30c 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
+ {
+       struct etnaviv_dump_registers *reg = iter->data;
+       unsigned int i;
++      u32 read_addr;
+       for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
++              read_addr = etnaviv_dump_registers[i];
++              if (read_addr >= VIVS_PM_POWER_CONTROLS &&
++                  read_addr <= VIVS_PM_PULSE_EATER)
++                      read_addr = gpu_fix_power_address(gpu, read_addr);
+               reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
+-              reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
++              reg->value = cpu_to_le32(gpu_read(gpu, read_addr));
+       }
+       etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 5fb1d62ec5950..e944bcd30a2ba 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -578,7 +578,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
+       u32 pmc, ppc;
+       /* enable clock gating */
+-      ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
++      ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+       ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+       /* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */
+@@ -586,9 +586,9 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
+           gpu->identity.revision == 0x4302)
+               ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING;
+-      gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc);
++      gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc);
+-      pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
++      pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS);
+       /* Disable PA clock gating for GC400+ without bugfix except for GC420 */
+       if (gpu->identity.model >= chipModel_GC400 &&
+@@ -617,7 +617,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
+       pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
+       pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;
+-      gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
++      gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
+ }
+ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
+@@ -677,11 +677,11 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
+           (gpu->identity.features & chipFeatures_PIPE_3D))
+       {
+               /* Performance fix: disable internal DFS */
+-              pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER);
++              pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER);
+               pulse_eater |= BIT(18);
+       }
+-      gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
++      gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
+ }
+ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
+@@ -1275,9 +1275,9 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
+       u32 val;
+       /* disable clock gating */
+-      val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
++      val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+       val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+-      gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
++      gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
+       /* enable debug register */
+       val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+@@ -1308,9 +1308,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+       gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
+       /* enable clock gating */
+-      val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
++      val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+       val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+-      gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
++      gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
+ }
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+index 85eddd492774d..39f1e83d3cc7d 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+@@ -10,6 +10,7 @@
+ #include "etnaviv_gem.h"
+ #include "etnaviv_mmu.h"
+ #include "etnaviv_drv.h"
++#include "common.xml.h"
+ struct etnaviv_gem_submit;
+ struct etnaviv_vram_mapping;
+@@ -159,6 +160,26 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
+       return readl(gpu->mmio + reg);
+ }
++static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg)
++{
++      /* Power registers in GC300 < 2.0 are offset by 0x100 */
++      if (gpu->identity.model == chipModel_GC300 &&
++          gpu->identity.revision < 0x2000)
++              reg += 0x100;
++
++      return reg;
++}
++
++static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data)
++{
++      writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg));
++}
++
++static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg)
++{
++      return readl(gpu->mmio + gpu_fix_power_address(gpu, reg));
++}
++
+ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
+ int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch b/queue-5.10/drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch
new file mode 100644 (file)
index 0000000..c7818e5
--- /dev/null
@@ -0,0 +1,78 @@
+From 4c92ec6260e88843a574ee30da6be0ac269abde4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jul 2024 22:00:09 +0200
+Subject: drm/etnaviv: hold GPU lock across perfmon sampling
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 37dc4737447a7667f8e9ec790dac251da057eb27 ]
+
+The perfmon sampling mutates shared GPU state (e.g. VIVS_HI_CLOCK_CONTROL
+to select the pipe for the perf counter reads). To avoid clashing with
+other functions mutating the same state (e.g. etnaviv_gpu_update_clock)
+the perfmon sampling needs to hold the GPU lock.
+
+Fixes: 68dc0b295dcb ("drm/etnaviv: use 'sync points' for performance monitor requests")
+Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index e944bcd30a2ba..407a15e1469f2 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -1274,6 +1274,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
+ {
+       u32 val;
++      mutex_lock(&gpu->lock);
++
+       /* disable clock gating */
+       val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+       val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+@@ -1285,6 +1287,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
+       gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
+       sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
++
++      mutex_unlock(&gpu->lock);
+ }
+ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+@@ -1294,13 +1298,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+       unsigned int i;
+       u32 val;
+-      sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
+-
+-      for (i = 0; i < submit->nr_pmrs; i++) {
+-              const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
++      mutex_lock(&gpu->lock);
+-              *pmr->bo_vma = pmr->sequence;
+-      }
++      sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
+       /* disable debug register */
+       val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+@@ -1311,6 +1311,14 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
+       val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
+       val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
+       gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
++
++      mutex_unlock(&gpu->lock);
++
++      for (i = 0; i < submit->nr_pmrs; i++) {
++              const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
++
++              *pmr->bo_vma = pmr->sequence;
++      }
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch b/queue-5.10/drm-etnaviv-request-pages-from-dma32-zone-on-address.patch
new file mode 100644 (file)
index 0000000..8ecde16
--- /dev/null
@@ -0,0 +1,68 @@
+From 297b8b75d71e1b7227dbb31f39e46cfc87bff77c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Oct 2024 07:34:30 +0800
+Subject: drm/etnaviv: Request pages from DMA32 zone on addressing_limited
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+[ Upstream commit 13c96ac9a3f0f1c7ba1ff0656ea508e7fa065e7e ]
+
+Remove __GFP_HIGHMEM when requesting a page from DMA32 zone,
+and since all vivante GPUs in the system will share the same
+DMA constraints, move the check of whether to get a page from
+DMA32 to etnaviv_bind().
+
+Fixes: b72af445cd38 ("drm/etnaviv: request pages from DMA32 zone when needed")
+Suggested-by: Sui Jingfeng <sui.jingfeng@linux.dev>
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_drv.c | 10 ++++++++++
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c |  8 --------
+ 2 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+index edf9387069cdc..b7225d863f684 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+@@ -543,6 +543,16 @@ static int etnaviv_bind(struct device *dev)
+       priv->num_gpus = 0;
+       priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
++      /*
++       * If the GPU is part of a system with DMA addressing limitations,
++       * request pages for our SHM backend buffers from the DMA32 zone to
++       * hopefully avoid performance killing SWIOTLB bounce buffering.
++       */
++      if (dma_addressing_limited(dev)) {
++              priv->shm_gfp_mask |= GFP_DMA32;
++              priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
++      }
++
+       priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
+       if (IS_ERR(priv->cmdbuf_suballoc)) {
+               dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 8baa59fb32f2d..5fb1d62ec5950 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -780,14 +780,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
+       if (ret)
+               goto fail;
+-      /*
+-       * If the GPU is part of a system with DMA addressing limitations,
+-       * request pages for our SHM backend buffers from the DMA32 zone to
+-       * hopefully avoid performance killing SWIOTLB bounce buffering.
+-       */
+-      if (dma_addressing_limited(gpu->dev))
+-              priv->shm_gfp_mask |= GFP_DMA32;
+-
+       /* Create buffer: */
+       ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
+                                 PAGE_SIZE);
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch b/queue-5.10/drm-etnaviv-rework-linear-window-offset-calculation.patch
new file mode 100644 (file)
index 0000000..f071389
--- /dev/null
@@ -0,0 +1,113 @@
+From 17e1e5a0875e09716c7baa234c85d1c38f814510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 May 2021 12:24:22 +0200
+Subject: drm/etnaviv: rework linear window offset calculation
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 4bfdd2aa67fbfba09d7c32a4c7fd4c5eb1052bce ]
+
+The current calculation based on the required_dma mask can be significantly
+off, so that the linear window only overlaps a small part of the DRAM
+address space. This can lead to the command buffer being unmappable, which
+is obviously bad.
+
+Rework the linear window offset calculation to be based on the command buffer
+physical address, making sure that the command buffer is always mappable.
+
+Tested-by: Primoz Fiser <primoz.fiser@norik.com>
+Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Stable-dep-of: 13c96ac9a3f0 ("drm/etnaviv: Request pages from DMA32 zone on addressing_limited")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 52 +++++++++++++--------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index f3281d56b1d82..8baa59fb32f2d 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -27,10 +27,6 @@
+ #include "state_hi.xml.h"
+ #include "cmdstream.xml.h"
+-#ifndef PHYS_OFFSET
+-#define PHYS_OFFSET 0
+-#endif
+-
+ static const struct platform_device_id gpu_ids[] = {
+       { .name = "etnaviv-gpu,2d" },
+       { },
+@@ -741,6 +737,7 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
+ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
+ {
+       struct etnaviv_drm_private *priv = gpu->drm->dev_private;
++      dma_addr_t cmdbuf_paddr;
+       int ret, i;
+       ret = pm_runtime_get_sync(gpu->dev);
+@@ -783,28 +780,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
+       if (ret)
+               goto fail;
+-      /*
+-       * Set the GPU linear window to be at the end of the DMA window, where
+-       * the CMA area is likely to reside. This ensures that we are able to
+-       * map the command buffers while having the linear window overlap as
+-       * much RAM as possible, so we can optimize mappings for other buffers.
+-       *
+-       * For 3D cores only do this if MC2.0 is present, as with MC1.0 it leads
+-       * to different views of the memory on the individual engines.
+-       */
+-      if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
+-          (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
+-              u32 dma_mask = (u32)dma_get_required_mask(gpu->dev);
+-              if (dma_mask < PHYS_OFFSET + SZ_2G)
+-                      priv->mmu_global->memory_base = PHYS_OFFSET;
+-              else
+-                      priv->mmu_global->memory_base = dma_mask - SZ_2G + 1;
+-      } else if (PHYS_OFFSET >= SZ_2G) {
+-              dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n");
+-              priv->mmu_global->memory_base = PHYS_OFFSET;
+-              gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
+-      }
+-
+       /*
+        * If the GPU is part of a system with DMA addressing limitations,
+        * request pages for our SHM backend buffers from the DMA32 zone to
+@@ -821,6 +796,31 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
+               goto fail;
+       }
++      /*
++       * Set the GPU linear window to cover the cmdbuf region, as the GPU
++       * won't be able to start execution otherwise. The alignment to 128M is
++       * chosen arbitrarily but helps in debugging, as the MMU offset
++       * calculations are much more straight forward this way.
++       *
++       * On MC1.0 cores the linear window offset is ignored by the TS engine,
++       * leading to inconsistent memory views. Avoid using the offset on those
++       * cores if possible, otherwise disable the TS feature.
++       */
++      cmdbuf_paddr = ALIGN_DOWN(etnaviv_cmdbuf_get_pa(&gpu->buffer), SZ_128M);
++
++      if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
++          (gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
++              if (cmdbuf_paddr >= SZ_2G)
++                      priv->mmu_global->memory_base = SZ_2G;
++              else
++                      priv->mmu_global->memory_base = cmdbuf_paddr;
++      } else if (cmdbuf_paddr + SZ_128M >= SZ_2G) {
++              dev_info(gpu->dev,
++                       "Need to move linear window on MC1.0, disabling TS\n");
++              gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
++              priv->mmu_global->memory_base = SZ_2G;
++      }
++
+       /* Setup event management */
+       spin_lock_init(&gpu->event_spinlock);
+       init_completion(&gpu->event_free);
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch b/queue-5.10/drm-fsl-dcu-convert-to-linux-irq-interfaces.patch
new file mode 100644 (file)
index 0000000..9567615
--- /dev/null
@@ -0,0 +1,167 @@
+From 5a610c95ac9f2b72671a2c1f8f270081f4a416bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Aug 2021 11:06:54 +0200
+Subject: drm/fsl-dcu: Convert to Linux IRQ interfaces
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 03ac16e584e496230903ba20f2b4bbfd942a16b4 ]
+
+Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
+IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
+don't benefit from using it. DRM IRQ callbacks are now being called
+directly or inlined.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210803090704.32152-5-tzimmermann@suse.de
+Stable-dep-of: ffcde9e44d3e ("drm: fsl-dcu: enable PIXCLK on LS1021A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 78 +++++++++++++----------
+ 1 file changed, 46 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+index abbc1ddbf27f0..11b4a81bacc68 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -23,7 +23,6 @@
+ #include <drm/drm_fb_cma_helper.h>
+ #include <drm/drm_fb_helper.h>
+ #include <drm/drm_gem_cma_helper.h>
+-#include <drm/drm_irq.h>
+ #include <drm/drm_modeset_helper.h>
+ #include <drm/drm_probe_helper.h>
+ #include <drm/drm_vblank.h>
+@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = {
+       .volatile_reg = fsl_dcu_drm_is_volatile_reg,
+ };
+-static void fsl_dcu_irq_uninstall(struct drm_device *dev)
++static void fsl_dcu_irq_reset(struct drm_device *dev)
+ {
+       struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+       regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0);
+ }
++static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
++{
++      struct drm_device *dev = arg;
++      struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
++      unsigned int int_status;
++      int ret;
++
++      ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
++      if (ret) {
++              dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
++              return IRQ_NONE;
++      }
++
++      if (int_status & DCU_INT_STATUS_VBLANK)
++              drm_handle_vblank(dev, 0);
++
++      regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
++
++      return IRQ_HANDLED;
++}
++
++static int fsl_dcu_irq_install(struct drm_device *dev, unsigned int irq)
++{
++      if (irq == IRQ_NOTCONNECTED)
++              return -ENOTCONN;
++
++      fsl_dcu_irq_reset(dev);
++
++      return request_irq(irq, fsl_dcu_drm_irq, 0, dev->driver->name, dev);
++}
++
++static void fsl_dcu_irq_uninstall(struct drm_device *dev)
++{
++      struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
++
++      fsl_dcu_irq_reset(dev);
++      free_irq(fsl_dev->irq, dev);
++}
++
+ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+ {
+       struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+       ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to initialize vblank\n");
+-              goto done;
++              goto done_vblank;
+       }
+-      ret = drm_irq_install(dev, fsl_dev->irq);
++      ret = fsl_dcu_irq_install(dev, fsl_dev->irq);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to install IRQ handler\n");
+-              goto done;
++              goto done_irq;
+       }
+       if (legacyfb_depth != 16 && legacyfb_depth != 24 &&
+@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+       }
+       return 0;
+-done:
++done_irq:
+       drm_kms_helper_poll_fini(dev);
+       drm_mode_config_cleanup(dev);
+-      drm_irq_uninstall(dev);
++done_vblank:
+       dev->dev_private = NULL;
+       return ret;
+@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev)
+       drm_kms_helper_poll_fini(dev);
+       drm_mode_config_cleanup(dev);
+-      drm_irq_uninstall(dev);
++      fsl_dcu_irq_uninstall(dev);
+       dev->dev_private = NULL;
+ }
+-static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
+-{
+-      struct drm_device *dev = arg;
+-      struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+-      unsigned int int_status;
+-      int ret;
+-
+-      ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
+-      if (ret) {
+-              dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
+-              return IRQ_NONE;
+-      }
+-
+-      if (int_status & DCU_INT_STATUS_VBLANK)
+-              drm_handle_vblank(dev, 0);
+-
+-      regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
+-
+-      return IRQ_HANDLED;
+-}
+-
+ DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops);
+ static struct drm_driver fsl_dcu_drm_driver = {
+       .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+       .load                   = fsl_dcu_load,
+       .unload                 = fsl_dcu_unload,
+-      .irq_handler            = fsl_dcu_drm_irq,
+-      .irq_preinstall         = fsl_dcu_irq_uninstall,
+-      .irq_uninstall          = fsl_dcu_irq_uninstall,
+       DRM_GEM_CMA_DRIVER_OPS,
+       .fops                   = &fsl_dcu_drm_fops,
+       .name                   = "fsl-dcu-drm",
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch b/queue-5.10/drm-fsl-dcu-enable-pixclk-on-ls1021a.patch
new file mode 100644 (file)
index 0000000..e71c9f8
--- /dev/null
@@ -0,0 +1,88 @@
+From 1432017045e2b47abbe2c4f839192c1ce52d84ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Sep 2024 07:55:51 +0200
+Subject: drm: fsl-dcu: enable PIXCLK on LS1021A
+
+From: Matthias Schiffer <matthias.schiffer@tq-group.com>
+
+[ Upstream commit ffcde9e44d3e18fde3d18bfff8d9318935413bfd ]
+
+The PIXCLK needs to be enabled in SCFG before accessing certain DCU
+registers, or the access will hang. For simplicity, the PIXCLK is enabled
+unconditionally, resulting in increased power consumption.
+
+Signed-off-by: Matthias Schiffer <matthias.schiffer@tq-group.com>
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Fixes: 109eee2f2a18 ("drm/layerscape: Add Freescale DCU DRM driver")
+Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240926055552.1632448-2-alexander.stein@ew.tq-group.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/fsl-dcu/Kconfig           |  1 +
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 15 +++++++++++++++
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h |  3 +++
+ 3 files changed, 19 insertions(+)
+
+diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig
+index d7dd8ba90e3af..9e5a35e7c00cc 100644
+--- a/drivers/gpu/drm/fsl-dcu/Kconfig
++++ b/drivers/gpu/drm/fsl-dcu/Kconfig
+@@ -8,6 +8,7 @@ config DRM_FSL_DCU
+       select DRM_PANEL
+       select REGMAP_MMIO
+       select VIDEOMODE_HELPERS
++      select MFD_SYSCON if SOC_LS1021A
+       help
+         Choose this option if you have an Freescale DCU chipset.
+         If M is selected the module will be called fsl-dcu-drm.
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+index 11b4a81bacc68..1065249807323 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -100,6 +100,7 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+ {
+       struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
++      struct regmap *scfg;
+       int ret;
+       ret = fsl_dcu_drm_modeset_init(fsl_dev);
+@@ -108,6 +109,20 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
+               return ret;
+       }
++      scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
++      if (PTR_ERR(scfg) != -ENODEV) {
++              /*
++               * For simplicity, enable the PIXCLK unconditionally,
++               * resulting in increased power consumption. Disabling
++               * the clock in PM or on unload could be implemented as
++               * a future improvement.
++               */
++              ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN,
++                                       SCFG_PIXCLKCR_PXCEN);
++              if (ret < 0)
++                      return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n");
++      }
++
+       ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to initialize vblank\n");
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+index e2049a0e8a92a..566396013c04a 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+@@ -160,6 +160,9 @@
+ #define FSL_DCU_ARGB4444              12
+ #define FSL_DCU_YUV422                        14
++#define SCFG_PIXCLKCR                 0x28
++#define SCFG_PIXCLKCR_PXCEN           BIT(31)
++
+ #define VF610_LAYER_REG_NUM           9
+ #define LS1021A_LAYER_REG_NUM         10
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch
new file mode 100644 (file)
index 0000000..8cac92f
--- /dev/null
@@ -0,0 +1,49 @@
+From dbeaeb14b5b5d6ffb53eb48382ef5344c29c6595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 16:30:16 +0800
+Subject: drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 1af01e14db7e0b45ae502d822776a58c86688763 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-2-ruanjinjie@huawei.com
+[DB: fixed the subject]
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/dcss/dcss-crtc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
+index 36abff0890b28..ec041fcd07d02 100644
+--- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c
++++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c
+@@ -201,15 +201,13 @@ int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm)
+       if (crtc->irq < 0)
+               return crtc->irq;
+-      ret = request_irq(crtc->irq, dcss_crtc_irq_handler,
+-                        0, "dcss_drm", crtc);
++      ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN,
++                        "dcss_drm", crtc);
+       if (ret) {
+               dev_err(dcss->dev, "irq request failed with %d.\n", ret);
+               return ret;
+       }
+-      disable_irq(crtc->irq);
+-
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch
new file mode 100644 (file)
index 0000000..21eb155
--- /dev/null
@@ -0,0 +1,48 @@
+From 680e12efd11c12c763df00eea3a175bc199e7a27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 16:30:18 +0800
+Subject: drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 40004709a3d3b07041a473a163ca911ef04ab8bd ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 47b1be5c0f4e ("staging: imx/drm: request irq only after adding the crtc")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240912083020.3720233-4-ruanjinjie@huawei.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/ipuv3-crtc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
+index fd9d8e51837fa..d6e5821c14c1d 100644
+--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
+@@ -406,14 +406,12 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
+       }
+       ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
+-      ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+-                      "imx_drm", ipu_crtc);
++      ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler,
++                             IRQF_NO_AUTOEN, "imx_drm", ipu_crtc);
+       if (ret < 0) {
+               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+               goto err_put_plane1_res;
+       }
+-      /* Only enable IRQ when we actually need it to trigger work. */
+-      disable_irq(ipu_crtc->irq);
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch b/queue-5.10/drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch
new file mode 100644 (file)
index 0000000..3ebbd90
--- /dev/null
@@ -0,0 +1,52 @@
+From d33ffbf39aed3c6e043ff9b318712ef1f2ab462c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 18:46:40 +0300
+Subject: drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 53bd7c1c0077db533472ae32799157758302ef48 ]
+
+The INTERVAL_TREE_DEFINE() uncoditionally provides a bunch of helper
+functions which in some cases may be not used. This, in particular,
+prevents kernel builds with clang, `make W=1` and CONFIG_WERROR=y:
+
+.../drm/drm_mm.c:152:1: error: unused function 'drm_mm_interval_tree_insert' [-Werror,-Wunused-function]
+  152 | INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
+      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  153 |                      u64, __subtree_last,
+      |                      ~~~~~~~~~~~~~~~~~~~~
+  154 |                      START, LAST, static inline, drm_mm_interval_tree)
+      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fix this by marking drm_mm_interval_tree*() functions with __maybe_unused.
+
+See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static
+inline functions for W=1 build").
+
+Fixes: 202b52b7fbf7 ("drm: Track drm_mm nodes with an interval tree")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240829154640.1120050-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
+index a4a04d2461353..7c25a8e38830b 100644
+--- a/drivers/gpu/drm/drm_mm.c
++++ b/drivers/gpu/drm/drm_mm.c
+@@ -154,7 +154,7 @@ static void show_leaks(struct drm_mm *mm) { }
+ INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
+                    u64, __subtree_last,
+-                   START, LAST, static inline, drm_mm_interval_tree)
++                   START, LAST, static inline __maybe_unused, drm_mm_interval_tree)
+ struct drm_mm_node *
+ __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch b/queue-5.10/drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch
new file mode 100644 (file)
index 0000000..9ea75e9
--- /dev/null
@@ -0,0 +1,47 @@
+From 8cd3998b71d5409d35b83b6d16870d6e5107e0b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 16:30:20 +0800
+Subject: drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 394679f322649d06fea3c646ba65f5a0887f52c3 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Patchwork: https://patchwork.freedesktop.org/patch/614075/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 8d78d95d29fcd..655938df45313 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -1407,15 +1407,13 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
+       irq = platform_get_irq_byname(pdev, name);
+-      ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);
++      ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu);
+       if (ret) {
+               DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",
+                             name, ret);
+               return ret;
+       }
+-      disable_irq(irq);
+-
+       return irq;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch b/queue-5.10/drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch
new file mode 100644 (file)
index 0000000..7c00d01
--- /dev/null
@@ -0,0 +1,46 @@
+From fdc6545fe302253a185a7281502928456ab1e3a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 14:42:10 -0500
+Subject: drm/msm/dpu: cast crtc_clk calculation to u64 in
+ _dpu_core_perf_calc_clk()
+
+From: Zichen Xie <zichenxie0106@gmail.com>
+
+[ Upstream commit 20c7b42d9dbd048019bfe0af39229e3014007a98 ]
+
+There may be a potential integer overflow issue in
+_dpu_core_perf_calc_clk(). crtc_clk is defined as u64, while
+mode->vtotal, mode->hdisplay, and drm_mode_vrefresh(mode) are defined as
+a smaller data type. The result of the calculation will be limited to
+"int" in this case without correct casting. In screen with high
+resolution and high refresh rate, integer overflow may happen.
+So, we recommend adding an extra cast to prevent potential
+integer overflow.
+
+Fixes: c33b7c0389e1 ("drm/msm/dpu: add support for clk and bw scaling for display")
+Signed-off-by: Zichen Xie <zichenxie0106@gmail.com>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/622206/
+Link: https://lore.kernel.org/r/20241029194209.23684-1-zichenxie0106@gmail.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+index 37c8270681c23..733941fb4078d 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+@@ -79,7 +79,7 @@ static u64 _dpu_core_perf_calc_clk(struct dpu_kms *kms,
+       mode = &state->adjusted_mode;
+-      crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
++      crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
+       drm_atomic_crtc_for_each_plane(plane, crtc) {
+               pstate = to_dpu_plane_state(plane->state);
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch b/queue-5.10/drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch
new file mode 100644 (file)
index 0000000..fe114d0
--- /dev/null
@@ -0,0 +1,76 @@
+From af145bdc3e4757c39d92a3b813aa976535a47d23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 16:50:29 +0300
+Subject: drm/omap: Fix locking in omap_gem_new_dmabuf()
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit e6a1c4037227539373c8cf484ace83833e2ad6a2 ]
+
+omap_gem_new_dmabuf() creates the new gem object, and then takes and
+holds the omap_obj->lock for the rest of the function. This has two
+issues:
+
+- omap_gem_free_object(), which is called in the error paths, also takes
+  the same lock, leading to deadlock
+- Even if the above wouldn't happen, in the error cases
+  omap_gem_new_dmabuf() still unlocks omap_obj->lock, even after the
+  omap_obj has already been freed.
+
+Furthermore, I don't think there's any reason to take the lock at all,
+as the object was just created and not yet shared with anyone else.
+
+To fix all this, drop taking the lock.
+
+Fixes: 3cbd0c587b12 ("drm/omap: gem: Replace struct_mutex usage with omap_obj private lock")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/all/511b99d7-aade-4f92-bd3e-63163a13d617@stanley.mountain/
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240806-omapdrm-misc-fixes-v1-3-15d31aea0831@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/omapdrm/omap_gem.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
+index f67f223c6479f..662062cdba9d4 100644
+--- a/drivers/gpu/drm/omapdrm/omap_gem.c
++++ b/drivers/gpu/drm/omapdrm/omap_gem.c
+@@ -1289,8 +1289,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
+       omap_obj = to_omap_bo(obj);
+-      mutex_lock(&omap_obj->lock);
+-
+       omap_obj->sgt = sgt;
+       if (sgt->orig_nents == 1) {
+@@ -1305,8 +1303,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
+               pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
+               if (!pages) {
+                       omap_gem_free_object(obj);
+-                      obj = ERR_PTR(-ENOMEM);
+-                      goto done;
++                      return ERR_PTR(-ENOMEM);
+               }
+               omap_obj->pages = pages;
+@@ -1314,13 +1311,10 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
+                                                      npages);
+               if (ret) {
+                       omap_gem_free_object(obj);
+-                      obj = ERR_PTR(-ENOMEM);
+-                      goto done;
++                      return ERR_PTR(-ENOMEM);
+               }
+       }
+-done:
+-      mutex_unlock(&omap_obj->lock);
+       return obj;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch b/queue-5.10/drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch
new file mode 100644 (file)
index 0000000..58c4b04
--- /dev/null
@@ -0,0 +1,35 @@
+From 38437b5d508313856d7cfa6d4b36551758d26c96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 15:00:07 +0100
+Subject: drm/panfrost: Remove unused id_mask from struct panfrost_model
+
+From: Steven Price <steven.price@arm.com>
+
+[ Upstream commit 581d1f8248550f2b67847e6d84f29fbe3751ea0a ]
+
+The id_mask field of struct panfrost_model has never been used.
+
+Fixes: f3ba91228e8e ("drm/panfrost: Add initial panfrost driver")
+Signed-off-by: Steven Price <steven.price@arm.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241025140008.385081-1-steven.price@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panfrost/panfrost_gpu.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+index 107ad2d764ec0..bff8cddfc7698 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
+@@ -158,7 +158,6 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev)
+ struct panfrost_model {
+       const char *name;
+       u32 id;
+-      u32 id_mask;
+       u64 features;
+       u64 issues;
+       struct {
+-- 
+2.43.0
+
diff --git a/queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch b/queue-5.10/drm-v3d-address-race-condition-in-mmu-flush.patch
new file mode 100644 (file)
index 0000000..ed0f459
--- /dev/null
@@ -0,0 +1,80 @@
+From 0c9c1aa6c3f618817425ea951dd93d853996d3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 10:55:05 -0300
+Subject: drm/v3d: Address race-condition in MMU flush
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit cf1becb7f996a0a23ea2c270cf6bb0911ec3ca1a ]
+
+We must first flush the MMU cache and then, flush the TLB, not the other
+way around. Currently, we can see a race condition between the MMU cache
+and the TLB when running multiple rendering processes at the same time.
+This is evidenced by MMU errors triggered by the IRQ.
+
+Fix the MMU flush order by flushing the MMU cache and then the TLB.
+Also, in order to address the race condition, wait for the MMU cache flush
+to finish before starting the TLB flush.
+
+Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+")
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240923141348.2422499-2-mcanal@igalia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/v3d/v3d_mmu.c | 29 ++++++++++-------------------
+ 1 file changed, 10 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/v3d/v3d_mmu.c b/drivers/gpu/drm/v3d/v3d_mmu.c
+index 5a453532901f1..166d4a88daee5 100644
+--- a/drivers/gpu/drm/v3d/v3d_mmu.c
++++ b/drivers/gpu/drm/v3d/v3d_mmu.c
+@@ -34,32 +34,23 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d)
+ {
+       int ret;
+-      /* Make sure that another flush isn't already running when we
+-       * start this one.
+-       */
+-      ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
+-                       V3D_MMU_CTL_TLB_CLEARING), 100);
+-      if (ret)
+-              dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n");
+-
+-      V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
+-                V3D_MMU_CTL_TLB_CLEAR);
+-
+-      V3D_WRITE(V3D_MMUC_CONTROL,
+-                V3D_MMUC_CONTROL_FLUSH |
++      V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH |
+                 V3D_MMUC_CONTROL_ENABLE);
+-      ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
+-                       V3D_MMU_CTL_TLB_CLEARING), 100);
++      ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
++                       V3D_MMUC_CONTROL_FLUSHING), 100);
+       if (ret) {
+-              dev_err(v3d->drm.dev, "TLB clear wait idle failed\n");
++              dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
+               return ret;
+       }
+-      ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
+-                       V3D_MMUC_CONTROL_FLUSHING), 100);
++      V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
++                V3D_MMU_CTL_TLB_CLEAR);
++
++      ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
++                       V3D_MMU_CTL_TLB_CLEARING), 100);
+       if (ret)
+-              dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
++              dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n");
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch b/queue-5.10/dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch
new file mode 100644 (file)
index 0000000..9e0b54c
--- /dev/null
@@ -0,0 +1,127 @@
+From a58d28eced75d00fdad90074a9565b17aeded5d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Oct 2020 17:34:20 +0300
+Subject: dt-bindings: clock: adi,axi-clkgen: convert old binding to yaml
+ format
+
+From: Alexandru Ardelean <alexandru.ardelean@analog.com>
+
+[ Upstream commit bd91abb218e0ac4a7402d6c25d383e2a706bb511 ]
+
+This change converts the old binding for the AXI clkgen driver to a yaml
+format.
+
+As maintainers, added:
+ - Lars-Peter Clausen <lars@metafoo.de> - as original author of driver &
+   binding
+ - Michael Hennerich <michael.hennerich@analog.com> - as supporter of
+   Analog Devices drivers
+
+Acked-by: Michael Hennerich <michael.hennerich@analog.com>
+Acked-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
+Link: https://lore.kernel.org/r/20201013143421.84188-1-alexandru.ardelean@analog.com
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 47f3f5a82a31 ("dt-bindings: clock: axi-clkgen: include AXI clk")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/clock/adi,axi-clkgen.yaml        | 53 +++++++++++++++++++
+ .../devicetree/bindings/clock/axi-clkgen.txt  | 25 ---------
+ 2 files changed, 53 insertions(+), 25 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+ delete mode 100644 Documentation/devicetree/bindings/clock/axi-clkgen.txt
+
+diff --git a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+new file mode 100644
+index 0000000000000..0d06387184d68
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+@@ -0,0 +1,53 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/adi,axi-clkgen.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Binding for Analog Devices AXI clkgen pcore clock generator
++
++maintainers:
++  - Lars-Peter Clausen <lars@metafoo.de>
++  - Michael Hennerich <michael.hennerich@analog.com>
++
++description: |
++  The axi_clkgen IP core is a software programmable clock generator,
++  that can be synthesized on various FPGA platforms.
++
++  Link: https://wiki.analog.com/resources/fpga/docs/axi_clkgen
++
++properties:
++  compatible:
++    enum:
++      - adi,axi-clkgen-2.00.a
++
++  clocks:
++    description:
++      Specifies the reference clock(s) from which the output frequency is
++      derived. This must either reference one clock if only the first clock
++      input is connected or two if both clock inputs are connected.
++    minItems: 1
++    maxItems: 2
++
++  '#clock-cells':
++    const: 0
++
++  reg:
++    maxItems: 1
++
++required:
++  - compatible
++  - reg
++  - clocks
++  - '#clock-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    clock-controller@ff000000 {
++      compatible = "adi,axi-clkgen-2.00.a";
++      #clock-cells = <0>;
++      reg = <0xff000000 0x1000>;
++      clocks = <&osc 1>;
++    };
+diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt
+deleted file mode 100644
+index aca94fe9416f0..0000000000000
+--- a/Documentation/devicetree/bindings/clock/axi-clkgen.txt
++++ /dev/null
+@@ -1,25 +0,0 @@
+-Binding for the axi-clkgen clock generator
+-
+-This binding uses the common clock binding[1].
+-
+-[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+-
+-Required properties:
+-- compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a".
+-- #clock-cells : from common clock binding; Should always be set to 0.
+-- reg : Address and length of the axi-clkgen register set.
+-- clocks : Phandle and clock specifier for the parent clock(s). This must
+-      either reference one clock if only the first clock input is connected or two
+-      if both clock inputs are connected. For the later case the clock connected
+-      to the first input must be specified first.
+-
+-Optional properties:
+-- clock-output-names : From common clock binding.
+-
+-Example:
+-      clock@ff000000 {
+-              compatible = "adi,axi-clkgen";
+-              #clock-cells = <0>;
+-              reg = <0xff000000 0x1000>;
+-              clocks = <&osc 1>;
+-      };
+-- 
+2.43.0
+
diff --git a/queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch b/queue-5.10/dt-bindings-clock-axi-clkgen-include-axi-clk.patch
new file mode 100644 (file)
index 0000000..f8396b6
--- /dev/null
@@ -0,0 +1,72 @@
+From a19bac5e58672c5a27cd61114e4b8633bcbfa62d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 14:59:41 +0100
+Subject: dt-bindings: clock: axi-clkgen: include AXI clk
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 47f3f5a82a31527e027929c5cec3dd1ef5ef30f5 ]
+
+In order to access the registers of the HW, we need to make sure that
+the AXI bus clock is enabled. Hence let's increase the number of clocks
+by one and add clock-names to differentiate between parent clocks and
+the bus clock.
+
+Fixes: 0e646c52cf0e ("clk: Add axi-clkgen driver")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20241029-axi-clkgen-fix-axiclk-v2-1-bc5e0733ad76@analog.com
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bindings/clock/adi,axi-clkgen.yaml        | 22 +++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+index 0d06387184d68..bb2eec3021a09 100644
+--- a/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
++++ b/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+@@ -25,9 +25,21 @@ properties:
+     description:
+       Specifies the reference clock(s) from which the output frequency is
+       derived. This must either reference one clock if only the first clock
+-      input is connected or two if both clock inputs are connected.
+-    minItems: 1
+-    maxItems: 2
++      input is connected or two if both clock inputs are connected. The last
++      clock is the AXI bus clock that needs to be enabled so we can access the
++      core registers.
++    minItems: 2
++    maxItems: 3
++
++  clock-names:
++    oneOf:
++      - items:
++          - const: clkin1
++          - const: s_axi_aclk
++      - items:
++          - const: clkin1
++          - const: clkin2
++          - const: s_axi_aclk
+   '#clock-cells':
+     const: 0
+@@ -39,6 +51,7 @@ required:
+   - compatible
+   - reg
+   - clocks
++  - clock-names
+   - '#clock-cells'
+ additionalProperties: false
+@@ -49,5 +62,6 @@ examples:
+       compatible = "adi,axi-clkgen-2.00.a";
+       #clock-cells = <0>;
+       reg = <0xff000000 0x1000>;
+-      clocks = <&osc 1>;
++      clocks = <&osc 1>, <&clkc 15>;
++      clock-names = "clkin1", "s_axi_aclk";
+     };
+-- 
+2.43.0
+
diff --git a/queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch b/queue-5.10/dt-bindings-vendor-prefixes-add-neofidelity-inc.patch
new file mode 100644 (file)
index 0000000..82f42ad
--- /dev/null
@@ -0,0 +1,36 @@
+From 255dee8d0c4884ee531c6323605ea8389ac4cdb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Sep 2024 17:52:39 +0300
+Subject: dt-bindings: vendor-prefixes: Add NeoFidelity, Inc
+
+From: Igor Prusov <ivprusov@salutedevices.com>
+
+[ Upstream commit 5d9e6d6fc1b98c8c22d110ee931b3b233d43cd13 ]
+
+Add vendor prefix for NeoFidelity, Inc
+
+Signed-off-by: Igor Prusov <ivprusov@salutedevices.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://patch.msgid.link/20240925-ntp-amps-8918-8835-v3-1-e2459a8191a6@salutedevices.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+index 2735be1a84709..e04be09dd0291 100644
+--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
+@@ -718,6 +718,8 @@ patternProperties:
+     description: National Semiconductor
+   "^nec,.*":
+     description: NEC LCD Technologies, Ltd.
++  "^neofidelity,.*":
++    description: Neofidelity Inc.
+   "^neonode,.*":
+     description: Neonode Inc.
+   "^netgear,.*":
+-- 
+2.43.0
+
diff --git a/queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch b/queue-5.10/edac-bluefield-fix-potential-integer-overflow.patch
new file mode 100644 (file)
index 0000000..e759abd
--- /dev/null
@@ -0,0 +1,43 @@
+From 2cb2d90c2a50c56b9408338933baad9d002c9fb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 11:10:56 -0400
+Subject: EDAC/bluefield: Fix potential integer overflow
+
+From: David Thompson <davthompson@nvidia.com>
+
+[ Upstream commit 1fe774a93b46bb029b8f6fa9d1f25affa53f06c6 ]
+
+The 64-bit argument for the "get DIMM info" SMC call consists of mem_ctrl_idx
+left-shifted 16 bits and OR-ed with DIMM index.  With mem_ctrl_idx defined as
+32-bits wide the left-shift operation truncates the upper 16 bits of
+information during the calculation of the SMC argument.
+
+The mem_ctrl_idx stack variable must be defined as 64-bits wide to prevent any
+potential integer overflow, i.e. loss of data from upper 16 bits.
+
+Fixes: 82413e562ea6 ("EDAC, mellanox: Add ECC support for BlueField DDR4")
+Signed-off-by: David Thompson <davthompson@nvidia.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Shravan Kumar Ramani <shravankr@nvidia.com>
+Link: https://lore.kernel.org/r/20240930151056.10158-1-davthompson@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/bluefield_edac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
+index e4736eb37bfb3..0ef0489827682 100644
+--- a/drivers/edac/bluefield_edac.c
++++ b/drivers/edac/bluefield_edac.c
+@@ -180,7 +180,7 @@ static void bluefield_edac_check(struct mem_ctl_info *mci)
+ static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
+ {
+       struct bluefield_edac_priv *priv = mci->pvt_info;
+-      int mem_ctrl_idx = mci->mc_idx;
++      u64 mem_ctrl_idx = mci->mc_idx;
+       struct dimm_info *dimm;
+       u64 smc_info, smc_arg;
+       int is_empty = 1, i;
+-- 
+2.43.0
+
diff --git a/queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch b/queue-5.10/edac-fsl_ddr-fix-bad-bit-shift-operations.patch
new file mode 100644 (file)
index 0000000..40f0ff0
--- /dev/null
@@ -0,0 +1,75 @@
+From b5f077f9d8c4678e5969507687d5f564223d7319 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 16:31:11 -0400
+Subject: EDAC/fsl_ddr: Fix bad bit shift operations
+
+From: Priyanka Singh <priyanka.singh@nxp.com>
+
+[ Upstream commit 9ec22ac4fe766c6abba845290d5139a3fbe0153b ]
+
+Fix undefined behavior caused by left-shifting a negative value in the
+expression:
+
+    cap_high ^ (1 << (bad_data_bit - 32))
+
+The variable bad_data_bit ranges from 0 to 63. When it is less than 32,
+bad_data_bit - 32 becomes negative, and left-shifting by a negative
+value in C is undefined behavior.
+
+Fix this by combining cap_high and cap_low into a 64-bit variable.
+
+  [ bp: Massage commit message, simplify error bits handling. ]
+
+Fixes: ea2eb9a8b620 ("EDAC, fsl-ddr: Separate FSL DDR driver from MPC85xx")
+Signed-off-by: Priyanka Singh <priyanka.singh@nxp.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20241016-imx95_edac-v3-3-86ae6fc2756a@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/fsl_ddr_edac.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c
+index 6d8ea226010d2..61e59341a41f9 100644
+--- a/drivers/edac/fsl_ddr_edac.c
++++ b/drivers/edac/fsl_ddr_edac.c
+@@ -331,21 +331,25 @@ static void fsl_mc_check(struct mem_ctl_info *mci)
+        * TODO: Add support for 32-bit wide buses
+        */
+       if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
++              u64 cap = (u64)cap_high << 32 | cap_low;
++              u32 s = syndrome;
++
+               sbe_ecc_decode(cap_high, cap_low, syndrome,
+                               &bad_data_bit, &bad_ecc_bit);
+-              if (bad_data_bit != -1)
+-                      fsl_mc_printk(mci, KERN_ERR,
+-                              "Faulty Data bit: %d\n", bad_data_bit);
+-              if (bad_ecc_bit != -1)
+-                      fsl_mc_printk(mci, KERN_ERR,
+-                              "Faulty ECC bit: %d\n", bad_ecc_bit);
++              if (bad_data_bit >= 0) {
++                      fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit);
++                      cap ^= 1ULL << bad_data_bit;
++              }
++
++              if (bad_ecc_bit >= 0) {
++                      fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit);
++                      s ^= 1 << bad_ecc_bit;
++              }
+               fsl_mc_printk(mci, KERN_ERR,
+                       "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
+-                      cap_high ^ (1 << (bad_data_bit - 32)),
+-                      cap_low ^ (1 << bad_data_bit),
+-                      syndrome ^ (1 << bad_ecc_bit));
++                      upper_32_bits(cap), lower_32_bits(cap), s);
+       }
+       fsl_mc_printk(mci, KERN_ERR,
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch b/queue-5.10/f2fs-avoid-using-native-allocate_segment_by_default.patch
new file mode 100644 (file)
index 0000000..afc3400
--- /dev/null
@@ -0,0 +1,116 @@
+From c245736e3c9105efd360e64be37a1345925839b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Apr 2021 09:54:55 +0800
+Subject: f2fs: avoid using native allocate_segment_by_default()
+
+From: Chao Yu <yuchao0@huawei.com>
+
+[ Upstream commit 509f1010e4fc55e2dbfc036317afd573ccd0931c ]
+
+As we did for other cases, in fix_curseg_write_pointer(), let's
+use wrapped f2fs_allocate_new_section() instead of native
+allocate_segment_by_default(), by this way, it fixes to cover
+segment allocation with curseg_lock and sentry_lock.
+
+Signed-off-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h    |  2 +-
+ fs/f2fs/file.c    |  2 +-
+ fs/f2fs/segment.c | 18 ++++++++++--------
+ 3 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 3da7be53a3de4..10231d5bba159 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3366,7 +3366,7 @@ void f2fs_get_new_segment(struct f2fs_sb_info *sbi,
+                       unsigned int *newseg, bool new_sec, int dir);
+ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+                                       unsigned int start, unsigned int end);
+-void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type);
++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force);
+ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
+ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
+ bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 7ce22137afbe9..9ecf39c2b47d9 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1689,7 +1689,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
+               down_write(&sbi->pin_sem);
+               f2fs_lock_op(sbi);
+-              f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED);
++              f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
+               f2fs_unlock_op(sbi);
+               map.m_seg_type = CURSEG_COLD_DATA_PINNED;
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index a37f88cc7c485..d2aad633529eb 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2937,7 +2937,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+ }
+ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+-                                                              bool new_sec)
++                                              bool new_sec, bool force)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+       unsigned int old_segno;
+@@ -2945,7 +2945,7 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+       if (!curseg->inited)
+               goto alloc;
+-      if (curseg->next_blkoff ||
++      if (force || curseg->next_blkoff ||
+               get_valid_blocks(sbi, curseg->segno, new_sec))
+               goto alloc;
+@@ -2957,16 +2957,17 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+       locate_dirty_segment(sbi, old_segno);
+ }
+-static void __allocate_new_section(struct f2fs_sb_info *sbi, int type)
++static void __allocate_new_section(struct f2fs_sb_info *sbi,
++                                              int type, bool force)
+ {
+-      __allocate_new_segment(sbi, type, true);
++      __allocate_new_segment(sbi, type, true, force);
+ }
+-void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type)
++void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force)
+ {
+       down_read(&SM_I(sbi)->curseg_lock);
+       down_write(&SIT_I(sbi)->sentry_lock);
+-      __allocate_new_section(sbi, type);
++      __allocate_new_section(sbi, type, force);
+       up_write(&SIT_I(sbi)->sentry_lock);
+       up_read(&SM_I(sbi)->curseg_lock);
+ }
+@@ -2978,7 +2979,7 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+       down_read(&SM_I(sbi)->curseg_lock);
+       down_write(&SIT_I(sbi)->sentry_lock);
+       for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
+-              __allocate_new_segment(sbi, i, false);
++              __allocate_new_segment(sbi, i, false, false);
+       up_write(&SIT_I(sbi)->sentry_lock);
+       up_read(&SM_I(sbi)->curseg_lock);
+ }
+@@ -4867,7 +4868,8 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type)
+       f2fs_notice(sbi, "Assign new section to curseg[%d]: "
+                   "curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff);
+-      allocate_segment_by_default(sbi, type, true);
++
++      f2fs_allocate_new_section(sbi, type, true);
+       /* check consistency of the zone curseg pointed to */
+       if (check_zone_write_pointer(sbi, zbd, &zone))
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch b/queue-5.10/f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch
new file mode 100644 (file)
index 0000000..0bab7d7
--- /dev/null
@@ -0,0 +1,39 @@
+From 26a21df69860ae83861dffd08b7e5326c5f4fdae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 12:48:01 +0800
+Subject: f2fs: check curseg->inited before write_sum_page in change_curseg
+
+From: Yongpeng Yang <yangyongpeng1@oppo.com>
+
+[ Upstream commit 43563069e1c1df417d2eed6eca8a22fc6b04691d ]
+
+In the __f2fs_init_atgc_curseg->get_atssr_segment calling,
+curseg->segno is NULL_SEGNO, indicating that there is no summary
+block that needs to be written.
+
+Fixes: 093749e296e2 ("f2fs: support age threshold based garbage collection")
+Signed-off-by: Yongpeng Yang <yangyongpeng1@oppo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index d99c9e6a0b3e4..a6d05264f1365 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2691,7 +2691,8 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
+       struct f2fs_summary_block *sum_node;
+       struct page *sum_page;
+-      write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
++      if (curseg->inited)
++              write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
+       __set_test_and_inuse(sbi, new_segno);
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch b/queue-5.10/f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch
new file mode 100644 (file)
index 0000000..df1eb8b
--- /dev/null
@@ -0,0 +1,40 @@
+From feb2648884bfc3341347b07065a37125dbf70e0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 10:31:47 +0800
+Subject: f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
+
+From: LongPing Wei <weilongping@oppo.com>
+
+[ Upstream commit c3af1f13476ec23fd99c98d060a89be28c1e8871 ]
+
+This f2fs_bug_on was introduced by commit 2c1905042c8c ("f2fs: check
+segment type in __f2fs_replace_block") when there were only 6 curseg types.
+After commit d0b9e42ab615 ("f2fs: introduce inmem curseg") was introduced,
+the condition should be changed to checking curseg->seg_type.
+
+Fixes: d0b9e42ab615 ("f2fs: introduce inmem curseg")
+Signed-off-by: LongPing Wei <weilongping@oppo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 6fcc83637b153..a37f88cc7c485 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3617,8 +3617,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+               }
+       }
+-      f2fs_bug_on(sbi, !IS_DATASEG(type));
+       curseg = CURSEG_I(sbi, type);
++      f2fs_bug_on(sbi, !IS_DATASEG(curseg->seg_type));
+       mutex_lock(&curseg->curseg_mutex);
+       down_write(&sit_i->sentry_lock);
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-open-code-allocate_segment_by_default.patch b/queue-5.10/f2fs-open-code-allocate_segment_by_default.patch
new file mode 100644 (file)
index 0000000..9536988
--- /dev/null
@@ -0,0 +1,106 @@
+From 375a0d1ab459ab2236fed043691922034d90eff3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:43:45 +0100
+Subject: f2fs: open code allocate_segment_by_default
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 8442d94b8ac8d5d8300725a9ffa9def526b71170 ]
+
+allocate_segment_by_default has just two callers, which use very
+different code pathes inside it based on the force paramter.  Just
+open code the logic in the two callers using a new helper to decided
+if a new segment should be allocated.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 50 +++++++++++++++++++++++------------------------
+ 1 file changed, 24 insertions(+), 26 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 82f8a86d7d701..7d6f2ee2f0177 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2876,31 +2876,20 @@ static int get_ssr_segment(struct f2fs_sb_info *sbi, int type,
+       return 0;
+ }
+-/*
+- * flush out current segment and replace it with new segment
+- * This function should be returned with success, otherwise BUG
+- */
+-static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
+-                                              int type, bool force)
++static bool need_new_seg(struct f2fs_sb_info *sbi, int type)
+ {
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+-      if (force)
+-              new_curseg(sbi, type, true);
+-      else if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) &&
+-                                      curseg->seg_type == CURSEG_WARM_NODE)
+-              new_curseg(sbi, type, false);
+-      else if (curseg->alloc_type == LFS &&
+-                      is_next_segment_free(sbi, curseg, type) &&
+-                      likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
+-              new_curseg(sbi, type, false);
+-      else if (f2fs_need_SSR(sbi) &&
+-                      get_ssr_segment(sbi, type, SSR, 0))
+-              change_curseg(sbi, type, true);
+-      else
+-              new_curseg(sbi, type, false);
+-
+-      stat_inc_seg_type(sbi, curseg);
++      if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) &&
++          curseg->seg_type == CURSEG_WARM_NODE)
++              return true;
++      if (curseg->alloc_type == LFS &&
++          is_next_segment_free(sbi, curseg, type) &&
++          likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
++              return true;
++      if (!f2fs_need_SSR(sbi) || !get_ssr_segment(sbi, type, SSR, 0))
++              return true;
++      return false;
+ }
+ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+@@ -2953,7 +2942,8 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+               return;
+ alloc:
+       old_segno = curseg->segno;
+-      allocate_segment_by_default(sbi, type, true);
++      new_curseg(sbi, type, true);
++      stat_inc_seg_type(sbi, curseg);
+       locate_dirty_segment(sbi, old_segno);
+ }
+@@ -3393,11 +3383,19 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+       update_sit_entry(sbi, old_blkaddr, -1);
+       if (!__has_curseg_space(sbi, curseg)) {
+-              if (from_gc)
++              /*
++               * Flush out current segment and replace it with new segment.
++               */
++              if (from_gc) {
+                       get_atssr_segment(sbi, type, se->type,
+                                               AT_SSR, se->mtime);
+-              else
+-                      allocate_segment_by_default(sbi, type, false);
++              } else {
++                      if (need_new_seg(sbi, type))
++                              new_curseg(sbi, type, false);
++                      else
++                              change_curseg(sbi, type, true);
++                      stat_inc_seg_type(sbi, curseg);
++              }
+       }
+       /*
+        * segment dirty status should be updated after segment allocation,
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch b/queue-5.10/f2fs-remove-struct-segment_allocation-default_salloc.patch
new file mode 100644 (file)
index 0000000..e2c2ec5
--- /dev/null
@@ -0,0 +1,92 @@
+From 518141ff44add897384fc6b7044f9d63027ad07f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:43:44 +0100
+Subject: f2fs: remove struct segment_allocation default_salloc_ops
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 1c8a8ec0a0e9a1176022a35c4daf04fe1594d270 ]
+
+There is only  single instance of these ops, so remove the indirection
+and call allocate_segment_by_default directly.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 11 ++---------
+ fs/f2fs/segment.h |  6 ------
+ 2 files changed, 2 insertions(+), 15 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index d2aad633529eb..82f8a86d7d701 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2953,7 +2953,7 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
+               return;
+ alloc:
+       old_segno = curseg->segno;
+-      SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
++      allocate_segment_by_default(sbi, type, true);
+       locate_dirty_segment(sbi, old_segno);
+ }
+@@ -2984,10 +2984,6 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+       up_read(&SM_I(sbi)->curseg_lock);
+ }
+-static const struct segment_allocation default_salloc_ops = {
+-      .allocate_segment = allocate_segment_by_default,
+-};
+-
+ bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
+                                               struct cp_control *cpc)
+ {
+@@ -3401,7 +3397,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+                       get_atssr_segment(sbi, type, se->type,
+                                               AT_SSR, se->mtime);
+               else
+-                      sit_i->s_ops->allocate_segment(sbi, type, false);
++                      allocate_segment_by_default(sbi, type, false);
+       }
+       /*
+        * segment dirty status should be updated after segment allocation,
+@@ -4337,9 +4333,6 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
+               return -ENOMEM;
+ #endif
+-      /* init SIT information */
+-      sit_i->s_ops = &default_salloc_ops;
+-
+       sit_i->sit_base_addr = le32_to_cpu(raw_super->sit_blkaddr);
+       sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg;
+       sit_i->written_valid_blocks = 0;
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 665e0e186687d..720951ce2f9d1 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -227,10 +227,6 @@ struct sec_entry {
+       unsigned int valid_blocks;      /* # of valid blocks in a section */
+ };
+-struct segment_allocation {
+-      void (*allocate_segment)(struct f2fs_sb_info *, int, bool);
+-};
+-
+ #define MAX_SKIP_GC_COUNT                     16
+ struct inmem_pages {
+@@ -240,8 +236,6 @@ struct inmem_pages {
+ };
+ struct sit_info {
+-      const struct segment_allocation *s_ops;
+-
+       block_t sit_base_addr;          /* start block address of SIT area */
+       block_t sit_blocks;             /* # of blocks used by SIT area */
+       block_t written_valid_blocks;   /* # of valid blocks in main area */
+-- 
+2.43.0
+
diff --git a/queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch b/queue-5.10/f2fs-remove-the-unused-flush-argument-to-change_curs.patch
new file mode 100644 (file)
index 0000000..9b54bea
--- /dev/null
@@ -0,0 +1,90 @@
+From b67d455381f69ee1e5df1d6a70b862356b7b3e7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:43:46 +0100
+Subject: f2fs: remove the unused flush argument to change_curseg
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 5bcd655fffaec24e849bda1207446f5cc821713e ]
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 43563069e1c1 ("f2fs: check curseg->inited before write_sum_page in change_curseg")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 7d6f2ee2f0177..d99c9e6a0b3e4 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -2683,7 +2683,7 @@ bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno)
+  * This function always allocates a used segment(from dirty seglist) by SSR
+  * manner, so it should recover the existing segment information of valid blocks
+  */
+-static void change_curseg(struct f2fs_sb_info *sbi, int type, bool flush)
++static void change_curseg(struct f2fs_sb_info *sbi, int type)
+ {
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+       struct curseg_info *curseg = CURSEG_I(sbi, type);
+@@ -2691,9 +2691,7 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool flush)
+       struct f2fs_summary_block *sum_node;
+       struct page *sum_page;
+-      if (flush)
+-              write_sum_page(sbi, curseg->sum_blk,
+-                                      GET_SUM_BLOCK(sbi, curseg->segno));
++      write_sum_page(sbi, curseg->sum_blk, GET_SUM_BLOCK(sbi, curseg->segno));
+       __set_test_and_inuse(sbi, new_segno);
+@@ -2732,7 +2730,7 @@ static void get_atssr_segment(struct f2fs_sb_info *sbi, int type,
+               struct seg_entry *se = get_seg_entry(sbi, curseg->next_segno);
+               curseg->seg_type = se->type;
+-              change_curseg(sbi, type, true);
++              change_curseg(sbi, type);
+       } else {
+               /* allocate cold segment by default */
+               curseg->seg_type = CURSEG_COLD_DATA;
+@@ -2907,7 +2905,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
+               goto unlock;
+       if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type, SSR, 0))
+-              change_curseg(sbi, type, true);
++              change_curseg(sbi, type);
+       else
+               new_curseg(sbi, type, true);
+@@ -3393,7 +3391,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+                       if (need_new_seg(sbi, type))
+                               new_curseg(sbi, type, false);
+                       else
+-                              change_curseg(sbi, type, true);
++                              change_curseg(sbi, type);
+                       stat_inc_seg_type(sbi, curseg);
+               }
+       }
+@@ -3624,7 +3622,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+       /* change the current segment */
+       if (segno != curseg->segno) {
+               curseg->next_segno = segno;
+-              change_curseg(sbi, type, true);
++              change_curseg(sbi, type);
+       }
+       curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr);
+@@ -3651,7 +3649,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+       if (recover_curseg) {
+               if (old_cursegno != curseg->segno) {
+                       curseg->next_segno = old_cursegno;
+-                      change_curseg(sbi, type, true);
++                      change_curseg(sbi, type);
+               }
+               curseg->next_blkoff = old_blkoff;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch b/queue-5.10/fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch
new file mode 100644 (file)
index 0000000..4bfd7ff
--- /dev/null
@@ -0,0 +1,65 @@
+From a7a426038cc2b086e13c44aabfaab8088fe7da94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 13:07:02 +0200
+Subject: fbdev/sh7760fb: Alloc DMA memory from hardware device
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 8404e56f4bc1d1a65bfc98450ba3dae5e653dda1 ]
+
+Pass the hardware device to the DMA helpers dma_alloc_coherent() and
+dma_free_coherent(). The fbdev device that is currently being used is
+a software device and does not provide DMA memory. Also update the
+related dev_*() output statements similarly.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230613110953.24176-28-tzimmermann@suse.de
+Stable-dep-of: f89d17ae2ac4 ("fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sh7760fb.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c
+index 5978a89212322..6adf048c1bae8 100644
+--- a/drivers/video/fbdev/sh7760fb.c
++++ b/drivers/video/fbdev/sh7760fb.c
+@@ -359,7 +359,7 @@ static void sh7760fb_free_mem(struct fb_info *info)
+       if (!info->screen_base)
+               return;
+-      dma_free_coherent(info->dev, info->screen_size,
++      dma_free_coherent(info->device, info->screen_size,
+                         info->screen_base, par->fbdma);
+       par->fbdma = 0;
+@@ -408,14 +408,14 @@ static int sh7760fb_alloc_mem(struct fb_info *info)
+       if (vram < PAGE_SIZE)
+               vram = PAGE_SIZE;
+-      fbmem = dma_alloc_coherent(info->dev, vram, &par->fbdma, GFP_KERNEL);
++      fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL);
+       if (!fbmem)
+               return -ENOMEM;
+       if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
+               sh7760fb_free_mem(info);
+-              dev_err(info->dev, "kernel gave me memory at 0x%08lx, which is"
++              dev_err(info->device, "kernel gave me memory at 0x%08lx, which is"
+                       "unusable for the LCDC\n", (unsigned long)par->fbdma);
+               return -ENOMEM;
+       }
+@@ -486,7 +486,7 @@ static int sh7760fb_probe(struct platform_device *pdev)
+       ret = sh7760fb_alloc_mem(info);
+       if (ret) {
+-              dev_dbg(info->dev, "framebuffer memory allocation failed!\n");
++              dev_dbg(info->device, "framebuffer memory allocation failed!\n");
+               goto out_unmap;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch b/queue-5.10/fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch
new file mode 100644 (file)
index 0000000..efcac66
--- /dev/null
@@ -0,0 +1,43 @@
+From f27fe7cb3f931e1b9348eea865616a1c9af9d968 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 11:56:34 +0800
+Subject: fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit f89d17ae2ac42931be2a0153fecbf8533280c927 ]
+
+When information such as info->screen_base is not ready, calling
+sh7760fb_free_mem() does not release memory correctly. Call
+dma_free_coherent() instead.
+
+Fixes: 4a25e41831ee ("video: sh7760fb: SH7760/SH7763 LCDC framebuffer driver")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sh7760fb.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/video/fbdev/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c
+index 6adf048c1bae8..62e28d315d815 100644
+--- a/drivers/video/fbdev/sh7760fb.c
++++ b/drivers/video/fbdev/sh7760fb.c
+@@ -409,12 +409,11 @@ static int sh7760fb_alloc_mem(struct fb_info *info)
+               vram = PAGE_SIZE;
+       fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL);
+-
+       if (!fbmem)
+               return -ENOMEM;
+       if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
+-              sh7760fb_free_mem(info);
++              dma_free_coherent(info->device, vram, fbmem, par->fbdma);
+               dev_err(info->device, "kernel gave me memory at 0x%08lx, which is"
+                       "unusable for the LCDC\n", (unsigned long)par->fbdma);
+               return -ENOMEM;
+-- 
+2.43.0
+
diff --git a/queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch b/queue-5.10/firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch
new file mode 100644 (file)
index 0000000..28c95e4
--- /dev/null
@@ -0,0 +1,93 @@
+From 3f869111ba201a954ef5e5c5997b48e5d2645379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2024 11:21:15 +0800
+Subject: firmware: arm_scpi: Check the DVFS OPP count returned by the firmware
+
+From: Luo Qiu <luoqiu@kylinsec.com.cn>
+
+[ Upstream commit 109aa654f85c5141e813b2cd1bd36d90be678407 ]
+
+Fix a kernel crash with the below call trace when the SCPI firmware
+returns OPP count of zero.
+
+dvfs_info.opp_count may be zero on some platforms during the reboot
+test, and the kernel will crash after dereferencing the pointer to
+kcalloc(info->count, sizeof(*opp), GFP_KERNEL).
+
+  |  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
+  |  Mem abort info:
+  |    ESR = 0x96000004
+  |    Exception class = DABT (current EL), IL = 32 bits
+  |    SET = 0, FnV = 0
+  |    EA = 0, S1PTW = 0
+  |  Data abort info:
+  |    ISV = 0, ISS = 0x00000004
+  |    CM = 0, WnR = 0
+  |  user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000faefa08c
+  |  [0000000000000028] pgd=0000000000000000
+  |  Internal error: Oops: 96000004 [#1] SMP
+  |  scpi-hwmon: probe of PHYT000D:00 failed with error -110
+  |  Process systemd-udevd (pid: 1701, stack limit = 0x00000000aaede86c)
+  |  CPU: 2 PID: 1701 Comm: systemd-udevd Not tainted 4.19.90+ #1
+  |  Hardware name: PHYTIUM LTD Phytium FT2000/4/Phytium FT2000/4, BIOS
+  |  pstate: 60000005 (nZCv daif -PAN -UAO)
+  |  pc : scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi]
+  |  lr : clk_register+0x438/0x720
+  |  Call trace:
+  |   scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi]
+  |   devm_clk_hw_register+0x50/0xa0
+  |   scpi_clk_ops_init.isra.2+0xa0/0x138 [clk_scpi]
+  |   scpi_clocks_probe+0x528/0x70c [clk_scpi]
+  |   platform_drv_probe+0x58/0xa8
+  |   really_probe+0x260/0x3d0
+  |   driver_probe_device+0x12c/0x148
+  |   device_driver_attach+0x74/0x98
+  |   __driver_attach+0xb4/0xe8
+  |   bus_for_each_dev+0x88/0xe0
+  |   driver_attach+0x30/0x40
+  |   bus_add_driver+0x178/0x2b0
+  |   driver_register+0x64/0x118
+  |   __platform_driver_register+0x54/0x60
+  |   scpi_clocks_driver_init+0x24/0x1000 [clk_scpi]
+  |   do_one_initcall+0x54/0x220
+  |   do_init_module+0x54/0x1c8
+  |   load_module+0x14a4/0x1668
+  |   __se_sys_finit_module+0xf8/0x110
+  |   __arm64_sys_finit_module+0x24/0x30
+  |   el0_svc_common+0x78/0x170
+  |   el0_svc_handler+0x38/0x78
+  |   el0_svc+0x8/0x340
+  |  Code: 937d7c00 a94153f3 a8c27bfd f9400421 (b8606820)
+  |  ---[ end trace 06feb22469d89fa8 ]---
+  |  Kernel panic - not syncing: Fatal exception
+  |  SMP: stopping secondary CPUs
+  |  Kernel Offset: disabled
+  |  CPU features: 0x10,a0002008
+  |  Memory Limit: none
+
+Fixes: 8cb7cf56c9fe ("firmware: add support for ARM System Control and Power Interface(SCPI) protocol")
+Signed-off-by: Luo Qiu <luoqiu@kylinsec.com.cn>
+Message-Id: <55A2F7A784391686+20241101032115.275977-1-luoqiu@kylinsec.com.cn>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scpi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
+index 36391cb5130e2..3a1d77b882f7e 100644
+--- a/drivers/firmware/arm_scpi.c
++++ b/drivers/firmware/arm_scpi.c
+@@ -627,6 +627,9 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
+       if (ret)
+               return ERR_PTR(ret);
++      if (!buf.opp_count)
++              return ERR_PTR(-ENOENT);
++
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return ERR_PTR(-ENOMEM);
+-- 
+2.43.0
+
diff --git a/queue-5.10/firmware-google-unregister-driver_info-on-failure.patch b/queue-5.10/firmware-google-unregister-driver_info-on-failure.patch
new file mode 100644 (file)
index 0000000..2b0346f
--- /dev/null
@@ -0,0 +1,53 @@
+From 16d67607e7a8853f94006c6a206671191ca7f036 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 21:13:44 +0800
+Subject: firmware: google: Unregister driver_info on failure
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 32b0901e141f6d4cf49d820b53eb09b88b1f72f7 ]
+
+When platform_device_register_full() returns error, the gsmi_init() returns
+without unregister gsmi_driver_info, fix by add missing
+platform_driver_unregister() when platform_device_register_full() failed.
+
+Fixes: 8942b2d5094b ("gsmi: Add GSMI commands to log S0ix info")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Link: https://lore.kernel.org/r/20241015131344.20272-1-yuancan@huawei.com
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/google/gsmi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
+index 407cac71c77de..c82d38436b9b6 100644
+--- a/drivers/firmware/google/gsmi.c
++++ b/drivers/firmware/google/gsmi.c
+@@ -917,7 +917,8 @@ static __init int gsmi_init(void)
+       gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
+       if (IS_ERR(gsmi_dev.pdev)) {
+               printk(KERN_ERR "gsmi: unable to register platform device\n");
+-              return PTR_ERR(gsmi_dev.pdev);
++              ret = PTR_ERR(gsmi_dev.pdev);
++              goto out_unregister;
+       }
+       /* SMI access needs to be serialized */
+@@ -1044,10 +1045,11 @@ static __init int gsmi_init(void)
+       gsmi_buf_free(gsmi_dev.name_buf);
+       dma_pool_destroy(gsmi_dev.dma_pool);
+       platform_device_unregister(gsmi_dev.pdev);
+-      pr_info("gsmi: failed to load: %d\n", ret);
++out_unregister:
+ #ifdef CONFIG_PM
+       platform_driver_unregister(&gsmi_driver_info);
+ #endif
++      pr_info("gsmi: failed to load: %d\n", ret);
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch b/queue-5.10/fs_parser-update-mount_api-doc-to-match-function-sig.patch
new file mode 100644 (file)
index 0000000..d1be936
--- /dev/null
@@ -0,0 +1,45 @@
+From 98dd6904a706ce12fb170d6ddc4a7c73f0380ac8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 13:50:21 -0800
+Subject: fs_parser: update mount_api doc to match function signature
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit c66f759832a83cb273ba5a55c66dcc99384efa74 ]
+
+Add the missing 'name' parameter to the mount_api documentation for
+fs_validate_description().
+
+Fixes: 96cafb9ccb15 ("fs_parser: remove fs_parameter_description name field")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20241125215021.231758-1-rdunlap@infradead.org
+Cc: Eric Sandeen <sandeen@redhat.com>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Christian Brauner <brauner@kernel.org>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: linux-doc@vger.kernel.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/filesystems/mount_api.rst | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/filesystems/mount_api.rst b/Documentation/filesystems/mount_api.rst
+index d7f53d62b5bb2..8fb03f57546d1 100644
+--- a/Documentation/filesystems/mount_api.rst
++++ b/Documentation/filesystems/mount_api.rst
+@@ -778,7 +778,8 @@ process the parameters it is given.
+    * ::
+-       bool fs_validate_description(const struct fs_parameter_description *desc);
++       bool fs_validate_description(const char *name,
++                                    const struct fs_parameter_description *desc);
+      This performs some validation checks on a parameter description.  It
+      returns true if the description is good and false if it is not.  It will
+-- 
+2.43.0
+
diff --git a/queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch b/queue-5.10/hfsplus-don-t-query-the-device-logical-block-size-mu.patch
new file mode 100644 (file)
index 0000000..ebb7433
--- /dev/null
@@ -0,0 +1,139 @@
+From defc2ec0baf6ce4d2f67c2795346036f2ba0ea5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 08:41:09 -0300
+Subject: hfsplus: don't query the device logical block size multiple times
+
+From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+
+[ Upstream commit 1c82587cb57687de3f18ab4b98a8850c789bedcf ]
+
+Devices block sizes may change. One of these cases is a loop device by
+using ioctl LOOP_SET_BLOCK_SIZE.
+
+While this may cause other issues like IO being rejected, in the case of
+hfsplus, it will allocate a block by using that size and potentially write
+out-of-bounds when hfsplus_read_wrapper calls hfsplus_submit_bio and the
+latter function reads a different io_size.
+
+Using a new min_io_size initally set to sb_min_blocksize works for the
+purposes of the original fix, since it will be set to the max between
+HFSPLUS_SECTOR_SIZE and the first seen logical block size. We still use the
+max between HFSPLUS_SECTOR_SIZE and min_io_size in case the latter is not
+initialized.
+
+Tested by mounting an hfsplus filesystem with loop block sizes 512, 1024
+and 4096.
+
+The produced KASAN report before the fix looks like this:
+
+[  419.944641] ==================================================================
+[  419.945655] BUG: KASAN: slab-use-after-free in hfsplus_read_wrapper+0x659/0xa0a
+[  419.946703] Read of size 2 at addr ffff88800721fc00 by task repro/10678
+[  419.947612]
+[  419.947846] CPU: 0 UID: 0 PID: 10678 Comm: repro Not tainted 6.12.0-rc5-00008-gdf56e0f2f3ca #84
+[  419.949007] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
+[  419.950035] Call Trace:
+[  419.950384]  <TASK>
+[  419.950676]  dump_stack_lvl+0x57/0x78
+[  419.951212]  ? hfsplus_read_wrapper+0x659/0xa0a
+[  419.951830]  print_report+0x14c/0x49e
+[  419.952361]  ? __virt_addr_valid+0x267/0x278
+[  419.952979]  ? kmem_cache_debug_flags+0xc/0x1d
+[  419.953561]  ? hfsplus_read_wrapper+0x659/0xa0a
+[  419.954231]  kasan_report+0x89/0xb0
+[  419.954748]  ? hfsplus_read_wrapper+0x659/0xa0a
+[  419.955367]  hfsplus_read_wrapper+0x659/0xa0a
+[  419.955948]  ? __pfx_hfsplus_read_wrapper+0x10/0x10
+[  419.956618]  ? do_raw_spin_unlock+0x59/0x1a9
+[  419.957214]  ? _raw_spin_unlock+0x1a/0x2e
+[  419.957772]  hfsplus_fill_super+0x348/0x1590
+[  419.958355]  ? hlock_class+0x4c/0x109
+[  419.958867]  ? __pfx_hfsplus_fill_super+0x10/0x10
+[  419.959499]  ? __pfx_string+0x10/0x10
+[  419.960006]  ? lock_acquire+0x3e2/0x454
+[  419.960532]  ? bdev_name.constprop.0+0xce/0x243
+[  419.961129]  ? __pfx_bdev_name.constprop.0+0x10/0x10
+[  419.961799]  ? pointer+0x3f0/0x62f
+[  419.962277]  ? __pfx_pointer+0x10/0x10
+[  419.962761]  ? vsnprintf+0x6c4/0xfba
+[  419.963178]  ? __pfx_vsnprintf+0x10/0x10
+[  419.963621]  ? setup_bdev_super+0x376/0x3b3
+[  419.964029]  ? snprintf+0x9d/0xd2
+[  419.964344]  ? __pfx_snprintf+0x10/0x10
+[  419.964675]  ? lock_acquired+0x45c/0x5e9
+[  419.965016]  ? set_blocksize+0x139/0x1c1
+[  419.965381]  ? sb_set_blocksize+0x6d/0xae
+[  419.965742]  ? __pfx_hfsplus_fill_super+0x10/0x10
+[  419.966179]  mount_bdev+0x12f/0x1bf
+[  419.966512]  ? __pfx_mount_bdev+0x10/0x10
+[  419.966886]  ? vfs_parse_fs_string+0xce/0x111
+[  419.967293]  ? __pfx_vfs_parse_fs_string+0x10/0x10
+[  419.967702]  ? __pfx_hfsplus_mount+0x10/0x10
+[  419.968073]  legacy_get_tree+0x104/0x178
+[  419.968414]  vfs_get_tree+0x86/0x296
+[  419.968751]  path_mount+0xba3/0xd0b
+[  419.969157]  ? __pfx_path_mount+0x10/0x10
+[  419.969594]  ? kmem_cache_free+0x1e2/0x260
+[  419.970311]  do_mount+0x99/0xe0
+[  419.970630]  ? __pfx_do_mount+0x10/0x10
+[  419.971008]  __do_sys_mount+0x199/0x1c9
+[  419.971397]  do_syscall_64+0xd0/0x135
+[  419.971761]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+[  419.972233] RIP: 0033:0x7c3cb812972e
+[  419.972564] Code: 48 8b 0d f5 46 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c2 46 0d 00 f7 d8 64 89 01 48
+[  419.974371] RSP: 002b:00007ffe30632548 EFLAGS: 00000286 ORIG_RAX: 00000000000000a5
+[  419.975048] RAX: ffffffffffffffda RBX: 00007ffe306328d8 RCX: 00007c3cb812972e
+[  419.975701] RDX: 0000000020000000 RSI: 0000000020000c80 RDI: 00007ffe306325d0
+[  419.976363] RBP: 00007ffe30632720 R08: 00007ffe30632610 R09: 0000000000000000
+[  419.977034] R10: 0000000000200008 R11: 0000000000000286 R12: 0000000000000000
+[  419.977713] R13: 00007ffe306328e8 R14: 00005a0eb298bc68 R15: 00007c3cb8356000
+[  419.978375]  </TASK>
+[  419.978589]
+
+Fixes: 6596528e391a ("hfsplus: ensure bio requests are not smaller than the hardware sectors")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Link: https://lore.kernel.org/r/20241107114109.839253-1-cascardo@igalia.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hfsplus/hfsplus_fs.h | 3 ++-
+ fs/hfsplus/wrapper.c    | 2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index bfbe88e804eb0..c37a2f3d88af0 100644
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -156,6 +156,7 @@ struct hfsplus_sb_info {
+       /* Runtime variables */
+       u32 blockoffset;
++      u32 min_io_size;
+       sector_t part_start;
+       sector_t sect_count;
+       int fs_shift;
+@@ -306,7 +307,7 @@ struct hfsplus_readdir_data {
+  */
+ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
+ {
+-      return max_t(unsigned short, bdev_logical_block_size(sb->s_bdev),
++      return max_t(unsigned short, HFSPLUS_SB(sb)->min_io_size,
+                    HFSPLUS_SECTOR_SIZE);
+ }
+diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
+index 0350dc7821bf9..59ba0a30f5392 100644
+--- a/fs/hfsplus/wrapper.c
++++ b/fs/hfsplus/wrapper.c
+@@ -173,6 +173,8 @@ int hfsplus_read_wrapper(struct super_block *sb)
+       if (!blocksize)
+               goto out;
++      sbi->min_io_size = blocksize;
++
+       if (hfsplus_get_last_session(sb, &part_start, &part_size))
+               goto out;
+-- 
+2.43.0
+
diff --git a/queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch b/queue-5.10/iio-light-al3010-fix-an-error-handling-path-in-al301.patch
new file mode 100644 (file)
index 0000000..73efece
--- /dev/null
@@ -0,0 +1,58 @@
+From 00cbdd904ef721e4215a7eef57f7fc1a3e88fbcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 20:36:06 +0200
+Subject: iio: light: al3010: Fix an error handling path in al3010_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit a4b7064d34186cf4970fe0333c3b27346cf8f819 ]
+
+If i2c_smbus_write_byte_data() fails in al3010_init(),
+al3010_set_pwr(false) is not called.
+
+In order to avoid such a situation, move the devm_add_action_or_reset()
+witch calls al3010_set_pwr(false) right after a successful
+al3010_set_pwr(true).
+
+Fixes: c36b5195ab70 ("iio: light: add Dyna-Image AL3010 driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://patch.msgid.link/ee5d10a2dd2b70f29772d5df33774d3974a80f30.1725993353.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/light/al3010.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iio/light/al3010.c b/drivers/iio/light/al3010.c
+index b4e9924094cd1..bd83e73e68026 100644
+--- a/drivers/iio/light/al3010.c
++++ b/drivers/iio/light/al3010.c
+@@ -87,7 +87,12 @@ static int al3010_init(struct al3010_data *data)
+       int ret;
+       ret = al3010_set_pwr(data->client, true);
++      if (ret < 0)
++              return ret;
++      ret = devm_add_action_or_reset(&data->client->dev,
++                                     al3010_set_pwr_off,
++                                     data);
+       if (ret < 0)
+               return ret;
+@@ -191,12 +196,6 @@ static int al3010_probe(struct i2c_client *client,
+               return ret;
+       }
+-      ret = devm_add_action_or_reset(&client->dev,
+-                                      al3010_set_pwr_off,
+-                                      data);
+-      if (ret < 0)
+-              return ret;
+-
+       return devm_iio_device_register(&client->dev, indio_dev);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/initramfs-avoid-filename-buffer-overrun.patch b/queue-5.10/initramfs-avoid-filename-buffer-overrun.patch
new file mode 100644 (file)
index 0000000..2f1098c
--- /dev/null
@@ -0,0 +1,118 @@
+From f42555fbc153ee26234a432c2754c5070f322848 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 03:55:10 +0000
+Subject: initramfs: avoid filename buffer overrun
+
+From: David Disseldorp <ddiss@suse.de>
+
+[ Upstream commit e017671f534dd3f568db9e47b0583e853d2da9b5 ]
+
+The initramfs filename field is defined in
+Documentation/driver-api/early-userspace/buffer-format.rst as:
+
+ 37 cpio_file := ALGN(4) + cpio_header + filename + "\0" + ALGN(4) + data
+...
+ 55 ============= ================== =========================
+ 56 Field name    Field size         Meaning
+ 57 ============= ================== =========================
+...
+ 70 c_namesize    8 bytes            Length of filename, including final \0
+
+When extracting an initramfs cpio archive, the kernel's do_name() path
+handler assumes a zero-terminated path at @collected, passing it
+directly to filp_open() / init_mkdir() / init_mknod().
+
+If a specially crafted cpio entry carries a non-zero-terminated filename
+and is followed by uninitialized memory, then a file may be created with
+trailing characters that represent the uninitialized memory. The ability
+to create an initramfs entry would imply already having full control of
+the system, so the buffer overrun shouldn't be considered a security
+vulnerability.
+
+Append the output of the following bash script to an existing initramfs
+and observe any created /initramfs_test_fname_overrunAA* path. E.g.
+  ./reproducer.sh | gzip >> /myinitramfs
+
+It's easiest to observe non-zero uninitialized memory when the output is
+gzipped, as it'll overflow the heap allocated @out_buf in __gunzip(),
+rather than the initrd_start+initrd_size block.
+
+---- reproducer.sh ----
+nilchar="A"    # change to "\0" to properly zero terminate / pad
+magic="070701"
+ino=1
+mode=$(( 0100777 ))
+uid=0
+gid=0
+nlink=1
+mtime=1
+filesize=0
+devmajor=0
+devminor=1
+rdevmajor=0
+rdevminor=0
+csum=0
+fname="initramfs_test_fname_overrun"
+namelen=$(( ${#fname} + 1 ))   # plus one to account for terminator
+
+printf "%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s" \
+       $magic $ino $mode $uid $gid $nlink $mtime $filesize \
+       $devmajor $devminor $rdevmajor $rdevminor $namelen $csum $fname
+
+termpadlen=$(( 1 + ((4 - ((110 + $namelen) & 3)) % 4) ))
+printf "%.s${nilchar}" $(seq 1 $termpadlen)
+---- reproducer.sh ----
+
+Symlink filename fields handled in do_symlink() won't overrun past the
+data segment, due to the explicit zero-termination of the symlink
+target.
+
+Fix filename buffer overrun by aborting the initramfs FSM if any cpio
+entry doesn't carry a zero-terminator at the expected (name_len - 1)
+offset.
+
+Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
+Signed-off-by: David Disseldorp <ddiss@suse.de>
+Link: https://lore.kernel.org/r/20241030035509.20194-2-ddiss@suse.de
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/initramfs.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/init/initramfs.c b/init/initramfs.c
+index ff09460727237..a56fc491c276d 100644
+--- a/init/initramfs.c
++++ b/init/initramfs.c
+@@ -325,6 +325,15 @@ static int __init do_name(void)
+ {
+       state = SkipIt;
+       next_state = Reset;
++
++      /* name_len > 0 && name_len <= PATH_MAX checked in do_header */
++      if (collected[name_len - 1] != '\0') {
++              pr_err("initramfs name without nulterm: %.*s\n",
++                     (int)name_len, collected);
++              error("malformed archive");
++              return 1;
++      }
++
+       if (strcmp(collected, "TRAILER!!!") == 0) {
+               free_hash();
+               return 0;
+@@ -390,6 +399,12 @@ static int __init do_copy(void)
+ static int __init do_symlink(void)
+ {
++      if (collected[name_len - 1] != '\0') {
++              pr_err("initramfs symlink without nulterm: %.*s\n",
++                     (int)name_len, collected);
++              error("malformed archive");
++              return 1;
++      }
+       collected[N_ALIGN(name_len) + body_len] = '\0';
+       clean_path(collected, 0);
+       init_symlink(collected + N_ALIGN(name_len), collected);
+-- 
+2.43.0
+
diff --git a/queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch b/queue-5.10/ipmr-convert-proc-handlers-to-rcu_read_lock.patch
new file mode 100644 (file)
index 0000000..b4392fb
--- /dev/null
@@ -0,0 +1,86 @@
+From 094035ad03905cc8e6645464f14de1fe42ab71b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 04:34:47 +0000
+Subject: ipmr: convert /proc handlers to rcu_read_lock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b96ef16d2f837870daaea51c38cd50458b95ad5c ]
+
+We can use standard rcu_read_lock(), to get rid
+of last read_lock(&mrt_lock) call points.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: fc9c273d6daa ("ipmr: fix tables suspicious RCU usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ipmr.c  | 8 ++++----
+ net/ipv6/ip6mr.c | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index db184cb826b95..fe3d23611a297 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -2896,7 +2896,7 @@ static int ipmr_rtm_dumplink(struct sk_buff *skb, struct netlink_callback *cb)
+  */
+ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+-      __acquires(mrt_lock)
++      __acquires(RCU)
+ {
+       struct mr_vif_iter *iter = seq->private;
+       struct net *net = seq_file_net(seq);
+@@ -2908,14 +2908,14 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+       iter->mrt = mrt;
+-      read_lock(&mrt_lock);
++      rcu_read_lock();
+       return mr_vif_seq_start(seq, pos);
+ }
+ static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
+-      __releases(mrt_lock)
++      __releases(RCU)
+ {
+-      read_unlock(&mrt_lock);
++      rcu_read_unlock();
+ }
+ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
+diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
+index c758d0cc6146d..926baaf8661cc 100644
+--- a/net/ipv6/ip6mr.c
++++ b/net/ipv6/ip6mr.c
+@@ -405,7 +405,7 @@ static void ip6mr_free_table(struct mr_table *mrt)
+  */
+ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+-      __acquires(mrt_lock)
++      __acquires(RCU)
+ {
+       struct mr_vif_iter *iter = seq->private;
+       struct net *net = seq_file_net(seq);
+@@ -417,14 +417,14 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+       iter->mrt = mrt;
+-      read_lock(&mrt_lock);
++      rcu_read_lock();
+       return mr_vif_seq_start(seq, pos);
+ }
+ static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v)
+-      __releases(mrt_lock)
++      __releases(RCU)
+ {
+-      read_unlock(&mrt_lock);
++      rcu_read_unlock();
+ }
+ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
+-- 
+2.43.0
+
diff --git a/queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch b/queue-5.10/ipmr-fix-tables-suspicious-rcu-usage.patch
new file mode 100644 (file)
index 0000000..0e11e44
--- /dev/null
@@ -0,0 +1,154 @@
+From 7b90915c575218edc0e3e450f306eefc585be7a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Nov 2024 16:40:58 +0100
+Subject: ipmr: fix tables suspicious RCU usage
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit fc9c273d6daaa9866f349bbe8cae25c67764c456 ]
+
+Similar to the previous patch, plumb the RCU lock inside
+the ipmr_get_table(), provided a lockless variant and apply
+the latter in the few spots were the lock is already held.
+
+Fixes: 709b46e8d90b ("net: Add compat ioctl support for the ipv4 multicast ioctl SIOCGETSGCNT")
+Fixes: f0ad0860d01e ("ipv4: ipmr: support multiple tables")
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ipmr.c | 42 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 29 insertions(+), 13 deletions(-)
+
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index fe3d23611a297..6e4f91e76e2d3 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -131,7 +131,7 @@ static struct mr_table *ipmr_mr_table_iter(struct net *net,
+       return ret;
+ }
+-static struct mr_table *ipmr_get_table(struct net *net, u32 id)
++static struct mr_table *__ipmr_get_table(struct net *net, u32 id)
+ {
+       struct mr_table *mrt;
+@@ -142,6 +142,16 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
+       return NULL;
+ }
++static struct mr_table *ipmr_get_table(struct net *net, u32 id)
++{
++      struct mr_table *mrt;
++
++      rcu_read_lock();
++      mrt = __ipmr_get_table(net, id);
++      rcu_read_unlock();
++      return mrt;
++}
++
+ static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
+                          struct mr_table **mrt)
+ {
+@@ -183,7 +193,7 @@ static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp,
+       arg->table = fib_rule_get_table(rule, arg);
+-      mrt = ipmr_get_table(rule->fr_net, arg->table);
++      mrt = __ipmr_get_table(rule->fr_net, arg->table);
+       if (!mrt)
+               return -EAGAIN;
+       res->mrt = mrt;
+@@ -315,6 +325,8 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
+       return net->ipv4.mrt;
+ }
++#define __ipmr_get_table ipmr_get_table
++
+ static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
+                          struct mr_table **mrt)
+ {
+@@ -404,7 +416,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
+       if (id != RT_TABLE_DEFAULT && id >= 1000000000)
+               return ERR_PTR(-EINVAL);
+-      mrt = ipmr_get_table(net, id);
++      mrt = __ipmr_get_table(net, id);
+       if (mrt)
+               return mrt;
+@@ -1366,7 +1378,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
+               goto out_unlock;
+       }
+-      mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
++      mrt = __ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
+       if (!mrt) {
+               ret = -ENOENT;
+               goto out_unlock;
+@@ -2242,11 +2254,13 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
+       struct mr_table *mrt;
+       int err;
+-      mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
+-      if (!mrt)
++      rcu_read_lock();
++      mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT);
++      if (!mrt) {
++              rcu_read_unlock();
+               return -ENOENT;
++      }
+-      rcu_read_lock();
+       cache = ipmr_cache_find(mrt, saddr, daddr);
+       if (!cache && skb->dev) {
+               int vif = ipmr_find_vif(mrt, skb->dev);
+@@ -2537,7 +2551,7 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
+       grp = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
+       tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0;
+-      mrt = ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT);
++      mrt = __ipmr_get_table(net, tableid ? tableid : RT_TABLE_DEFAULT);
+       if (!mrt) {
+               err = -ENOENT;
+               goto errout_free;
+@@ -2589,7 +2603,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
+       if (filter.table_id) {
+               struct mr_table *mrt;
+-              mrt = ipmr_get_table(sock_net(skb->sk), filter.table_id);
++              mrt = __ipmr_get_table(sock_net(skb->sk), filter.table_id);
+               if (!mrt) {
+                       if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IPMR)
+                               return skb->len;
+@@ -2697,7 +2711,7 @@ static int rtm_to_ipmr_mfcc(struct net *net, struct nlmsghdr *nlh,
+                       break;
+               }
+       }
+-      mrt = ipmr_get_table(net, tblid);
++      mrt = __ipmr_get_table(net, tblid);
+       if (!mrt) {
+               ret = -ENOENT;
+               goto out;
+@@ -2902,13 +2916,15 @@ static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+       struct net *net = seq_file_net(seq);
+       struct mr_table *mrt;
+-      mrt = ipmr_get_table(net, RT_TABLE_DEFAULT);
+-      if (!mrt)
++      rcu_read_lock();
++      mrt = __ipmr_get_table(net, RT_TABLE_DEFAULT);
++      if (!mrt) {
++              rcu_read_unlock();
+               return ERR_PTR(-ENOENT);
++      }
+       iter->mrt = mrt;
+-      rcu_read_lock();
+       return mr_vif_seq_start(seq, pos);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch b/queue-5.10/kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch
new file mode 100644 (file)
index 0000000..99d99c0
--- /dev/null
@@ -0,0 +1,78 @@
+From df739d648270b8220f4fb5634a6c07cb3c53e072 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 16:43:09 +0100
+Subject: kcsan, seqlock: Fix incorrect assumption in read_seqbegin()
+
+From: Marco Elver <elver@google.com>
+
+[ Upstream commit 183ec5f26b2fc97a4a9871865bfe9b33c41fddb2 ]
+
+During testing of the preceding changes, I noticed that in some cases,
+current->kcsan_ctx.in_flat_atomic remained true until task exit. This is
+obviously wrong, because _all_ accesses for the given task will be
+treated as atomic, resulting in false negatives i.e. missed data races.
+
+Debugging led to fs/dcache.c, where we can see this usage of seqlock:
+
+       struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name)
+       {
+               struct dentry *dentry;
+               unsigned seq;
+
+               do {
+                       seq = read_seqbegin(&rename_lock);
+                       dentry = __d_lookup(parent, name);
+                       if (dentry)
+                               break;
+               } while (read_seqretry(&rename_lock, seq));
+       [...]
+
+As can be seen, read_seqretry() is never called if dentry != NULL;
+consequently, current->kcsan_ctx.in_flat_atomic will never be reset to
+false by read_seqretry().
+
+Give up on the wrong assumption of "assume closing read_seqretry()", and
+rely on the already-present annotations in read_seqcount_begin/retry().
+
+Fixes: 88ecd153be95 ("seqlock, kcsan: Add annotations for KCSAN")
+Signed-off-by: Marco Elver <elver@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241104161910.780003-6-elver@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/seqlock.h | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
+index 0928a60b8f825..9bb3e8a40e941 100644
+--- a/include/linux/seqlock.h
++++ b/include/linux/seqlock.h
+@@ -832,11 +832,7 @@ typedef struct {
+  */
+ static inline unsigned read_seqbegin(const seqlock_t *sl)
+ {
+-      unsigned ret = read_seqcount_begin(&sl->seqcount);
+-
+-      kcsan_atomic_next(0);  /* non-raw usage, assume closing read_seqretry() */
+-      kcsan_flat_atomic_begin();
+-      return ret;
++      return read_seqcount_begin(&sl->seqcount);
+ }
+ /**
+@@ -852,12 +848,6 @@ static inline unsigned read_seqbegin(const seqlock_t *sl)
+  */
+ static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
+ {
+-      /*
+-       * Assume not nested: read_seqretry() may be called multiple times when
+-       * completing read critical section.
+-       */
+-      kcsan_flat_atomic_end();
+-
+       return read_seqcount_retry(&sl->seqcount, start);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch b/queue-5.10/kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch
new file mode 100644 (file)
index 0000000..3a2e2c0
--- /dev/null
@@ -0,0 +1,51 @@
+From ab9cf49bdd29a4eb8aa3195b0cfac5b52c1da4b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Aug 2024 16:32:51 +0100
+Subject: kselftest/arm64: mte: fix printf type warnings about longs
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit 96dddb7b9406259baace9a1831e8da155311be6f ]
+
+When checking MTE tags, we print some diagnostic messages when the tests
+fail. Some variables uses there are "longs", however we only use "%x"
+for the format specifier.
+
+Update the format specifiers to "%lx", to match the variable types they
+are supposed to print.
+
+Fixes: f3b2a26ca78d ("kselftest/arm64: Verify mte tag inclusion via prctl")
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240816153251.2833702-9-andre.przywara@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/arm64/mte/check_tags_inclusion.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
+index deaef1f610768..74a3727f640de 100644
+--- a/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
++++ b/tools/testing/selftests/arm64/mte/check_tags_inclusion.c
+@@ -57,7 +57,7 @@ static int check_single_included_tags(int mem_type, int mode)
+                       ptr = (char *)mte_insert_tags(ptr, BUFFER_SIZE);
+                       /* Check tag value */
+                       if (MT_FETCH_TAG((uintptr_t)ptr) == tag) {
+-                              ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n",
++                              ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%x\n",
+                                              MT_FETCH_TAG((uintptr_t)ptr),
+                                              MT_INCLUDE_VALID_TAG(tag));
+                               result = KSFT_FAIL;
+@@ -89,7 +89,7 @@ static int check_multiple_included_tags(int mem_type, int mode)
+                       ptr = (char *)mte_insert_tags(ptr, BUFFER_SIZE);
+                       /* Check tag value */
+                       if (MT_FETCH_TAG((uintptr_t)ptr) < tag) {
+-                              ksft_print_msg("FAIL: wrong tag = 0x%x with include mask=0x%x\n",
++                              ksft_print_msg("FAIL: wrong tag = 0x%lx with include mask=0x%lx\n",
+                                              MT_FETCH_TAG((uintptr_t)ptr),
+                                              MT_INCLUDE_VALID_TAGS(excl_mask));
+                               result = KSFT_FAIL;
+-- 
+2.43.0
+
diff --git a/queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch b/queue-5.10/m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch
new file mode 100644 (file)
index 0000000..59bd550
--- /dev/null
@@ -0,0 +1,77 @@
+From fb5e1815b45c6e9e4bd39df57b6f24a18f94aeea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 22:43:15 +0100
+Subject: m68k: coldfire/device.c: only build FEC when HW macros are defined
+
+From: Antonio Quartulli <antonio@mandelbit.com>
+
+[ Upstream commit 63a24cf8cc330e5a68ebd2e20ae200096974c475 ]
+
+When CONFIG_FEC is set (due to COMPILE_TEST) along with
+CONFIG_M54xx, coldfire/device.c has compile errors due to
+missing MCFEC_* and MCF_IRQ_FEC_* symbols.
+
+Make the whole FEC blocks dependent on having the HW macros
+defined, rather than on CONFIG_FEC itself.
+
+This fix is very similar to commit e6e1e7b19fa1 ("m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined")
+
+Fixes: b7ce7f0d0efc ("m68knommu: merge common ColdFire FEC platform setup code")
+To: Greg Ungerer <gerg@linux-m68k.org>
+To: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: linux-m68k@lists.linux-m68k.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Antonio Quartulli <antonio@mandelbit.com>
+Signed-off-by: Greg Ungerer <gerg@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/coldfire/device.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c
+index a055616942a1e..d73d90452b123 100644
+--- a/arch/m68k/coldfire/device.c
++++ b/arch/m68k/coldfire/device.c
+@@ -93,7 +93,7 @@ static struct platform_device mcf_uart = {
+       .dev.platform_data      = mcf_uart_platform_data,
+ };
+-#if IS_ENABLED(CONFIG_FEC)
++#ifdef MCFFEC_BASE0
+ #ifdef CONFIG_M5441x
+ #define FEC_NAME      "enet-fec"
+@@ -145,6 +145,7 @@ static struct platform_device mcf_fec0 = {
+               .platform_data          = FEC_PDATA,
+       }
+ };
++#endif /* MCFFEC_BASE0 */
+ #ifdef MCFFEC_BASE1
+ static struct resource mcf_fec1_resources[] = {
+@@ -182,7 +183,6 @@ static struct platform_device mcf_fec1 = {
+       }
+ };
+ #endif /* MCFFEC_BASE1 */
+-#endif /* CONFIG_FEC */
+ #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
+ /*
+@@ -583,12 +583,12 @@ static struct platform_device mcf_esdhc = {
+ static struct platform_device *mcf_devices[] __initdata = {
+       &mcf_uart,
+-#if IS_ENABLED(CONFIG_FEC)
++#ifdef MCFFEC_BASE0
+       &mcf_fec0,
++#endif
+ #ifdef MCFFEC_BASE1
+       &mcf_fec1,
+ #endif
+-#endif
+ #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
+       &mcf_qspi,
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch b/queue-5.10/m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch
new file mode 100644 (file)
index 0000000..eb27a9e
--- /dev/null
@@ -0,0 +1,37 @@
+From 3594986f942bb2c349300c9eb30995082e541a3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 09:24:35 +0200
+Subject: m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x
+
+From: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
+
+[ Upstream commit f212140962c93cd5da43283a18e31681540fc23d ]
+
+Fix a typo in the CONFIG_M5441x preprocessor condition, where the GPIO
+register offset was incorrectly set to 8 instead of 0. This prevented
+proper GPIO configuration for m5441x targets.
+
+Fixes: bea8bcb12da0 ("m68knommu: Add support for the Coldfire m5441x.")
+Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@yoseli.org>
+Signed-off-by: Greg Ungerer <gerg@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/include/asm/mcfgpio.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h
+index 27f32cc81da6b..02049568198c9 100644
+--- a/arch/m68k/include/asm/mcfgpio.h
++++ b/arch/m68k/include/asm/mcfgpio.h
+@@ -144,7 +144,7 @@ static inline void gpio_free(unsigned gpio)
+  * read-modify-write as well as those controlled by the EPORT and GPIO modules.
+  */
+ #define MCFGPIO_SCR_START             40
+-#elif defined(CONFIGM5441x)
++#elif defined(CONFIG_M5441x)
+ /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */
+ #define MCFGPIO_SCR_START             0
+ #else
+-- 
+2.43.0
+
diff --git a/queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch b/queue-5.10/m68k-mvme147-fix-scsi-controller-irq-numbers.patch
new file mode 100644 (file)
index 0000000..ed5e6f2
--- /dev/null
@@ -0,0 +1,46 @@
+From 0fe4206ac13b584c8c3ad8aa590daf93d1e15cc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 13:29:47 +1000
+Subject: m68k: mvme147: Fix SCSI controller IRQ numbers
+
+From: Daniel Palmer <daniel@0x0f.com>
+
+[ Upstream commit 47bc874427382018fa2e3e982480e156271eee70 ]
+
+Sometime long ago the m68k IRQ code was refactored and the interrupt
+numbers for SCSI controller on this board ended up wrong, and it hasn't
+worked since.
+
+The PCC adds 0x40 to the vector for its interrupts so they end up in
+the user interrupt range. Hence, the kernel number should be the kernel
+offset for user interrupt range + the PCC interrupt number.
+
+Fixes: 200a3d352cd5 ("[PATCH] m68k: convert VME irq code")
+Signed-off-by: Daniel Palmer <daniel@0x0f.com>
+Reviewed-by: Finn Thain <fthain@linux-m68k.org>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/0e7636a21a0274eea35bfd5d874459d5078e97cc.1727926187.git.fthain@linux-m68k.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/include/asm/mvme147hw.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h
+index e28eb1c0e0bfb..dbf88059e47a4 100644
+--- a/arch/m68k/include/asm/mvme147hw.h
++++ b/arch/m68k/include/asm/mvme147hw.h
+@@ -93,8 +93,8 @@ struct pcc_regs {
+ #define M147_SCC_B_ADDR               0xfffe3000
+ #define M147_SCC_PCLK         5000000
+-#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45)
+-#define MVME147_IRQ_SCSI_DMA  (IRQ_USER+0x46)
++#define MVME147_IRQ_SCSI_PORT (IRQ_USER + 5)
++#define MVME147_IRQ_SCSI_DMA  (IRQ_USER + 6)
+ /* SCC interrupts, for MVME147 */
+-- 
+2.43.0
+
diff --git a/queue-5.10/m68k-mvme147-reinstate-early-console.patch b/queue-5.10/m68k-mvme147-reinstate-early-console.patch
new file mode 100644 (file)
index 0000000..274fe96
--- /dev/null
@@ -0,0 +1,113 @@
+From 89667d369fb007a766172181a6f83047e3396498 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 10:51:24 +1100
+Subject: m68k: mvme147: Reinstate early console
+
+From: Daniel Palmer <daniel@0x0f.com>
+
+[ Upstream commit 077b33b9e2833ff25050d986178a2c4c4036cbac ]
+
+Commit a38eaa07a0ce ("m68k/mvme147: config.c - Remove unused
+functions"), removed the console functionality for the mvme147 instead
+of wiring it up to an early console.  Put the console write function
+back and wire it up like mvme16x does so it's possible to see Linux boot
+on this fine hardware once more.
+
+Fixes: a38eaa07a0ce ("m68k/mvme147: config.c - Remove unused functions")
+Signed-off-by: Daniel Palmer <daniel@0x0f.com>
+Co-developed-by: Finn Thain <fthain@linux-m68k.org>
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/a82e8f0068a8722996a0ccfe666abb5e0a5c120d.1730850684.git.fthain@linux-m68k.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/kernel/early_printk.c |  5 ++++-
+ arch/m68k/mvme147/config.c      | 30 ++++++++++++++++++++++++++++++
+ arch/m68k/mvme147/mvme147.h     |  6 ++++++
+ 3 files changed, 40 insertions(+), 1 deletion(-)
+ create mode 100644 arch/m68k/mvme147/mvme147.h
+
+diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
+index 3cc944df04f65..f11ef9f1f56fc 100644
+--- a/arch/m68k/kernel/early_printk.c
++++ b/arch/m68k/kernel/early_printk.c
+@@ -13,6 +13,7 @@
+ #include <asm/setup.h>
++#include "../mvme147/mvme147.h"
+ #include "../mvme16x/mvme16x.h"
+ asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
+@@ -22,7 +23,9 @@ static void __ref debug_cons_write(struct console *c,
+ {
+ #if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \
+       defined(CONFIG_COLDFIRE))
+-      if (MACH_IS_MVME16x)
++      if (MACH_IS_MVME147)
++              mvme147_scc_write(c, s, n);
++      else if (MACH_IS_MVME16x)
+               mvme16x_cons_write(c, s, n);
+       else
+               debug_cons_nputs(s, n);
+diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
+index aab7880e078df..4456591f5b7fe 100644
+--- a/arch/m68k/mvme147/config.c
++++ b/arch/m68k/mvme147/config.c
+@@ -35,6 +35,7 @@
+ #include <asm/machdep.h>
+ #include <asm/mvme147hw.h>
++#include "mvme147.h"
+ static void mvme147_get_model(char *model);
+ extern void mvme147_sched_init(irq_handler_t handler);
+@@ -188,3 +189,32 @@ int mvme147_hwclk(int op, struct rtc_time *t)
+       }
+       return 0;
+ }
++
++static void scc_delay(void)
++{
++      __asm__ __volatile__ ("nop; nop;");
++}
++
++static void scc_write(char ch)
++{
++      do {
++              scc_delay();
++      } while (!(in_8(M147_SCC_A_ADDR) & BIT(2)));
++      scc_delay();
++      out_8(M147_SCC_A_ADDR, 8);
++      scc_delay();
++      out_8(M147_SCC_A_ADDR, ch);
++}
++
++void mvme147_scc_write(struct console *co, const char *str, unsigned int count)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      while (count--) {
++              if (*str == '\n')
++                      scc_write('\r');
++              scc_write(*str++);
++      }
++      local_irq_restore(flags);
++}
+diff --git a/arch/m68k/mvme147/mvme147.h b/arch/m68k/mvme147/mvme147.h
+new file mode 100644
+index 0000000000000..140bc98b0102a
+--- /dev/null
++++ b/arch/m68k/mvme147/mvme147.h
+@@ -0,0 +1,6 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++struct console;
++
++/* config.c */
++void mvme147_scc_write(struct console *co, const char *str, unsigned int count);
+-- 
+2.43.0
+
diff --git a/queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch b/queue-5.10/m68k-mvme16x-add-and-use-mvme16x.h.patch
new file mode 100644 (file)
index 0000000..237316d
--- /dev/null
@@ -0,0 +1,76 @@
+From 8b82bd8a40c01bdf2109acd4d3bb15bb183f322b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 16:08:25 +0200
+Subject: m68k: mvme16x: Add and use "mvme16x.h"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+[ Upstream commit dcec33c1fc4ab63983d93ffb0d82b68fc5775b88 ]
+
+When building with W=1:
+
+    arch/m68k/mvme16x/config.c:208:6: warning: no previous prototype for â€˜mvme16x_cons_write’ [-Wmissing-prototypes]
+      208 | void mvme16x_cons_write(struct console *co, const char *str, unsigned count)
+         |      ^~~~~~~~~~~~~~~~~~
+
+Fix this by introducing a new header file "mvme16x.h" for holding the
+prototypes of functions implemented in arch/m68k/mvme16x/.
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/6200cc3b26fad215c4524748af04692e38c5ecd2.1694613528.git.geert@linux-m68k.org
+Stable-dep-of: 077b33b9e283 ("m68k: mvme147: Reinstate early console")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/kernel/early_printk.c | 4 ++--
+ arch/m68k/mvme16x/config.c      | 2 ++
+ arch/m68k/mvme16x/mvme16x.h     | 6 ++++++
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+ create mode 100644 arch/m68k/mvme16x/mvme16x.h
+
+diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
+index 7d3fe08a48eb0..3cc944df04f65 100644
+--- a/arch/m68k/kernel/early_printk.c
++++ b/arch/m68k/kernel/early_printk.c
+@@ -12,8 +12,8 @@
+ #include <linux/string.h>
+ #include <asm/setup.h>
+-extern void mvme16x_cons_write(struct console *co,
+-                             const char *str, unsigned count);
++
++#include "../mvme16x/mvme16x.h"
+ asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
+diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
+index d43d128b77471..e26ee07dec9e2 100644
+--- a/arch/m68k/mvme16x/config.c
++++ b/arch/m68k/mvme16x/config.c
+@@ -38,6 +38,8 @@
+ #include <asm/machdep.h>
+ #include <asm/mvme16xhw.h>
++#include "mvme16x.h"
++
+ extern t_bdid mvme_bdid;
+ static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
+diff --git a/arch/m68k/mvme16x/mvme16x.h b/arch/m68k/mvme16x/mvme16x.h
+new file mode 100644
+index 0000000000000..159c34b700394
+--- /dev/null
++++ b/arch/m68k/mvme16x/mvme16x.h
+@@ -0,0 +1,6 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++struct console;
++
++/* config.c */
++void mvme16x_cons_write(struct console *co, const char *str, unsigned count);
+-- 
+2.43.0
+
diff --git a/queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch b/queue-5.10/marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch
new file mode 100644 (file)
index 0000000..16791b2
--- /dev/null
@@ -0,0 +1,76 @@
+From 868cadd6911bb2cf91625e7d2ab5283583bcff9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Nov 2024 23:06:58 +0300
+Subject: marvell: pxa168_eth: fix call balance of pep->clk handling routines
+
+From: Vitalii Mordan <mordan@ispras.ru>
+
+[ Upstream commit b032ae57d4fe2b2445e3bc190db6fcaa8c102f68 ]
+
+If the clock pep->clk was not enabled in pxa168_eth_probe,
+it should not be disabled in any path.
+
+Conversely, if it was enabled in pxa168_eth_probe, it must be disabled
+in all error paths to ensure proper cleanup.
+
+Use the devm_clk_get_enabled helper function to ensure proper call balance
+for pep->clk.
+
+Found by Linux Verification Center (linuxtesting.org) with Klever.
+
+Fixes: a49f37eed22b ("net: add Fast Ethernet driver for PXA168.")
+Signed-off-by: Vitalii Mordan <mordan@ispras.ru>
+Link: https://patch.msgid.link/20241121200658.2203871-1-mordan@ispras.ru
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/pxa168_eth.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
+index 3712e1786091f..cf867b8f43808 100644
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -1397,18 +1397,15 @@ static int pxa168_eth_probe(struct platform_device *pdev)
+       printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+-      clk = devm_clk_get(&pdev->dev, NULL);
++      clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(clk)) {
+-              dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n");
++              dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n");
+               return -ENODEV;
+       }
+-      clk_prepare_enable(clk);
+       dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
+-      if (!dev) {
+-              err = -ENOMEM;
+-              goto err_clk;
+-      }
++      if (!dev)
++              return -ENOMEM;
+       platform_set_drvdata(pdev, dev);
+       pep = netdev_priv(dev);
+@@ -1523,8 +1520,6 @@ static int pxa168_eth_probe(struct platform_device *pdev)
+       mdiobus_free(pep->smi_bus);
+ err_netdev:
+       free_netdev(dev);
+-err_clk:
+-      clk_disable_unprepare(clk);
+       return err;
+ }
+@@ -1541,7 +1536,6 @@ static int pxa168_eth_remove(struct platform_device *pdev)
+       if (dev->phydev)
+               phy_disconnect(dev->phydev);
+-      clk_disable_unprepare(pep->clk);
+       mdiobus_unregister(pep->smi_bus);
+       mdiobus_free(pep->smi_bus);
+       cancel_work_sync(&pep->tx_timeout_task);
+-- 
+2.43.0
+
diff --git a/queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch b/queue-5.10/media-atomisp-add-check-for-rgby_data-memory-allocat.patch
new file mode 100644 (file)
index 0000000..932eba6
--- /dev/null
@@ -0,0 +1,42 @@
+From 39632f4ffa97847fd215d7fcd682ebc851538e1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 22:50:51 +0800
+Subject: media: atomisp: Add check for rgby_data memory allocation failure
+
+From: Li Huafei <lihuafei1@huawei.com>
+
+[ Upstream commit ed61c59139509f76d3592683c90dc3fdc6e23cd6 ]
+
+In ia_css_3a_statistics_allocate(), there is no check on the allocation
+result of the rgby_data memory. If rgby_data is not successfully
+allocated, it may trigger the assert(host_stats->rgby_data) assertion in
+ia_css_s3a_hmem_decode(). Adding a check to fix this potential issue.
+
+Fixes: a49d25364dfb ("staging/atomisp: Add support for the Intel IPU v2")
+Signed-off-by: Li Huafei <lihuafei1@huawei.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Link: https://lore.kernel.org/r/20241104145051.3088231-1-lihuafei1@huawei.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/atomisp/pci/sh_css_params.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
+index 90aa8fc999ef8..34d8ffb7742d3 100644
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
+@@ -4356,6 +4356,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
+               goto err;
+       /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */
+       me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL);
++      if (!me->rgby_data)
++              goto err;
+       IA_CSS_LEAVE("return=%p", me);
+       return me;
+-- 
+2.43.0
+
diff --git a/queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch b/queue-5.10/media-atomisp-remove-ifdef-has_no_hmem.patch
new file mode 100644 (file)
index 0000000..2818668
--- /dev/null
@@ -0,0 +1,150 @@
+From a534512afc9162bfb9911bfea96df9d749347a35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Nov 2021 07:19:06 +0000
+Subject: media: atomisp: remove #ifdef HAS_NO_HMEM
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 63705da3dfc8922a2dbfc3c805a5faadb4416954 ]
+
+This is not defined anywhere, so, solve the ifdefs, getting
+rid of them.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: ed61c5913950 ("media: atomisp: Add check for rgby_data memory allocation failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c   |  2 --
+ .../raw_aa_binning_1.0/ia_css_raa.host.c               |  2 --
+ .../pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c      |  5 -----
+ .../media/atomisp/pci/runtime/binary/src/binary.c      |  4 ----
+ drivers/staging/media/atomisp/pci/sh_css_params.c      | 10 ----------
+ 5 files changed, 23 deletions(-)
+
+diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
+index 82aa69b74677c..2091f001502d4 100644
+--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
++++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
+@@ -13,7 +13,6 @@
+  * more details.
+  */
+-#if !defined(HAS_NO_HMEM)
+ #include "ia_css_types.h"
+ #include "sh_css_internal.h"
+@@ -63,4 +62,3 @@ ia_css_bh_encode(
+           uDIGIT_FITTING(from->ae_y_coef_b, 16, SH_CSS_AE_YCOEF_SHIFT);
+ }
+-#endif
+diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
+index 29c707ecf9f3b..9b756daddee06 100644
+--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
++++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
+@@ -13,7 +13,6 @@
+  * more details.
+  */
+-#if !defined(HAS_NO_HMEM)
+ #include "ia_css_types.h"
+ #include "sh_css_internal.h"
+@@ -32,4 +31,3 @@ ia_css_raa_encode(
+       (void)from;
+ }
+-#endif
+diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
+index ba52c80df4a58..bd7b89d9475bf 100644
+--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
++++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
+@@ -227,10 +227,6 @@ ia_css_s3a_hmem_decode(
+     struct ia_css_3a_statistics *host_stats,
+     const struct ia_css_bh_table *hmem_buf)
+ {
+-#if defined(HAS_NO_HMEM)
+-      (void)host_stats;
+-      (void)hmem_buf;
+-#else
+       struct ia_css_3a_rgby_output    *out_ptr;
+       int                     i;
+@@ -291,7 +287,6 @@ ia_css_s3a_hmem_decode(
+       out_ptr[0].g -= diff;
+       out_ptr[0].b -= diff;
+       out_ptr[0].y -= diff;
+-#endif
+ }
+ void
+diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
+index 060d387495704..002bd8cf28634 100644
+--- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
++++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
+@@ -805,11 +805,7 @@ ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
+       s3a_info->deci_factor_log2  = binary->deci_factor_log2;
+       s3a_info->elem_bit_depth    = SH_CSS_BAYER_BITS;
+       s3a_info->use_dmem          = binary->info->sp.s3a.s3atbl_use_dmem;
+-#if defined(HAS_NO_HMEM)
+-      s3a_info->has_histogram     = 1;
+-#else
+       s3a_info->has_histogram     = 0;
+-#endif
+       IA_CSS_LEAVE_ERR_PRIVATE(err);
+       return err;
+ }
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
+index 8d6514c45eeb6..90aa8fc999ef8 100644
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
+@@ -16,12 +16,10 @@
+ #include "gdc_device.h"               /* gdc_lut_store(), ... */
+ #include "isp.h"                      /* ISP_VEC_ELEMBITS */
+ #include "vamem.h"
+-#if !defined(HAS_NO_HMEM)
+ #ifndef __INLINE_HMEM__
+ #define __INLINE_HMEM__
+ #endif
+ #include "hmem.h"
+-#endif /* !defined(HAS_NO_HMEM) */
+ #define IA_CSS_INCLUDE_PARAMETERS
+ #define IA_CSS_INCLUDE_ACC_PARAMETERS
+@@ -1513,10 +1511,8 @@ ia_css_translate_3a_statistics(
+               ia_css_s3a_vmem_decode(host_stats, isp_stats->vmem_stats_hi,
+                                      isp_stats->vmem_stats_lo);
+       }
+-#if !defined(HAS_NO_HMEM)
+       IA_CSS_LOG("3A: HMEM");
+       ia_css_s3a_hmem_decode(host_stats, isp_stats->hmem_stats);
+-#endif
+       IA_CSS_LEAVE("void");
+ }
+@@ -2255,9 +2251,7 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
+               me->vmem_size = ISP_S3ATBL_HI_LO_STRIDE_BYTES *
+                               grid->aligned_height;
+       }
+-#if !defined(HAS_NO_HMEM)
+       me->hmem_size = sizeof_hmem(HMEM0_ID);
+-#endif
+       /* All subsections need to be aligned to the system bus width */
+       me->dmem_size = CEIL_MUL(me->dmem_size, HIVE_ISP_DDR_WORD_BYTES);
+@@ -4360,12 +4354,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
+       me->data = kvmalloc(grid_size * sizeof(*me->data), GFP_KERNEL);
+       if (!me->data)
+               goto err;
+-#if !defined(HAS_NO_HMEM)
+       /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */
+       me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL);
+-#else
+-      me->rgby_data = NULL;
+-#endif
+       IA_CSS_LEAVE("return=%p", me);
+       return me;
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch b/queue-5.10/mfd-da9052-spi-change-read-mask-to-write-mask.patch
new file mode 100644 (file)
index 0000000..b5cac8b
--- /dev/null
@@ -0,0 +1,38 @@
+From 49fad7370f136069cb8497455bdf95747649598e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Sep 2024 12:19:53 +0200
+Subject: mfd: da9052-spi: Change read-mask to write-mask
+
+From: Marcus Folkesson <marcus.folkesson@gmail.com>
+
+[ Upstream commit 2e3378f6c79a1b3f7855ded1ef306ea4406352ed ]
+
+Driver has mixed up the R/W bit.
+The LSB bit is set on write rather than read.
+Change it to avoid nasty things to happen.
+
+Fixes: e9e9d3973594 ("mfd: da9052: Avoid setting read_flag_mask for da9052-i2c driver")
+Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
+Link: https://lore.kernel.org/r/20240925-da9052-v2-1-f243e4505b07@gmail.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/da9052-spi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
+index 5faf3766a5e20..06c500bf4d57e 100644
+--- a/drivers/mfd/da9052-spi.c
++++ b/drivers/mfd/da9052-spi.c
+@@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi)
+       spi_set_drvdata(spi, da9052);
+       config = da9052_regmap_config;
+-      config.read_flag_mask = 1;
++      config.write_flag_mask = 1;
+       config.reg_bits = 7;
+       config.pad_bits = 1;
+       config.val_bits = 8;
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch
new file mode 100644 (file)
index 0000000..12bb0bf
--- /dev/null
@@ -0,0 +1,189 @@
+From 4546cf9eca4055c0ffdb1136e9461a7344536058 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 01:17:40 +0300
+Subject: mfd: intel_soc_pmic_bxtwc: Use dev_err_probe()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit d30e2c30a43de950cfd3690f24342a39034221c4 ]
+
+Simplify the mux error path a bit by using dev_err_probe().
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220628221747.33956-4-andriy.shevchenko@linux.intel.com
+Stable-dep-of: 686fb77712a4 ("mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel_soc_pmic_bxtwc.c | 86 +++++++++---------------------
+ 1 file changed, 26 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
+index eba89780dbe75..3b41cc2d1ec01 100644
+--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
+@@ -410,12 +410,9 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
+       int irq;
+       irq = regmap_irq_get_virq(pdata, pirq);
+-      if (irq < 0) {
+-              dev_err(pmic->dev,
+-                      "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
+-                      pirq, chip->name, irq);
+-              return irq;
+-      }
++      if (irq < 0)
++              return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n",
++                                   pirq, chip->name);
+       return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
+                                       0, chip, data);
+@@ -423,6 +420,7 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
+ static int bxtwc_probe(struct platform_device *pdev)
+ {
++      struct device *dev = &pdev->dev;
+       int ret;
+       acpi_handle handle;
+       acpi_status status;
+@@ -431,15 +429,10 @@ static int bxtwc_probe(struct platform_device *pdev)
+       handle = ACPI_HANDLE(&pdev->dev);
+       status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
+-      if (ACPI_FAILURE(status)) {
+-              dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
+-              return -ENODEV;
+-      }
+-      if (hrv != BROXTON_PMIC_WC_HRV) {
+-              dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
+-                      hrv);
+-              return -ENODEV;
+-      }
++      if (ACPI_FAILURE(status))
++              return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n");
++      if (hrv != BROXTON_PMIC_WC_HRV)
++              return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv);
+       pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
+       if (!pmic)
+@@ -459,40 +452,31 @@ static int bxtwc_probe(struct platform_device *pdev)
+       pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
+                                       &bxtwc_regmap_config);
+-      if (IS_ERR(pmic->regmap)) {
+-              ret = PTR_ERR(pmic->regmap);
+-              dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
+-              return ret;
+-      }
++      if (IS_ERR(pmic->regmap))
++              return dev_err_probe(dev, PTR_ERR(pmic->regmap), "Failed to initialise regmap\n");
+       ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
+                                      IRQF_ONESHOT | IRQF_SHARED,
+                                      0, &bxtwc_regmap_irq_chip,
+                                      &pmic->irq_chip_data);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+                                        BXTWC_PWRBTN_LVL1_IRQ,
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_pwrbtn,
+                                        &pmic->irq_chip_data_pwrbtn);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+                                        BXTWC_TMU_LVL1_IRQ,
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_tmu,
+                                        &pmic->irq_chip_data_tmu);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
+       /* Add chained IRQ handler for BCU IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+@@ -500,12 +484,8 @@ static int bxtwc_probe(struct platform_device *pdev)
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_bcu,
+                                        &pmic->irq_chip_data_bcu);
+-
+-
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
+       /* Add chained IRQ handler for ADC IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+@@ -513,12 +493,8 @@ static int bxtwc_probe(struct platform_device *pdev)
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_adc,
+                                        &pmic->irq_chip_data_adc);
+-
+-
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
+       /* Add chained IRQ handler for CHGR IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+@@ -526,12 +502,8 @@ static int bxtwc_probe(struct platform_device *pdev)
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_chgr,
+                                        &pmic->irq_chip_data_chgr);
+-
+-
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
+       /* Add chained IRQ handler for CRIT IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+@@ -539,19 +511,13 @@ static int bxtwc_probe(struct platform_device *pdev)
+                                        IRQF_ONESHOT,
+                                        &bxtwc_regmap_irq_chip_crit,
+                                        &pmic->irq_chip_data_crit);
+-
+-
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n");
+       ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
+                                  ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to add devices\n");
+-              return ret;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add devices\n");
+       ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
+       if (ret) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch
new file mode 100644 (file)
index 0000000..3ddcf40
--- /dev/null
@@ -0,0 +1,118 @@
+From 05cb51dbb482c87c2c8d086e41eabe7a11e816c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Oct 2024 22:27:06 +0300
+Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 0350d783ab888cb1cb48ced36cc28b372723f1a4 ]
+
+While design wise the idea of converting the driver to use
+the hierarchy of the IRQ chips is correct, the implementation
+has (inherited) flaws. This was unveiled when platform_get_irq()
+had started WARN() on IRQ 0 that is supposed to be a Linux
+IRQ number (also known as vIRQ).
+
+Rework the driver to respect IRQ domain when creating each MFD
+device separately, as the domain is not the same for all of them.
+
+Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips")
+Tested-by: Zhang Ning <zhangn1985@outlook.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20241005193029.1929139-4-andriy.shevchenko@linux.intel.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel_soc_pmic_bxtwc.c | 54 +++++++++++++++++-------------
+ 1 file changed, 30 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
+index 8b55f839a946b..6d708d6f7281a 100644
+--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
+@@ -230,21 +230,11 @@ static struct resource tmu_resources[] = {
+ };
+ static struct mfd_cell bxt_wc_dev[] = {
+-      {
+-              .name = "bxt_wcove_gpadc",
+-              .num_resources = ARRAY_SIZE(adc_resources),
+-              .resources = adc_resources,
+-      },
+       {
+               .name = "bxt_wcove_thermal",
+               .num_resources = ARRAY_SIZE(thermal_resources),
+               .resources = thermal_resources,
+       },
+-      {
+-              .name = "bxt_wcove_bcu",
+-              .num_resources = ARRAY_SIZE(bcu_resources),
+-              .resources = bcu_resources,
+-      },
+       {
+               .name = "bxt_wcove_gpio",
+               .num_resources = ARRAY_SIZE(gpio_resources),
+@@ -263,6 +253,22 @@ static const struct mfd_cell bxt_wc_tmu_dev[] = {
+       },
+ };
++static const struct mfd_cell bxt_wc_bcu_dev[] = {
++      {
++              .name = "bxt_wcove_bcu",
++              .num_resources = ARRAY_SIZE(bcu_resources),
++              .resources = bcu_resources,
++      },
++};
++
++static const struct mfd_cell bxt_wc_adc_dev[] = {
++      {
++              .name = "bxt_wcove_gpadc",
++              .num_resources = ARRAY_SIZE(adc_resources),
++              .resources = adc_resources,
++      },
++};
++
+ static struct mfd_cell bxt_wc_chgr_dev[] = {
+       {
+               .name = "bxt_wcove_usbc",
+@@ -504,23 +510,23 @@ static int bxtwc_probe(struct platform_device *pdev)
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
+-      /* Add chained IRQ handler for BCU IRQs */
+-      ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+-                                       BXTWC_BCU_LVL1_IRQ,
+-                                       IRQF_ONESHOT,
+-                                       &bxtwc_regmap_irq_chip_bcu,
+-                                       &pmic->irq_chip_data_bcu);
++      ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev),
++                                      pmic->irq_chip_data,
++                                      BXTWC_BCU_LVL1_IRQ,
++                                      IRQF_ONESHOT,
++                                      &bxtwc_regmap_irq_chip_bcu,
++                                      &pmic->irq_chip_data_bcu);
+       if (ret)
+-              return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
++              return ret;
+-      /* Add chained IRQ handler for ADC IRQs */
+-      ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+-                                       BXTWC_ADC_LVL1_IRQ,
+-                                       IRQF_ONESHOT,
+-                                       &bxtwc_regmap_irq_chip_adc,
+-                                       &pmic->irq_chip_data_adc);
++      ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev),
++                                      pmic->irq_chip_data,
++                                      BXTWC_ADC_LVL1_IRQ,
++                                      IRQF_ONESHOT,
++                                      &bxtwc_regmap_irq_chip_adc,
++                                      &pmic->irq_chip_data_adc);
+       if (ret)
+-              return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
++              return ret;
+       ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev),
+                                       pmic->irq_chip_data,
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch
new file mode 100644 (file)
index 0000000..8726eda
--- /dev/null
@@ -0,0 +1,147 @@
+From 08f39765067b5286fd01ac15da91837242ff723e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Oct 2024 22:27:05 +0300
+Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 9b79d59e6b2b515eb9a22bc469ef7b8f0904fc73 ]
+
+While design wise the idea of converting the driver to use
+the hierarchy of the IRQ chips is correct, the implementation
+has (inherited) flaws. This was unveiled when platform_get_irq()
+had started WARN() on IRQ 0 that is supposed to be a Linux
+IRQ number (also known as vIRQ).
+
+Rework the driver to respect IRQ domain when creating each MFD
+device separately, as the domain is not the same for all of them.
+
+Fixes: 957ae5098185 ("platform/x86: Add Whiskey Cove PMIC TMU support")
+Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips")
+Reported-by: Zhang Ning <zhangn1985@outlook.com>
+Closes: https://lore.kernel.org/r/TY2PR01MB3322FEDCDC048B7D3794F922CDBA2@TY2PR01MB3322.jpnprd01.prod.outlook.com
+Tested-by: Zhang Ning <zhangn1985@outlook.com>
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20241005193029.1929139-3-andriy.shevchenko@linux.intel.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel_soc_pmic_bxtwc.c     | 31 ++++++++++++++------------
+ drivers/platform/x86/intel_bxtwc_tmu.c | 22 +++++-------------
+ 2 files changed, 23 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
+index 82c71b475a7e0..8b55f839a946b 100644
+--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
+@@ -245,12 +245,6 @@ static struct mfd_cell bxt_wc_dev[] = {
+               .num_resources = ARRAY_SIZE(bcu_resources),
+               .resources = bcu_resources,
+       },
+-      {
+-              .name = "bxt_wcove_tmu",
+-              .num_resources = ARRAY_SIZE(tmu_resources),
+-              .resources = tmu_resources,
+-      },
+-
+       {
+               .name = "bxt_wcove_gpio",
+               .num_resources = ARRAY_SIZE(gpio_resources),
+@@ -261,6 +255,14 @@ static struct mfd_cell bxt_wc_dev[] = {
+       },
+ };
++static const struct mfd_cell bxt_wc_tmu_dev[] = {
++      {
++              .name = "bxt_wcove_tmu",
++              .num_resources = ARRAY_SIZE(tmu_resources),
++              .resources = tmu_resources,
++      },
++};
++
+ static struct mfd_cell bxt_wc_chgr_dev[] = {
+       {
+               .name = "bxt_wcove_usbc",
+@@ -485,6 +487,15 @@ static int bxtwc_probe(struct platform_device *pdev)
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
++      ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev),
++                                      pmic->irq_chip_data,
++                                      BXTWC_TMU_LVL1_IRQ,
++                                      IRQF_ONESHOT,
++                                      &bxtwc_regmap_irq_chip_tmu,
++                                      &pmic->irq_chip_data_tmu);
++      if (ret)
++              return ret;
++
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+                                        BXTWC_PWRBTN_LVL1_IRQ,
+                                        IRQF_ONESHOT,
+@@ -493,14 +504,6 @@ static int bxtwc_probe(struct platform_device *pdev)
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
+-      ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+-                                       BXTWC_TMU_LVL1_IRQ,
+-                                       IRQF_ONESHOT,
+-                                       &bxtwc_regmap_irq_chip_tmu,
+-                                       &pmic->irq_chip_data_tmu);
+-      if (ret)
+-              return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
+-
+       /* Add chained IRQ handler for BCU IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+                                        BXTWC_BCU_LVL1_IRQ,
+diff --git a/drivers/platform/x86/intel_bxtwc_tmu.c b/drivers/platform/x86/intel_bxtwc_tmu.c
+index 7ccf583649e6b..3c9778366d930 100644
+--- a/drivers/platform/x86/intel_bxtwc_tmu.c
++++ b/drivers/platform/x86/intel_bxtwc_tmu.c
+@@ -48,9 +48,8 @@ static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data)
+ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
+ {
+       struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+-      struct regmap_irq_chip_data *regmap_irq_chip;
+       struct wcove_tmu *wctmu;
+-      int ret, virq, irq;
++      int ret;
+       wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL);
+       if (!wctmu)
+@@ -59,27 +58,18 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
+       wctmu->dev = &pdev->dev;
+       wctmu->regmap = pmic->regmap;
+-      irq = platform_get_irq(pdev, 0);
+-      if (irq < 0)
+-              return irq;
++      wctmu->irq = platform_get_irq(pdev, 0);
++      if (wctmu->irq < 0)
++              return wctmu->irq;
+-      regmap_irq_chip = pmic->irq_chip_data_tmu;
+-      virq = regmap_irq_get_virq(regmap_irq_chip, irq);
+-      if (virq < 0) {
+-              dev_err(&pdev->dev,
+-                      "failed to get virtual interrupt=%d\n", irq);
+-              return virq;
+-      }
+-
+-      ret = devm_request_threaded_irq(&pdev->dev, virq,
++      ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq,
+                                       NULL, bxt_wcove_tmu_irq_handler,
+                                       IRQF_ONESHOT, "bxt_wcove_tmu", wctmu);
+       if (ret) {
+               dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n",
+-                                                      ret, virq);
++                      ret, wctmu->irq);
+               return ret;
+       }
+-      wctmu->irq = virq;
+       /* Unmask TMU second level Wake & System alarm */
+       regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch b/queue-5.10/mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch
new file mode 100644 (file)
index 0000000..54d7a67
--- /dev/null
@@ -0,0 +1,142 @@
+From 6148a7da81d658b0f698dc91d5f792a196509df6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Oct 2024 22:27:04 +0300
+Subject: mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 686fb77712a4bc94b76a0c5ae74c60118b7a0d79 ]
+
+While design wise the idea of converting the driver to use
+the hierarchy of the IRQ chips is correct, the implementation
+has (inherited) flaws. This was unveiled when platform_get_irq()
+had started WARN() on IRQ 0 that is supposed to be a Linux
+IRQ number (also known as vIRQ).
+
+Rework the driver to respect IRQ domain when creating each MFD
+device separately, as the domain is not the same for all of them.
+
+Fixes: 9c6235c86332 ("mfd: intel_soc_pmic_bxtwc: Add bxt_wcove_usbc device")
+Fixes: d2061f9cc32d ("usb: typec: add driver for Intel Whiskey Cove PMIC USB Type-C PHY")
+Fixes: 57129044f504 ("mfd: intel_soc_pmic_bxtwc: Use chained IRQs for second level IRQ chips")
+Reported-by: Zhang Ning <zhangn1985@outlook.com>
+Closes: https://lore.kernel.org/r/TY2PR01MB3322FEDCDC048B7D3794F922CDBA2@TY2PR01MB3322.jpnprd01.prod.outlook.com
+Tested-by: Zhang Ning <zhangn1985@outlook.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20241005193029.1929139-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel_soc_pmic_bxtwc.c | 57 +++++++++++++++++++++---------
+ drivers/usb/typec/tcpm/wcove.c     |  4 ---
+ 2 files changed, 40 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
+index 3b41cc2d1ec01..82c71b475a7e0 100644
+--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
++++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
+@@ -240,16 +240,6 @@ static struct mfd_cell bxt_wc_dev[] = {
+               .num_resources = ARRAY_SIZE(thermal_resources),
+               .resources = thermal_resources,
+       },
+-      {
+-              .name = "bxt_wcove_usbc",
+-              .num_resources = ARRAY_SIZE(usbc_resources),
+-              .resources = usbc_resources,
+-      },
+-      {
+-              .name = "bxt_wcove_ext_charger",
+-              .num_resources = ARRAY_SIZE(charger_resources),
+-              .resources = charger_resources,
+-      },
+       {
+               .name = "bxt_wcove_bcu",
+               .num_resources = ARRAY_SIZE(bcu_resources),
+@@ -271,6 +261,19 @@ static struct mfd_cell bxt_wc_dev[] = {
+       },
+ };
++static struct mfd_cell bxt_wc_chgr_dev[] = {
++      {
++              .name = "bxt_wcove_usbc",
++              .num_resources = ARRAY_SIZE(usbc_resources),
++              .resources = usbc_resources,
++      },
++      {
++              .name = "bxt_wcove_ext_charger",
++              .num_resources = ARRAY_SIZE(charger_resources),
++              .resources = charger_resources,
++      },
++};
++
+ static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
+                                   unsigned int *val)
+ {
+@@ -418,6 +421,26 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
+                                       0, chip, data);
+ }
++static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic,
++                                   const struct mfd_cell *cells, int n_devs,
++                                   struct regmap_irq_chip_data *pdata,
++                                   int pirq, int irq_flags,
++                                   const struct regmap_irq_chip *chip,
++                                   struct regmap_irq_chip_data **data)
++{
++      struct device *dev = pmic->dev;
++      struct irq_domain *domain;
++      int ret;
++
++      ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data);
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
++
++      domain = regmap_irq_get_domain(*data);
++
++      return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain);
++}
++
+ static int bxtwc_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -496,14 +519,14 @@ static int bxtwc_probe(struct platform_device *pdev)
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
+-      /* Add chained IRQ handler for CHGR IRQs */
+-      ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+-                                       BXTWC_CHGR_LVL1_IRQ,
+-                                       IRQF_ONESHOT,
+-                                       &bxtwc_regmap_irq_chip_chgr,
+-                                       &pmic->irq_chip_data_chgr);
++      ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev),
++                                      pmic->irq_chip_data,
++                                      BXTWC_CHGR_LVL1_IRQ,
++                                      IRQF_ONESHOT,
++                                      &bxtwc_regmap_irq_chip_chgr,
++                                      &pmic->irq_chip_data_chgr);
+       if (ret)
+-              return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
++              return ret;
+       /* Add chained IRQ handler for CRIT IRQs */
+       ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
+diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c
+index 7e9c279bf49df..22fe8d60fe368 100644
+--- a/drivers/usb/typec/tcpm/wcove.c
++++ b/drivers/usb/typec/tcpm/wcove.c
+@@ -620,10 +620,6 @@ static int wcove_typec_probe(struct platform_device *pdev)
+       if (irq < 0)
+               return irq;
+-      irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
+-      if (irq < 0)
+-              return irq;
+-
+       ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
+       if (ret)
+               return ret;
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch b/queue-5.10/mfd-rt5033-fix-missing-regmap_del_irq_chip.patch
new file mode 100644 (file)
index 0000000..b5feb3d
--- /dev/null
@@ -0,0 +1,39 @@
+From bdfac5d59fa3fb682be07fe6e801791d3d9e297c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Oct 2024 23:41:06 +0800
+Subject: mfd: rt5033: Fix missing regmap_del_irq_chip()
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit d256d612f47529ed0b332298e2d5ea981a4dd5b8 ]
+
+Fix missing call to regmap_del_irq_chip() in error handling path by
+using devm_regmap_add_irq_chip().
+
+Fixes: 0b271258544b ("mfd: rt5033: Add Richtek RT5033 driver core.")
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Link: https://lore.kernel.org/r/1730302867-8391-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/rt5033.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c
+index 302115dabff4b..9afb8d2b35476 100644
+--- a/drivers/mfd/rt5033.c
++++ b/drivers/mfd/rt5033.c
+@@ -82,8 +82,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c,
+       }
+       dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id);
+-      ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
+-                      IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++      ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap,
++                      rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                       0, &rt5033_irq_chip, &rt5033->irq_data);
+       if (ret) {
+               dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+-- 
+2.43.0
+
diff --git a/queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch b/queue-5.10/mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch
new file mode 100644 (file)
index 0000000..b5d049f
--- /dev/null
@@ -0,0 +1,49 @@
+From 6c8d3ebdfc809b4dcbc3162dd6049912075bb2c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 11:15:30 +0800
+Subject: mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 2174f9a8c9db50f74df769edd5a4ab822c73b6d2 ]
+
+As the comment said, disable_irq() after request_irq() still has a
+time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN
+flag will disable IRQ auto-enable when request IRQ.
+
+Fixes: 72cd799544f2 ("[PATCH] I2C: add i2c driver for TPS6501x")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20240912031530.2211654-1-ruanjinjie@huawei.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/tps65010.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
+index 7e7dbee58ca90..744a68f3c359c 100644
+--- a/drivers/mfd/tps65010.c
++++ b/drivers/mfd/tps65010.c
+@@ -549,17 +549,13 @@ static int tps65010_probe(struct i2c_client *client,
+        */
+       if (client->irq > 0) {
+               status = request_irq(client->irq, tps65010_irq,
+-                                   IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
++                                   IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
++                                   DRIVER_NAME, tps);
+               if (status < 0) {
+                       dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
+                                       client->irq, status);
+                       return status;
+               }
+-              /* annoying race here, ideally we'd have an option
+-               * to claim the irq now and enable it later.
+-               * FIXME genirq IRQF_NOAUTOEN now solves that ...
+-               */
+-              disable_irq(client->irq);
+               set_bit(FLAG_IRQ_ENABLE, &tps->flags);
+       } else
+               dev_warn(&client->dev, "IRQ not configured!\n");
+-- 
+2.43.0
+
diff --git a/queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch b/queue-5.10/mips-asm-fix-warning-when-disabling-mips_fp_support.patch
new file mode 100644 (file)
index 0000000..217a2f2
--- /dev/null
@@ -0,0 +1,49 @@
+From a29afac8012ee2908ad60c5c2befe5f568363a98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Oct 2024 12:12:14 +0200
+Subject: mips: asm: fix warning when disabling MIPS_FP_SUPPORT
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit da09935975c8f8c90d6f57be2422dee5557206cd ]
+
+When MIPS_FP_SUPPORT is disabled, __sanitize_fcr31() is defined as
+nothing, which triggers a gcc warning:
+
+    In file included from kernel/sched/core.c:79:
+    kernel/sched/core.c: In function 'context_switch':
+    ./arch/mips/include/asm/switch_to.h:114:39: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
+      114 |                 __sanitize_fcr31(next);                                 \
+          |                                       ^
+    kernel/sched/core.c:5316:9: note: in expansion of macro 'switch_to'
+     5316 |         switch_to(prev, next, prev);
+          |         ^~~~~~~~~
+
+Fix this by providing an empty body for __sanitize_fcr31() like one is
+defined for __mips_mt_fpaff_switch_to().
+
+Fixes: 36a498035bd2 ("MIPS: Avoid FCSR sanitization when CONFIG_MIPS_FP_SUPPORT=n")
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Reviewed-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/switch_to.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
+index a4374b4cb88fd..d6ccd53440213 100644
+--- a/arch/mips/include/asm/switch_to.h
++++ b/arch/mips/include/asm/switch_to.h
+@@ -97,7 +97,7 @@ do {                                                                 \
+       }                                                               \
+ } while (0)
+ #else
+-# define __sanitize_fcr31(next)
++# define __sanitize_fcr31(next) do { (void) (next); } while (0)
+ #endif
+ /*
+-- 
+2.43.0
+
diff --git a/queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch b/queue-5.10/misc-apds990x-fix-missing-pm_runtime_disable.patch
new file mode 100644 (file)
index 0000000..682be75
--- /dev/null
@@ -0,0 +1,67 @@
+From 7e913a3dffbd74912719cdd605dcdb546e5f5342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Sep 2024 11:55:56 +0800
+Subject: misc: apds990x: Fix missing pm_runtime_disable()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 3c5d8b819d27012264edd17e6ae7fffda382fe44 ]
+
+The pm_runtime_disable() is missing in probe error path,
+so add it to fix it.
+
+Fixes: 92b1f84d46b2 ("drivers/misc: driver for APDS990X ALS and proximity sensors")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20240923035556.3009105-1-ruanjinjie@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/apds990x.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c
+index 45f5b997a0e10..5b17288ecc2f0 100644
+--- a/drivers/misc/apds990x.c
++++ b/drivers/misc/apds990x.c
+@@ -1148,7 +1148,7 @@ static int apds990x_probe(struct i2c_client *client,
+               err = chip->pdata->setup_resources();
+               if (err) {
+                       err = -EINVAL;
+-                      goto fail3;
++                      goto fail4;
+               }
+       }
+@@ -1156,7 +1156,7 @@ static int apds990x_probe(struct i2c_client *client,
+                               apds990x_attribute_group);
+       if (err < 0) {
+               dev_err(&chip->client->dev, "Sysfs registration failed\n");
+-              goto fail4;
++              goto fail5;
+       }
+       err = request_threaded_irq(client->irq, NULL,
+@@ -1167,15 +1167,17 @@ static int apds990x_probe(struct i2c_client *client,
+       if (err) {
+               dev_err(&client->dev, "could not get IRQ %d\n",
+                       client->irq);
+-              goto fail5;
++              goto fail6;
+       }
+       return err;
+-fail5:
++fail6:
+       sysfs_remove_group(&chip->client->dev.kobj,
+                       &apds990x_attribute_group[0]);
+-fail4:
++fail5:
+       if (chip->pdata && chip->pdata->release_resources)
+               chip->pdata->release_resources();
++fail4:
++      pm_runtime_disable(&client->dev);
+ fail3:
+       regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
+ fail2:
+-- 
+2.43.0
+
diff --git a/queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch b/queue-5.10/mmc-mmc_spi-drop-buggy-snprintf.patch
new file mode 100644 (file)
index 0000000..a941208
--- /dev/null
@@ -0,0 +1,66 @@
+From a49b982fc9522404b2a1542ece3f07fc803986c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 18:01:34 +0200
+Subject: mmc: mmc_spi: drop buggy snprintf()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 328bda09cc91b3d93bc64f4a4dadc44313dd8140 ]
+
+GCC 13 complains about the truncated output of snprintf():
+
+drivers/mmc/host/mmc_spi.c: In function â€˜mmc_spi_response_get’:
+drivers/mmc/host/mmc_spi.c:227:64: error: â€˜snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
+  227 |         snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
+      |                                                                ^
+drivers/mmc/host/mmc_spi.c:227:9: note: â€˜snprintf’ output between 26 and 43 bytes into a destination of size 32
+  227 |         snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
+      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  228 |                 cmd->opcode, maptype(cmd));
+
+Drop it and fold the string it generates into the only place where it's
+emitted - the dev_dbg() call at the end of the function.
+
+Fixes: 15a0580ced08 ("mmc_spi host driver")
+Suggested-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20241008160134.69934-1-brgl@bgdev.pl
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mmc_spi.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
+index a1fb5d0e9553a..d85e5f7f5011d 100644
+--- a/drivers/mmc/host/mmc_spi.c
++++ b/drivers/mmc/host/mmc_spi.c
+@@ -230,10 +230,6 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
+       u8      leftover = 0;
+       unsigned short rotator;
+       int     i;
+-      char    tag[32];
+-
+-      snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
+-              cmd->opcode, maptype(cmd));
+       /* Except for data block reads, the whole response will already
+        * be stored in the scratch buffer.  It's somewhere after the
+@@ -386,8 +382,9 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
+       }
+       if (value < 0)
+-              dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
+-                      tag, cmd->resp[0], cmd->resp[1]);
++              dev_dbg(&host->spi->dev,
++                      "  ... CMD%d response SPI_%s: resp %04x %08x\n",
++                      cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]);
+       /* disable chipselect on errors and some success cases */
+       if (value >= 0 && cs_on)
+-- 
+2.43.0
+
diff --git a/queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch b/queue-5.10/mtd-rawnand-atmel-fix-possible-memory-leak.patch
new file mode 100644 (file)
index 0000000..fcf0cbc
--- /dev/null
@@ -0,0 +1,70 @@
+From 7885763356c1ca927f08ea39e0db6cbc8fc1be64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 22:31:49 +0200
+Subject: mtd: rawnand: atmel: Fix possible memory leak
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 6d734f1bfc336aaea91313a5632f2f197608fadd ]
+
+The pmecc "user" structure is allocated in atmel_pmecc_create_user() and
+was supposed to be freed with atmel_pmecc_destroy_user(), but this other
+helper is never called. One solution would be to find the proper
+location to call the destructor, but the trend today is to switch to
+device managed allocations, which in this case fits pretty well.
+
+Replace kzalloc() by devm_kzalloc() and drop the destructor entirely.
+
+Reported-by: "Dr. David Alan Gilbert" <linux@treblig.org>
+Closes: https://lore.kernel.org/all/ZvmIvRJCf6VhHvpo@gallifrey/
+Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20241001203149.387655-1-miquel.raynal@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/atmel/pmecc.c | 8 +-------
+ drivers/mtd/nand/raw/atmel/pmecc.h | 2 --
+ 2 files changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
+index cbb023bf00f72..09848d13802d8 100644
+--- a/drivers/mtd/nand/raw/atmel/pmecc.c
++++ b/drivers/mtd/nand/raw/atmel/pmecc.c
+@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+       size = ALIGN(size, sizeof(s32));
+       size += (req->ecc.strength + 1) * sizeof(s32) * 3;
+-      user = kzalloc(size, GFP_KERNEL);
++      user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL);
+       if (!user)
+               return ERR_PTR(-ENOMEM);
+@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+ }
+ EXPORT_SYMBOL_GPL(atmel_pmecc_create_user);
+-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user)
+-{
+-      kfree(user);
+-}
+-EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user);
+-
+ static int get_strength(struct atmel_pmecc_user *user)
+ {
+       const int *strengths = user->pmecc->caps->strengths;
+diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h
+index 7851c05126cf1..cc0c5af1f4f1a 100644
+--- a/drivers/mtd/nand/raw/atmel/pmecc.h
++++ b/drivers/mtd/nand/raw/atmel/pmecc.h
+@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);
+ struct atmel_pmecc_user *
+ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
+                       struct atmel_pmecc_user_req *req);
+-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
+-
+ void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
+ int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
+ void atmel_pmecc_disable(struct atmel_pmecc_user *user);
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch b/queue-5.10/net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch
new file mode 100644 (file)
index 0000000..ac65ace
--- /dev/null
@@ -0,0 +1,61 @@
+From 58a37bfabbae0a5f1cb39c282326ad747962549c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 17:13:43 +0000
+Subject: net: hsr: fix hsr_init_sk() vs network/transport headers.
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9cfb5e7f0ded2bfaabc270ceb5f91d13f0e805b9 ]
+
+Following sequence in hsr_init_sk() is invalid :
+
+    skb_reset_mac_header(skb);
+    skb_reset_mac_len(skb);
+    skb_reset_network_header(skb);
+    skb_reset_transport_header(skb);
+
+It is invalid because skb_reset_mac_len() needs the correct
+network header, which should be after the mac header.
+
+This patch moves the skb_reset_network_header()
+and skb_reset_transport_header() before
+the call to dev_hard_header().
+
+As a result skb->mac_len is no longer set to a value
+close to 65535.
+
+Fixes: 48b491a5cc74 ("net: hsr: fix mac_len checks")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: George McCollister <george.mccollister@gmail.com>
+Link: https://patch.msgid.link/20241122171343.897551-1-edumazet@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_device.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index c5a4c5fb72934..505eb58f7e081 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -256,6 +256,8 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master)
+       skb->dev = master->dev;
+       skb->priority = TC_PRIO_CONTROL;
++      skb_reset_network_header(skb);
++      skb_reset_transport_header(skb);
+       if (dev_hard_header(skb, skb->dev, ETH_P_PRP,
+                           hsr->sup_multicast_addr,
+                           skb->dev->dev_addr, skb->len) <= 0)
+@@ -263,8 +265,6 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master)
+       skb_reset_mac_header(skb);
+       skb_reset_mac_len(skb);
+-      skb_reset_network_header(skb);
+-      skb_reset_transport_header(skb);
+       return skb;
+ out:
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch b/queue-5.10/net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch
new file mode 100644 (file)
index 0000000..e03cf34
--- /dev/null
@@ -0,0 +1,67 @@
+From f05ec627e4c3e2bf47e787330753ac474690dacb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jan 2021 18:19:48 +0000
+Subject: net: introduce a netdev feature for UDP GRO forwarding
+
+From: Alexander Lobakin <alobakin@pm.me>
+
+[ Upstream commit 6f1c0ea133a6e4a193a7b285efe209664caeea43 ]
+
+Introduce a new netdev feature, NETIF_F_GRO_UDP_FWD, to allow user
+to turn UDP GRO on and off for forwarding.
+Defaults to off to not change current datapath.
+
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Alexander Lobakin <alobakin@pm.me>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 9cfb5e7f0ded ("net: hsr: fix hsr_init_sk() vs network/transport headers.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netdev_features.h | 4 +++-
+ net/ethtool/common.c            | 1 +
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
+index e2a92697a6638..7b7a7e4d81254 100644
+--- a/include/linux/netdev_features.h
++++ b/include/linux/netdev_features.h
+@@ -84,6 +84,7 @@ enum {
+       NETIF_F_GRO_FRAGLIST_BIT,       /* Fraglist GRO */
+       NETIF_F_HW_MACSEC_BIT,          /* Offload MACsec operations */
++      NETIF_F_GRO_UDP_FWD_BIT,        /* Allow UDP GRO for forwarding */
+       /*
+        * Add your fresh new feature above and remember to update
+@@ -157,6 +158,7 @@ enum {
+ #define NETIF_F_GRO_FRAGLIST  __NETIF_F(GRO_FRAGLIST)
+ #define NETIF_F_GSO_FRAGLIST  __NETIF_F(GSO_FRAGLIST)
+ #define NETIF_F_HW_MACSEC     __NETIF_F(HW_MACSEC)
++#define NETIF_F_GRO_UDP_FWD   __NETIF_F(GRO_UDP_FWD)
+ /* Finds the next feature with the highest number of the range of start-1 till 0.
+  */
+@@ -234,7 +236,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start)
+ #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
+ /* Changeable features with no special hardware requirements that defaults to off. */
+-#define NETIF_F_SOFT_FEATURES_OFF     NETIF_F_GRO_FRAGLIST
++#define NETIF_F_SOFT_FEATURES_OFF     (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD)
+ #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
+                                NETIF_F_HW_VLAN_CTAG_RX | \
+diff --git a/net/ethtool/common.c b/net/ethtool/common.c
+index 24036e3055a13..181220101a6e7 100644
+--- a/net/ethtool/common.c
++++ b/net/ethtool/common.c
+@@ -68,6 +68,7 @@ const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
+       [NETIF_F_HW_TLS_RX_BIT] =        "tls-hw-rx-offload",
+       [NETIF_F_GRO_FRAGLIST_BIT] =     "rx-gro-list",
+       [NETIF_F_HW_MACSEC_BIT] =        "macsec-hw-offload",
++      [NETIF_F_GRO_UDP_FWD_BIT] =      "rx-udp-gro-forwarding",
+ };
+ const char
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch b/queue-5.10/net-rfkill-gpio-add-check-for-clk_enable.patch
new file mode 100644 (file)
index 0000000..d0eec28
--- /dev/null
@@ -0,0 +1,44 @@
+From 36c7d393b835c1069a67695718f02accfb82e1b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2024 14:53:41 -0500
+Subject: net: rfkill: gpio: Add check for clk_enable()
+
+From: Mingwei Zheng <zmw12306@gmail.com>
+
+[ Upstream commit 8251e7621b25ccdb689f1dd9553b8789e3745ea1 ]
+
+Add check for the return value of clk_enable() to catch the potential
+error.
+
+Fixes: 7176ba23f8b5 ("net: rfkill: add generic gpio rfkill driver")
+Signed-off-by: Mingwei Zheng <zmw12306@gmail.com>
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Link: https://patch.msgid.link/20241108195341.1853080-1-zmw12306@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rfkill/rfkill-gpio.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
+index f74baefd855d3..2df5bf240b64a 100644
+--- a/net/rfkill/rfkill-gpio.c
++++ b/net/rfkill/rfkill-gpio.c
+@@ -30,8 +30,12 @@ static int rfkill_gpio_set_power(void *data, bool blocked)
+ {
+       struct rfkill_gpio_data *rfkill = data;
+-      if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled)
+-              clk_enable(rfkill->clk);
++      if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) {
++              int ret = clk_enable(rfkill->clk);
++
++              if (ret)
++                      return ret;
++      }
+       gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked);
+       gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked);
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch b/queue-5.10/net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch
new file mode 100644 (file)
index 0000000..3ddcade
--- /dev/null
@@ -0,0 +1,50 @@
+From c060709fb05e6fd5dd4ca37d6cd38339c159b847 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 15:12:55 +0100
+Subject: net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 407618d66dba55e7db1278872e8be106808bbe91 ]
+
+On DWMAC3 and later, there's a RX Watchdog interrupt that's used for
+interrupt coalescing. It's known to be buggy on some platforms, and
+dwmac-socfpga appears to be one of them. Changing the interrupt
+coalescing from ethtool doesn't appear to have any effect here.
+
+Without disabling RIWT (Received Interrupt Watchdog Timer, I
+believe...), we observe latencies while receiving traffic that amount to
+around ~0.4ms. This was discovered with NTP but can be easily reproduced
+with a simple ping. Without this patch :
+
+64 bytes from 192.168.5.2: icmp_seq=1 ttl=64 time=0.657 ms
+
+With this patch :
+
+64 bytes from 192.168.5.2: icmp_seq=1 ttl=64 time=0.254 ms
+
+Fixes: 801d233b7302 ("net: stmmac: Add SOCFPGA glue driver")
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20241122141256.764578-1-maxime.chevallier@bootlin.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+index 142bf912011e2..263235a4fc554 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -426,6 +426,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
+       plat_dat->bsp_priv = dwmac;
+       plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
++      plat_dat->riwt_off = 1;
++
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
+               goto err_remove_config_dt;
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch b/queue-5.10/net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch
new file mode 100644 (file)
index 0000000..477b754
--- /dev/null
@@ -0,0 +1,51 @@
+From fe60b77a776d2c2f8bc9d2a0e51fe2d56a3b11b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Nov 2024 14:05:58 +0100
+Subject: net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY
+ device
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit ae7370e61c5d8f5bcefc2d4fca724bd4e9bbf789 ]
+
+Add calls to `phy_device_free` after `fixed_phy_unregister` to fix a
+memory leak that occurs when the device is unplugged. This ensures
+proper cleanup of pseudo fixed-link PHYs.
+
+Fixes: 89b36fb5e532 ("lan78xx: Lan7801 Support for Fixed PHY")
+Cc: Raghuram Chary J <raghuramchary.jallipalli@microchip.com>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20241116130558.1352230-2-o.rempel@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/lan78xx.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 96d3d0bd248bc..757d5c82f3f09 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2157,6 +2157,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
+               if (dev->chipid == ID_REV_CHIP_ID_7801_) {
+                       if (phy_is_pseudo_fixed_link(phydev)) {
+                               fixed_phy_unregister(phydev);
++                              phy_device_free(phydev);
+                       } else {
+                               phy_unregister_fixup_for_uid(PHY_KSZ9031RNX,
+                                                            0xfffffff0);
+@@ -3835,8 +3836,10 @@ static void lan78xx_disconnect(struct usb_interface *intf)
+       phy_disconnect(net->phydev);
+-      if (phy_is_pseudo_fixed_link(phydev))
++      if (phy_is_pseudo_fixed_link(phydev)) {
+               fixed_phy_unregister(phydev);
++              phy_device_free(phydev);
++      }
+       unregister_netdev(net);
+-- 
+2.43.0
+
diff --git a/queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch b/queue-5.10/net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch
new file mode 100644 (file)
index 0000000..fc39134
--- /dev/null
@@ -0,0 +1,49 @@
+From 5373c9cf9c12de35dee218077b5d7b749f88b993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2024 15:03:51 +0100
+Subject: net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL
+ configuration
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit e863ff806f72098bccaf8fa89c80d9ad6187c3b0 ]
+
+Validate Wake-on-LAN (WoL) options in `lan78xx_set_wol` before calling
+`usb_autopm_get_interface`. This prevents USB autopm refcounting issues
+and ensures the adapter can properly enter autosuspend when invalid WoL
+options are provided.
+
+Fixes: eb9ad088f966 ("lan78xx: Check for supported Wake-on-LAN modes")
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://patch.msgid.link/20241118140351.2398166-1-o.rempel@pengutronix.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/lan78xx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 757d5c82f3f09..cabe6cdd6903a 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -1428,13 +1428,13 @@ static int lan78xx_set_wol(struct net_device *netdev,
+       struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
+       int ret;
++      if (wol->wolopts & ~WAKE_ALL)
++              return -EINVAL;
++
+       ret = usb_autopm_get_interface(dev->intf);
+       if (ret < 0)
+               return ret;
+-      if (wol->wolopts & ~WAKE_ALL)
+-              return -EINVAL;
+-
+       pdata->wol = wol->wolopts;
+       device_set_wakeup_enable(&dev->udev->dev, (bool)wol->wolopts);
+-- 
+2.43.0
+
diff --git a/queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch b/queue-5.10/netdevsim-copy-addresses-for-both-in-and-out-paths.patch
new file mode 100644 (file)
index 0000000..8a13606
--- /dev/null
@@ -0,0 +1,70 @@
+From 0e3b7bca065a9c607fd9dbb57f665ae0e9404076 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 04:00:26 +0000
+Subject: netdevsim: copy addresses for both in and out paths
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 2cf567f421dbfe7e53b7e5ddee9400da10efb75d ]
+
+The current code only copies the address for the in path, leaving the out
+path address set to 0. This patch corrects the issue by copying the addresses
+for both the in and out paths. Before this patch:
+
+  # cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec
+  SA count=2 tx=20
+  sa[0] tx ipaddr=0.0.0.0
+  sa[0]    spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1
+  sa[0]    key=0x3167608a ca4f1397 43565909 941fa627
+  sa[1] rx ipaddr=192.168.0.1
+  sa[1]    spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1
+  sa[1]    key=0x3167608a ca4f1397 43565909 941fa627
+
+After this patch:
+
+  = cat /sys/kernel/debug/netdevsim/netdevsim0/ports/0/ipsec
+  SA count=2 tx=20
+  sa[0] tx ipaddr=192.168.0.2
+  sa[0]    spi=0x00000100 proto=0x32 salt=0x0adecc3a crypt=1
+  sa[0]    key=0x3167608a ca4f1397 43565909 941fa627
+  sa[1] rx ipaddr=192.168.0.1
+  sa[1]    spi=0x00000101 proto=0x32 salt=0x0adecc3a crypt=1
+  sa[1]    key=0x3167608a ca4f1397 43565909 941fa627
+
+Fixes: 7699353da875 ("netdevsim: add ipsec offload testing")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20241010040027.21440-3-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/ipsec.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
+index 386336a38f349..feca55eef9938 100644
+--- a/drivers/net/netdevsim/ipsec.c
++++ b/drivers/net/netdevsim/ipsec.c
+@@ -171,14 +171,13 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
+               return ret;
+       }
+-      if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
++      if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN)
+               sa.rx = true;
+-              if (xs->props.family == AF_INET6)
+-                      memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
+-              else
+-                      memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
+-      }
++      if (xs->props.family == AF_INET6)
++              memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
++      else
++              memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
+       /* the preparations worked, so save the info */
+       memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa));
+-- 
+2.43.0
+
diff --git a/queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch b/queue-5.10/netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch
new file mode 100644 (file)
index 0000000..31971b7
--- /dev/null
@@ -0,0 +1,37 @@
+From 85aad10a3d3f1013a863c121c5ccb11d7a9320b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 13:06:43 +0300
+Subject: netdevsim: rely on XFRM state direction instead of flags
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 55e2f83afb1c142885da63c5a9ce2998b6f6ab21 ]
+
+Make sure that netdevsim relies on direction and not on flags.
+
+Reviewed-by: Raed Salem <raeds@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/ipsec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
+index b80ed2ffd45eb..386336a38f349 100644
+--- a/drivers/net/netdevsim/ipsec.c
++++ b/drivers/net/netdevsim/ipsec.c
+@@ -171,7 +171,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
+               return ret;
+       }
+-      if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
++      if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
+               sa.rx = true;
+               if (xs->props.family == AF_INET6)
+-- 
+2.43.0
+
diff --git a/queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch b/queue-5.10/netlink-typographical-error-in-nlmsg_type-constants-.patch
new file mode 100644 (file)
index 0000000..c2a8d1c
--- /dev/null
@@ -0,0 +1,36 @@
+From 262f8f209d4cf8fe3a2d135b8bc9848b7b25f736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Nov 2024 23:39:50 +0100
+Subject: netlink: typographical error in nlmsg_type constants definition
+
+From: Maurice Lambert <mauricelambert434@gmail.com>
+
+[ Upstream commit 84bfbfbbd32aee136afea4b6bf82581dce79c305 ]
+
+This commit fix a typographical error in netlink nlmsg_type constants definition in the include/uapi/linux/rtnetlink.h at line 177. The definition is RTM_NEWNVLAN RTM_NEWVLAN instead of RTM_NEWVLAN RTM_NEWVLAN.
+
+Signed-off-by: Maurice Lambert <mauricelambert434@gmail.com>
+Fixes: 8dcea187088b ("net: bridge: vlan: add rtm definitions and dump support")
+Link: https://patch.msgid.link/20241103223950.230300-1-mauricelambert434@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/rtnetlink.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
+index 9b814c92de123..31be7345e0c2e 100644
+--- a/include/uapi/linux/rtnetlink.h
++++ b/include/uapi/linux/rtnetlink.h
+@@ -172,7 +172,7 @@ enum {
+ #define RTM_GETLINKPROP       RTM_GETLINKPROP
+       RTM_NEWVLAN = 112,
+-#define RTM_NEWNVLAN  RTM_NEWVLAN
++#define RTM_NEWVLAN   RTM_NEWVLAN
+       RTM_DELVLAN,
+ #define RTM_DELVLAN   RTM_DELVLAN
+       RTM_GETVLAN,
+-- 
+2.43.0
+
diff --git a/queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch b/queue-5.10/netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch
new file mode 100644 (file)
index 0000000..6710afd
--- /dev/null
@@ -0,0 +1,45 @@
+From 01f17401af2e04b4a121af34acbcf1a239ae0133 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2024 03:15:18 -0800
+Subject: netpoll: Use rcu_access_pointer() in netpoll_poll_lock
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit a57d5a72f8dec7db8a79d0016fb0a3bdecc82b56 ]
+
+The ndev->npinfo pointer in netpoll_poll_lock() is RCU-protected but is
+being accessed directly for a NULL check. While no RCU read lock is held
+in this context, we should still use proper RCU primitives for
+consistency and correctness.
+
+Replace the direct NULL check with rcu_access_pointer(), which is the
+appropriate primitive when only checking for NULL without dereferencing
+the pointer. This function provides the necessary ordering guarantees
+without requiring RCU read-side protection.
+
+Fixes: bea3348eef27 ("[NET]: Make NAPI polling independent of struct net_device objects.")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Link: https://patch.msgid.link/20241118-netpoll_rcu-v1-2-a1888dcb4a02@debian.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netpoll.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
+index e6a2d72e0dc7a..533f8a5323a3b 100644
+--- a/include/linux/netpoll.h
++++ b/include/linux/netpoll.h
+@@ -70,7 +70,7 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi)
+ {
+       struct net_device *dev = napi->dev;
+-      if (dev && dev->npinfo) {
++      if (dev && rcu_access_pointer(dev->npinfo)) {
+               int owner = smp_processor_id();
+               while (cmpxchg(&napi->poll_owner, -1, owner) != -1)
+-- 
+2.43.0
+
diff --git a/queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch b/queue-5.10/nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch
new file mode 100644 (file)
index 0000000..dc7094d
--- /dev/null
@@ -0,0 +1,37 @@
+From a14574fbeb60884c36392a3efe7b9f7e7910fca8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Oct 2024 11:03:56 -0400
+Subject: NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit f64ea4af43161bb86ffc77e6aeb5bcf5c3229df0 ]
+
+It's only current caller already length-checks the string, but let's
+be safe.
+
+Fixes: 0964a3d3f1aa ("[PATCH] knfsd: nfsd4 reboot dirname fix")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4recover.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 2904268c18c9a..eca39b5c12c68 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -658,7 +658,8 @@ nfs4_reset_recoverydir(char *recdir)
+               return status;
+       status = -ENOTDIR;
+       if (d_is_dir(path.dentry)) {
+-              strcpy(user_recovery_dirname, recdir);
++              strscpy(user_recovery_dirname, recdir,
++                      sizeof(user_recovery_dirname));
+               status = 0;
+       }
+       path_put(&path);
+-- 
+2.43.0
+
diff --git a/queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch b/queue-5.10/nfsd-fix-nfsd4_shutdown_copy.patch
new file mode 100644 (file)
index 0000000..57362c3
--- /dev/null
@@ -0,0 +1,73 @@
+From 26b4bc3e2ac1e825ba05ec57df0a1c879a29820d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Oct 2024 09:40:03 -0400
+Subject: NFSD: Fix nfsd4_shutdown_copy()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 62a8642ba00aa8ceb0a02ade942f5ec52e877c95 ]
+
+nfsd4_shutdown_copy() is just this:
+
+       while ((copy = nfsd4_get_copy(clp)) != NULL)
+               nfsd4_stop_copy(copy);
+
+nfsd4_get_copy() bumps @copy's reference count, preventing
+nfsd4_stop_copy() from releasing @copy.
+
+A while loop like this usually works by removing the first element
+of the list, but neither nfsd4_get_copy() nor nfsd4_stop_copy()
+alters the async_copies list.
+
+Best I can tell, then, is that nfsd4_shutdown_copy() continues to
+loop until other threads manage to remove all the items from this
+list. The spinning loop blocks shutdown until these items are gone.
+
+Possibly the reason we haven't seen this issue in the field is
+because client_has_state() prevents __destroy_client() from calling
+nfsd4_shutdown_copy() if there are any items on this list. In a
+subsequent patch I plan to remove that restriction.
+
+Fixes: e0639dc5805a ("NFSD introduce async copy feature")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 237e47896af86..8cf0e4e62bc84 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1256,7 +1256,7 @@ static void nfsd4_stop_copy(struct nfsd4_copy *copy)
+       nfs4_put_copy(copy);
+ }
+-static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
++static struct nfsd4_copy *nfsd4_unhash_copy(struct nfs4_client *clp)
+ {
+       struct nfsd4_copy *copy = NULL;
+@@ -1265,6 +1265,9 @@ static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
+               copy = list_first_entry(&clp->async_copies, struct nfsd4_copy,
+                                       copies);
+               refcount_inc(&copy->refcount);
++              copy->cp_clp = NULL;
++              if (!list_empty(&copy->copies))
++                      list_del_init(&copy->copies);
+       }
+       spin_unlock(&clp->async_lock);
+       return copy;
+@@ -1274,7 +1277,7 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp)
+ {
+       struct nfsd4_copy *copy;
+-      while ((copy = nfsd4_get_copy(clp)) != NULL)
++      while ((copy = nfsd4_unhash_copy(clp)) != NULL)
+               nfsd4_stop_copy(copy);
+ }
+ #ifdef CONFIG_NFSD_V4_2_INTER_SSC
+-- 
+2.43.0
+
diff --git a/queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch b/queue-5.10/nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch
new file mode 100644 (file)
index 0000000..a29fb78
--- /dev/null
@@ -0,0 +1,37 @@
+From 9012872c33883c74704550ebdb79d33854897565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Oct 2024 11:03:53 -0400
+Subject: NFSD: Prevent NULL dereference in nfsd4_process_cb_update()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit 1e02c641c3a43c88cecc08402000418e15578d38 ]
+
+@ses is initialized to NULL. If __nfsd4_find_backchannel() finds no
+available backchannel session, setup_callback_client() will try to
+dereference @ses and segfault.
+
+Fixes: dcbeaa68dbbd ("nfsd4: allow backchannel recovery")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4callback.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 4eae2c5af2edf..18d62d3424c1a 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -1379,6 +1379,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
+               ses = c->cn_session;
+       }
+       spin_unlock(&clp->cl_lock);
++      if (!c)
++              return;
+       err = setup_callback_client(clp, &conn, ses);
+       if (err) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch b/queue-5.10/nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch
new file mode 100644 (file)
index 0000000..5a848e0
--- /dev/null
@@ -0,0 +1,94 @@
+From f7e4dbe5e3db37c512c35c650f4ba9edd0164760 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2024 05:40:04 +0100
+Subject: nvme-pci: fix freeing of the HMB descriptor table
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 3c2fb1ca8086eb139b2a551358137525ae8e0d7a ]
+
+The HMB descriptor table is sized to the maximum number of descriptors
+that could be used for a given device, but __nvme_alloc_host_mem could
+break out of the loop earlier on memory allocation failure and end up
+using less descriptors than planned for, which leads to an incorrect
+size passed to dma_free_coherent.
+
+In practice this was not showing up because the number of descriptors
+tends to be low and the dma coherent allocator always allocates and
+frees at least a page.
+
+Fixes: 87ad72a59a38 ("nvme-pci: implement host memory buffer support")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/pci.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 78cac4220e03a..875ebef6adc71 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -147,6 +147,7 @@ struct nvme_dev {
+       /* host memory buffer support: */
+       u64 host_mem_size;
+       u32 nr_host_mem_descs;
++      u32 host_mem_descs_size;
+       dma_addr_t host_mem_descs_dma;
+       struct nvme_host_mem_buf_desc *host_mem_descs;
+       void **host_mem_desc_bufs;
+@@ -1925,10 +1926,10 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
+       kfree(dev->host_mem_desc_bufs);
+       dev->host_mem_desc_bufs = NULL;
+-      dma_free_coherent(dev->dev,
+-                      dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs),
++      dma_free_coherent(dev->dev, dev->host_mem_descs_size,
+                       dev->host_mem_descs, dev->host_mem_descs_dma);
+       dev->host_mem_descs = NULL;
++      dev->host_mem_descs_size = 0;
+       dev->nr_host_mem_descs = 0;
+ }
+@@ -1936,7 +1937,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+               u32 chunk_size)
+ {
+       struct nvme_host_mem_buf_desc *descs;
+-      u32 max_entries, len;
++      u32 max_entries, len, descs_size;
+       dma_addr_t descs_dma;
+       int i = 0;
+       void **bufs;
+@@ -1949,8 +1950,9 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+       if (dev->ctrl.hmmaxd && dev->ctrl.hmmaxd < max_entries)
+               max_entries = dev->ctrl.hmmaxd;
+-      descs = dma_alloc_coherent(dev->dev, max_entries * sizeof(*descs),
+-                                 &descs_dma, GFP_KERNEL);
++      descs_size = max_entries * sizeof(*descs);
++      descs = dma_alloc_coherent(dev->dev, descs_size, &descs_dma,
++                      GFP_KERNEL);
+       if (!descs)
+               goto out;
+@@ -1979,6 +1981,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+       dev->host_mem_size = size;
+       dev->host_mem_descs = descs;
+       dev->host_mem_descs_dma = descs_dma;
++      dev->host_mem_descs_size = descs_size;
+       dev->host_mem_desc_bufs = bufs;
+       return 0;
+@@ -1993,8 +1996,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
+       kfree(bufs);
+ out_free_descs:
+-      dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs,
+-                      descs_dma);
++      dma_free_coherent(dev->dev, descs_size, descs, descs_dma);
+ out:
+       dev->host_mem_descs = NULL;
+       return -ENOMEM;
+-- 
+2.43.0
+
diff --git a/queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch b/queue-5.10/ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch
new file mode 100644 (file)
index 0000000..776f0f6
--- /dev/null
@@ -0,0 +1,98 @@
+From fd60c0272d1fe93af7f9e0825cdf973b6f6e22ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Oct 2024 12:17:36 +0300
+Subject: ocfs2: fix uninitialized value in ocfs2_file_read_iter()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit adc77b19f62d7e80f98400b2fca9d700d2afdd6f ]
+
+Syzbot has reported the following KMSAN splat:
+
+BUG: KMSAN: uninit-value in ocfs2_file_read_iter+0x9a4/0xf80
+ ocfs2_file_read_iter+0x9a4/0xf80
+ __io_read+0x8d4/0x20f0
+ io_read+0x3e/0xf0
+ io_issue_sqe+0x42b/0x22c0
+ io_wq_submit_work+0xaf9/0xdc0
+ io_worker_handle_work+0xd13/0x2110
+ io_wq_worker+0x447/0x1410
+ ret_from_fork+0x6f/0x90
+ ret_from_fork_asm+0x1a/0x30
+
+Uninit was created at:
+ __alloc_pages_noprof+0x9a7/0xe00
+ alloc_pages_mpol_noprof+0x299/0x990
+ alloc_pages_noprof+0x1bf/0x1e0
+ allocate_slab+0x33a/0x1250
+ ___slab_alloc+0x12ef/0x35e0
+ kmem_cache_alloc_bulk_noprof+0x486/0x1330
+ __io_alloc_req_refill+0x84/0x560
+ io_submit_sqes+0x172f/0x2f30
+ __se_sys_io_uring_enter+0x406/0x41c0
+ __x64_sys_io_uring_enter+0x11f/0x1a0
+ x64_sys_call+0x2b54/0x3ba0
+ do_syscall_64+0xcd/0x1e0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Since an instance of 'struct kiocb' may be passed from the block layer
+with 'private' field uninitialized, introduce 'ocfs2_iocb_init_rw_locked()'
+and use it from where 'ocfs2_dio_end_io()' might take care, i.e. in
+'ocfs2_file_read_iter()' and 'ocfs2_file_write_iter()'.
+
+Link: https://lkml.kernel.org/r/20241029091736.1501946-1-dmantipov@yandex.ru
+Fixes: 7cdfc3a1c397 ("ocfs2: Remember rw lock level during direct io")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Reported-by: syzbot+a73e253cca4f0230a5a5@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=a73e253cca4f0230a5a5
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ocfs2/aops.h | 2 ++
+ fs/ocfs2/file.c | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
+index 70ed4382750d5..5b129ae9c3d22 100644
+--- a/fs/ocfs2/aops.h
++++ b/fs/ocfs2/aops.h
+@@ -72,6 +72,8 @@ enum ocfs2_iocb_lock_bits {
+       OCFS2_IOCB_NUM_LOCKS
+ };
++#define ocfs2_iocb_init_rw_locked(iocb) \
++      (iocb->private = NULL)
+ #define ocfs2_iocb_clear_rw_locked(iocb) \
+       clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
+ #define ocfs2_iocb_rw_locked_level(iocb) \
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index 224ced997d64b..3ce7606f5dbe8 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -2401,6 +2401,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
+       } else
+               inode_lock(inode);
++      ocfs2_iocb_init_rw_locked(iocb);
++
+       /*
+        * Concurrent O_DIRECT writes are allowed with
+        * mount_option "coherency=buffered".
+@@ -2547,6 +2549,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
+       if (!direct_io && nowait)
+               return -EOPNOTSUPP;
++      ocfs2_iocb_init_rw_locked(iocb);
++
+       /*
+        * buffered reads protect themselves in ->readpage().  O_DIRECT reads
+        * need locks to protect pending reads from racing with truncate.
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch b/queue-5.10/octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch
new file mode 100644 (file)
index 0000000..1d0eb05
--- /dev/null
@@ -0,0 +1,210 @@
+From 77cd25f2bb5fb06c0ef4f90ee74e9c249bc089cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 16:05:26 +0530
+Subject: octeontx2-af: Add new CGX_CMD to get PHY FEC statistics
+
+From: Felix Manlunas <fmanlunas@marvell.com>
+
+[ Upstream commit bd74d4ea29cc3c0520d9af109bb7a7c769325746 ]
+
+This patch adds support to fetch fec stats from PHY. The stats are
+put in the shared data struct fwdata.  A PHY driver indicates
+that it has FEC stats by setting the flag fwdata.phy.misc.has_fec_stats
+
+Besides CGX_CMD_GET_PHY_FEC_STATS, also add CGX_CMD_PRBS and
+CGX_CMD_DISPLAY_EYE to enum cgx_cmd_id so that Linux's enum list is in sync
+with firmware's enum list.
+
+Signed-off-by: Felix Manlunas <fmanlunas@marvell.com>
+Signed-off-by: Christina Jacob <cjacob@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/af/cgx.c   | 12 ++++++
+ .../net/ethernet/marvell/octeontx2/af/cgx.h   |  1 +
+ .../ethernet/marvell/octeontx2/af/cgx_fw_if.h |  5 +++
+ .../net/ethernet/marvell/octeontx2/af/mbox.h  | 43 +++++++++++++++++++
+ .../net/ethernet/marvell/octeontx2/af/rvu.h   |  4 ++
+ .../ethernet/marvell/octeontx2/af/rvu_cgx.c   | 32 ++++++++++++++
+ 6 files changed, 97 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+index 6bcc403e031ff..1eaf728d5e79f 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -866,6 +866,18 @@ int cgx_set_fec(u64 fec, int cgx_id, int lmac_id)
+       return cgx->lmac_idmap[lmac_id]->link_info.fec;
+ }
++int cgx_get_phy_fec_stats(void *cgxd, int lmac_id)
++{
++      struct cgx *cgx = cgxd;
++      u64 req = 0, resp;
++
++      if (!cgx)
++              return -ENODEV;
++
++      req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_PHY_FEC_STATS, req);
++      return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
++}
++
+ static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
+ {
+       u64 req = 0;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+index 6295a6963ff78..82563a88fe1bb 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+@@ -153,5 +153,6 @@ void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+ u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
+ int cgx_set_fec(u64 fec, int cgx_id, int lmac_id);
+ int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
++int cgx_get_phy_fec_stats(void *cgxd, int lmac_id);
+ #endif /* CGX_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
+index 3485596c0ed6c..65f832ac39cf1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
+@@ -89,6 +89,11 @@ enum cgx_cmd_id {
+       CGX_CMD_SET_AN,
+       CGX_CMD_GET_ADV_LINK_MODES,
+       CGX_CMD_GET_ADV_FEC,
++      CGX_CMD_GET_PHY_MOD_TYPE, /* line-side modulation type: NRZ or PAM4 */
++      CGX_CMD_SET_PHY_MOD_TYPE,
++      CGX_CMD_PRBS,
++      CGX_CMD_DISPLAY_EYE,
++      CGX_CMD_GET_PHY_FEC_STATS,
+ };
+ /* async event ids */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+index 9a135d1cf102d..ccd58d378fe48 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+@@ -151,6 +151,8 @@ M(CGX_CFG_PAUSE_FRM,       0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg,    \
+                              cgx_pause_frm_cfg)                       \
+ M(CGX_FEC_SET,                0x210, cgx_set_fec_param, fec_mode, fec_mode)   \
+ M(CGX_FEC_STATS,      0x211, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \
++M(CGX_GET_PHY_FEC_STATS, 0x212, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
++M(CGX_FW_DATA_GET,    0x213, cgx_get_aux_link_info, msg_req, cgx_fw_data) \
+  /* NPA mbox IDs (range 0x400 - 0x5FF) */                             \
+ /* NPA mbox IDs (range 0x400 - 0x5FF) */                              \
+ M(NPA_LF_ALLOC,               0x400, npa_lf_alloc,                            \
+@@ -399,6 +401,47 @@ struct fec_mode {
+       int fec;
+ };
++struct sfp_eeprom_s {
++#define SFP_EEPROM_SIZE 256
++      u16 sff_id;
++      u8 buf[SFP_EEPROM_SIZE];
++      u64 reserved;
++};
++
++struct phy_s {
++      struct {
++              u64 can_change_mod_type:1;
++              u64 mod_type:1;
++              u64 has_fec_stats:1;
++      } misc;
++      struct fec_stats_s {
++              u32 rsfec_corr_cws;
++              u32 rsfec_uncorr_cws;
++              u32 brfec_corr_blks;
++              u32 brfec_uncorr_blks;
++      } fec_stats;
++};
++
++struct cgx_lmac_fwdata_s {
++      u16 rw_valid;
++      u64 supported_fec;
++      u64 supported_an;
++      u64 supported_link_modes;
++      /* only applicable if AN is supported */
++      u64 advertised_fec;
++      u64 advertised_link_modes;
++      /* Only applicable if SFP/QSFP slot is present */
++      struct sfp_eeprom_s sfp_eeprom;
++      struct phy_s phy;
++#define LMAC_FWDATA_RESERVED_MEM 1021
++      u64 reserved[LMAC_FWDATA_RESERVED_MEM];
++};
++
++struct cgx_fw_data {
++      struct mbox_msghdr hdr;
++      struct cgx_lmac_fwdata_s fwdata;
++};
++
+ /* NPA mbox message formats */
+ /* NPA mailbox error codes
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index ec9a291e866c7..da8ab4ac4280d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -291,6 +291,10 @@ struct rvu_fwdata {
+       u64 msixtr_base;
+ #define FWDATA_RESERVED_MEM 1023
+       u64 reserved[FWDATA_RESERVED_MEM];
++#define CGX_MAX         5
++#define CGX_LMACS_MAX   4
++      struct cgx_lmac_fwdata_s cgx_fw_data[CGX_MAX][CGX_LMACS_MAX];
++      /* Do not add new fields below this line */
+ };
+ struct ptp;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index 05ef3a104748a..8f116d681ff42 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -692,6 +692,19 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
+       return 0;
+ }
++int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
++                                         struct msg_rsp *rsp)
++{
++      int pf = rvu_get_pf(req->hdr.pcifunc);
++      u8 cgx_id, lmac_id;
++
++      if (!is_pf_cgxmapped(rvu, pf))
++              return -EPERM;
++
++      rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
++      return cgx_get_phy_fec_stats(rvu_cgx_pdata(cgx_id, rvu), lmac_id);
++}
++
+ /* Finds cumulative status of NIX rx/tx counters from LF of a PF and those
+  * from its VFs as well. ie. NIX rx/tx counters at the CGX port level
+  */
+@@ -800,3 +813,22 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
+       rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
+       return 0;
+ }
++
++int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
++                                         struct cgx_fw_data *rsp)
++{
++      int pf = rvu_get_pf(req->hdr.pcifunc);
++      u8 cgx_id, lmac_id;
++
++      if (!rvu->fwdata)
++              return -ENXIO;
++
++      if (!is_pf_cgxmapped(rvu, pf))
++              return -EPERM;
++
++      rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
++
++      memcpy(&rsp->fwdata, &rvu->fwdata->cgx_fw_data[cgx_id][lmac_id],
++             sizeof(struct cgx_lmac_fwdata_s));
++      return 0;
++}
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-af-forward-error-correction-configuration.patch b/queue-5.10/octeontx2-af-forward-error-correction-configuration.patch
new file mode 100644 (file)
index 0000000..c5c1a3e
--- /dev/null
@@ -0,0 +1,320 @@
+From da3d76109ec863608968a4887dfa2126e9c54401 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 16:05:25 +0530
+Subject: octeontx2-af: forward error correction configuration
+
+From: Christina Jacob <cjacob@marvell.com>
+
+[ Upstream commit 84c4f9cab4f99e774a8d9bbee299d288bdb2d792 ]
+
+CGX block supports forward error correction modes baseR
+and RS. This patch adds support to set encoding mode
+and to read corrected/uncorrected block counters
+
+Adds new mailbox handlers set_fec to configure encoding modes
+and fec_stats to read counters and also increase mbox timeout
+to accomdate firmware command response timeout.
+
+Along with new CGX_CMD_SET_FEC command add other commands to
+sync with kernel enum list with firmware.
+
+Signed-off-by: Christina Jacob <cjacob@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/af/cgx.c   | 76 +++++++++++++++++++
+ .../net/ethernet/marvell/octeontx2/af/cgx.h   |  7 ++
+ .../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 17 ++++-
+ .../net/ethernet/marvell/octeontx2/af/mbox.h  | 24 +++++-
+ .../ethernet/marvell/octeontx2/af/rvu_cgx.c   | 33 ++++++++
+ 5 files changed, 155 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+index 7f82baf8e7403..6bcc403e031ff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -340,6 +340,60 @@ int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat)
+       return 0;
+ }
++static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo)
++{
++      if (!linfo->fec)
++              return 0;
++
++      switch (linfo->lmac_type_id) {
++      case LMAC_MODE_SGMII:
++      case LMAC_MODE_XAUI:
++      case LMAC_MODE_RXAUI:
++      case LMAC_MODE_QSGMII:
++              return 0;
++      case LMAC_MODE_10G_R:
++      case LMAC_MODE_25G_R:
++      case LMAC_MODE_100G_R:
++      case LMAC_MODE_USXGMII:
++              return 1;
++      case LMAC_MODE_40G_R:
++              return 4;
++      case LMAC_MODE_50G_R:
++              if (linfo->fec == OTX2_FEC_BASER)
++                      return 2;
++              else
++                      return 1;
++      default:
++              return 0;
++      }
++}
++
++int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp)
++{
++      int stats, fec_stats_count = 0;
++      int corr_reg, uncorr_reg;
++      struct cgx *cgx = cgxd;
++
++      if (!cgx || lmac_id >= cgx->lmac_count)
++              return -ENODEV;
++      fec_stats_count =
++              cgx_set_fec_stats_count(&cgx->lmac_idmap[lmac_id]->link_info);
++      if (cgx->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) {
++              corr_reg = CGXX_SPUX_LNX_FEC_CORR_BLOCKS;
++              uncorr_reg = CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS;
++      } else {
++              corr_reg = CGXX_SPUX_RSFEC_CORR;
++              uncorr_reg = CGXX_SPUX_RSFEC_UNCORR;
++      }
++      for (stats = 0; stats < fec_stats_count; stats++) {
++              rsp->fec_corr_blks +=
++                      cgx_read(cgx, lmac_id, corr_reg + (stats * 8));
++              rsp->fec_uncorr_blks +=
++                      cgx_read(cgx, lmac_id, uncorr_reg + (stats * 8));
++      }
++      return 0;
++}
++
+ int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable)
+ {
+       struct cgx *cgx = cgxd;
+@@ -620,6 +674,7 @@ static inline void link_status_user_format(u64 lstat,
+       linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
+       linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
+       linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
++      linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat);
+       linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id);
+       lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
+       strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
+@@ -790,6 +845,27 @@ int cgx_get_fwdata_base(u64 *base)
+       return err;
+ }
++int cgx_set_fec(u64 fec, int cgx_id, int lmac_id)
++{
++      u64 req = 0, resp;
++      struct cgx *cgx;
++      int err = 0;
++
++      cgx = cgx_get_pdata(cgx_id);
++      if (!cgx)
++              return -ENXIO;
++
++      req = FIELD_SET(CMDREG_ID, CGX_CMD_SET_FEC, req);
++      req = FIELD_SET(CMDSETFEC, fec, req);
++      err = cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
++      if (err)
++              return err;
++
++      cgx->lmac_idmap[lmac_id]->link_info.fec =
++                      FIELD_GET(RESP_LINKSTAT_FEC, resp);
++      return cgx->lmac_idmap[lmac_id]->link_info.fec;
++}
++
+ static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
+ {
+       u64 req = 0;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+index e176a6c654ef2..6295a6963ff78 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+@@ -55,6 +55,11 @@
+ #define CGXX_SCRATCH1_REG             0x1058
+ #define CGX_CONST                     0x2000
+ #define CGXX_SPUX_CONTROL1            0x10000
++#define CGXX_SPUX_LNX_FEC_CORR_BLOCKS 0x10700
++#define CGXX_SPUX_LNX_FEC_UNCORR_BLOCKS       0x10800
++#define CGXX_SPUX_RSFEC_CORR          0x10088
++#define CGXX_SPUX_RSFEC_UNCORR                0x10090
++
+ #define CGXX_SPUX_CONTROL1_LBK                BIT_ULL(14)
+ #define CGXX_GMP_PCS_MRX_CTL          0x30000
+ #define CGXX_GMP_PCS_MRX_CTL_LBK      BIT_ULL(14)
+@@ -146,5 +151,7 @@ int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
+                          u8 tx_pause, u8 rx_pause);
+ void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+ u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
++int cgx_set_fec(u64 fec, int cgx_id, int lmac_id);
++int cgx_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
+ #endif /* CGX_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
+index c3702fa58b6bd..3485596c0ed6c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
+@@ -81,6 +81,14 @@ enum cgx_cmd_id {
+       CGX_CMD_GET_MKEX_PRFL_SIZE,
+       CGX_CMD_GET_MKEX_PRFL_ADDR,
+       CGX_CMD_GET_FWD_BASE,           /* get base address of shared FW data */
++      CGX_CMD_GET_LINK_MODES,         /* Supported Link Modes */
++      CGX_CMD_SET_LINK_MODE,
++      CGX_CMD_GET_SUPPORTED_FEC,
++      CGX_CMD_SET_FEC,
++      CGX_CMD_GET_AN,
++      CGX_CMD_SET_AN,
++      CGX_CMD_GET_ADV_LINK_MODES,
++      CGX_CMD_GET_ADV_FEC,
+ };
+ /* async event ids */
+@@ -171,13 +179,19 @@ struct cgx_lnk_sts {
+       uint64_t full_duplex:1;
+       uint64_t speed:4;               /* cgx_link_speed */
+       uint64_t err_type:10;
+-      uint64_t reserved2:39;
++      uint64_t an:1;                  /* AN supported or not */
++      uint64_t fec:2;                 /* FEC type if enabled, if not 0 */
++      uint64_t port:8;
++      uint64_t reserved2:28;
+ };
+ #define RESP_LINKSTAT_UP              GENMASK_ULL(9, 9)
+ #define RESP_LINKSTAT_FDUPLEX         GENMASK_ULL(10, 10)
+ #define RESP_LINKSTAT_SPEED           GENMASK_ULL(14, 11)
+ #define RESP_LINKSTAT_ERRTYPE         GENMASK_ULL(24, 15)
++#define RESP_LINKSTAT_AN              GENMASK_ULL(25, 25)
++#define RESP_LINKSTAT_FEC             GENMASK_ULL(27, 26)
++#define RESP_LINKSTAT_PORT            GENMASK_ULL(35, 28)
+ /* scratchx(1) CSR used for non-secure SW->ATF communication
+  * This CSR acts as a command register
+@@ -199,4 +213,5 @@ struct cgx_lnk_sts {
+ #define CMDLINKCHANGE_FULLDPLX        BIT_ULL(9)
+ #define CMDLINKCHANGE_SPEED   GENMASK_ULL(13, 10)
++#define CMDSETFEC                     GENMASK_ULL(9, 8)
+ #endif /* __CGX_FW_INTF_H__ */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+index f46de8419b770..9a135d1cf102d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+@@ -36,7 +36,7 @@
+ #define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull))
+-#define MBOX_RSP_TIMEOUT      2000 /* Time(ms) to wait for mbox response */
++#define MBOX_RSP_TIMEOUT      3000 /* Time(ms) to wait for mbox response */
+ #define MBOX_MSG_ALIGN                16  /* Align mbox msg start to 16bytes */
+@@ -149,6 +149,9 @@ M(CGX_PTP_RX_ENABLE,       0x20C, cgx_ptp_rx_enable, msg_req, msg_rsp)     \
+ M(CGX_PTP_RX_DISABLE, 0x20D, cgx_ptp_rx_disable, msg_req, msg_rsp)    \
+ M(CGX_CFG_PAUSE_FRM,  0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg,    \
+                              cgx_pause_frm_cfg)                       \
++M(CGX_FEC_SET,                0x210, cgx_set_fec_param, fec_mode, fec_mode)   \
++M(CGX_FEC_STATS,      0x211, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \
++ /* NPA mbox IDs (range 0x400 - 0x5FF) */                             \
+ /* NPA mbox IDs (range 0x400 - 0x5FF) */                              \
+ M(NPA_LF_ALLOC,               0x400, npa_lf_alloc,                            \
+                               npa_lf_alloc_req, npa_lf_alloc_rsp)     \
+@@ -346,6 +349,11 @@ struct cgx_stats_rsp {
+       u64 tx_stats[CGX_TX_STATS_COUNT];
+ };
++struct cgx_fec_stats_rsp {
++      struct mbox_msghdr hdr;
++      u64 fec_corr_blks;
++      u64 fec_uncorr_blks;
++};
+ /* Structure for requesting the operation for
+  * setting/getting mac address in the CGX interface
+  */
+@@ -359,6 +367,7 @@ struct cgx_link_user_info {
+       uint64_t full_duplex:1;
+       uint64_t lmac_type_id:4;
+       uint64_t speed:20; /* speed in Mbps */
++      uint64_t fec:2;  /* FEC type if enabled else 0 */
+ #define LMACTYPE_STR_LEN 16
+       char lmac_type[LMACTYPE_STR_LEN];
+ };
+@@ -377,6 +386,19 @@ struct cgx_pause_frm_cfg {
+       u8 tx_pause;
+ };
++enum fec_type {
++      OTX2_FEC_NONE,
++      OTX2_FEC_BASER,
++      OTX2_FEC_RS,
++      OTX2_FEC_STATS_CNT = 2,
++      OTX2_FEC_OFF,
++};
++
++struct fec_mode {
++      struct mbox_msghdr hdr;
++      int fec;
++};
++
+ /* NPA mbox message formats */
+ /* NPA mailbox error codes
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index 83743e15326d7..05ef3a104748a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -462,6 +462,22 @@ int rvu_mbox_handler_cgx_stats(struct rvu *rvu, struct msg_req *req,
+       return 0;
+ }
++int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
++                                 struct msg_req *req,
++                                 struct cgx_fec_stats_rsp *rsp)
++{
++      int pf = rvu_get_pf(req->hdr.pcifunc);
++      u8 cgx_idx, lmac;
++      void *cgxd;
++
++      if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
++              return -EPERM;
++      rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
++
++      cgxd = rvu_cgx_pdata(cgx_idx, rvu);
++      return cgx_get_fec_stats(cgxd, lmac, rsp);
++}
++
+ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp)
+@@ -767,3 +783,20 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
+       mutex_unlock(&rvu->cgx_cfg_lock);
+       return err;
+ }
++
++int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
++                                     struct fec_mode *req,
++                                     struct fec_mode *rsp)
++{
++      int pf = rvu_get_pf(req->hdr.pcifunc);
++      u8 cgx_id, lmac_id;
++
++      if (!is_pf_cgxmapped(rvu, pf))
++              return -EPERM;
++
++      if (req->fec == OTX2_FEC_OFF)
++              req->fec = OTX2_FEC_NONE;
++      rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
++      rsp->fec = cgx_set_fec(req->fec, cgx_id, lmac_id);
++      return 0;
++}
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch b/queue-5.10/octeontx2-af-mbox-changes-for-98xx.patch
new file mode 100644 (file)
index 0000000..3392435
--- /dev/null
@@ -0,0 +1,369 @@
+From 0134afea263b93be1f06b859e161a186fb1e1fa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Oct 2020 10:45:46 +0530
+Subject: octeontx2-af: Mbox changes for 98xx
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit a84cdcea3b4feb46730c88454b5f85e828429c2b ]
+
+This patch puts together all mailbox changes
+for 98xx silicon:
+
+Attach ->
+Modify resource attach mailbox handler to
+request LFs from a block address out of multiple
+blocks of same type. If a PF/VF need LFs from two
+blocks of same type then attach mbox should be
+called twice.
+
+Example:
+        struct rsrc_attach *attach;
+        .. Allocate memory for message ..
+        attach->cptlfs = 3; /* 3 LFs from CPT0 */
+        .. Send message ..
+        .. Allocate memory for message ..
+        attach->modify = 1;
+        attach->cpt_blkaddr = BLKADDR_CPT1;
+        attach->cptlfs = 2; /* 2 LFs from CPT1 */
+        .. Send message ..
+
+Detach ->
+Update detach mailbox and its handler to detach
+resources from CPT1 and NIX1 blocks.
+
+MSIX ->
+Updated the MSIX mailbox and its handler to return
+MSIX offsets for the new block CPT1.
+
+Free resources ->
+Update free_rsrc mailbox and its handler to return
+the free resources count of new blocks NIX1 and CPT1
+
+Links ->
+Number of CGX,LBK and SDP links may vary between
+platforms. For example, in 98xx number of CGX and LBK
+links are more than 96xx. Hence the info about number
+of links present in hardware is useful for consumers to
+request link configuration properly. This patch sends
+this info in nix_lf_alloc_rsp.
+
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Rakesh Babu <rsaladi2@marvell.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/af/mbox.h  | 19 ++++-
+ .../net/ethernet/marvell/octeontx2/af/rvu.c   | 85 +++++++++++++++----
+ .../ethernet/marvell/octeontx2/af/rvu_nix.c   |  4 +
+ .../ethernet/marvell/octeontx2/af/rvu_reg.c   |  2 +-
+ .../marvell/octeontx2/af/rvu_struct.h         |  2 +
+ 5 files changed, 94 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+index 263a211294168..f46de8419b770 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+@@ -86,7 +86,7 @@ struct mbox_msghdr {
+ #define OTX2_MBOX_REQ_SIG (0xdead)
+ #define OTX2_MBOX_RSP_SIG (0xbeef)
+       u16 sig;         /* Signature, for validating corrupted msgs */
+-#define OTX2_MBOX_VERSION (0x0001)
++#define OTX2_MBOX_VERSION (0x0007)
+       u16 ver;         /* Version of msg's structure for this ID */
+       u16 next_msgoff; /* Offset of next msg within mailbox region */
+       int rc;          /* Msg process'ed response code */
+@@ -271,6 +271,17 @@ struct ready_msg_rsp {
+  * or to detach partial of a cetain resource type.
+  * Rest of the fields specify how many of what type to
+  * be attached.
++ * To request LFs from two blocks of same type this mailbox
++ * can be sent twice as below:
++ *      struct rsrc_attach *attach;
++ *       .. Allocate memory for message ..
++ *       attach->cptlfs = 3; <3 LFs from CPT0>
++ *       .. Send message ..
++ *       .. Allocate memory for message ..
++ *       attach->modify = 1;
++ *       attach->cpt_blkaddr = BLKADDR_CPT1;
++ *       attach->cptlfs = 2; <2 LFs from CPT1>
++ *       .. Send message ..
+  */
+ struct rsrc_attach {
+       struct mbox_msghdr hdr;
+@@ -281,6 +292,7 @@ struct rsrc_attach {
+       u16  ssow;
+       u16  timlfs;
+       u16  cptlfs;
++      int  cpt_blkaddr; /* BLKADDR_CPT0/BLKADDR_CPT1 or 0 for BLKADDR_CPT0 */
+ };
+ /* Structure for relinquishing resources.
+@@ -314,6 +326,8 @@ struct msix_offset_rsp {
+       u16  ssow_msixoff[MAX_RVU_BLKLF_CNT];
+       u16  timlf_msixoff[MAX_RVU_BLKLF_CNT];
+       u16  cptlf_msixoff[MAX_RVU_BLKLF_CNT];
++      u8   cpt1_lfs;
++      u16  cpt1_lf_msixoff[MAX_RVU_BLKLF_CNT];
+ };
+ struct get_hw_cap_rsp {
+@@ -491,6 +505,9 @@ struct nix_lf_alloc_rsp {
+       u8      lf_tx_stats; /* NIX_AF_CONST1::LF_TX_STATS */
+       u16     cints; /* NIX_AF_CONST2::CINTS */
+       u16     qints; /* NIX_AF_CONST2::QINTS */
++      u8      cgx_links;  /* No. of CGX links present in HW */
++      u8      lbk_links;  /* No. of LBK links present in HW */
++      u8      sdp_links;  /* No. of SDP links present in HW */
+ };
+ /* NIX AQ enqueue msg */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+index e8a2552fb690a..78309821ce298 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -1185,6 +1185,8 @@ static int rvu_detach_rsrcs(struct rvu *rvu, struct rsrc_detach *detach,
+                               continue;
+                       else if ((blkid == BLKADDR_NIX0) && !detach->nixlf)
+                               continue;
++                      else if ((blkid == BLKADDR_NIX1) && !detach->nixlf)
++                              continue;
+                       else if ((blkid == BLKADDR_SSO) && !detach->sso)
+                               continue;
+                       else if ((blkid == BLKADDR_SSOW) && !detach->ssow)
+@@ -1193,6 +1195,8 @@ static int rvu_detach_rsrcs(struct rvu *rvu, struct rsrc_detach *detach,
+                               continue;
+                       else if ((blkid == BLKADDR_CPT0) && !detach->cptlfs)
+                               continue;
++                      else if ((blkid == BLKADDR_CPT1) && !detach->cptlfs)
++                              continue;
+               }
+               rvu_detach_block(rvu, pcifunc, block->type);
+       }
+@@ -1242,7 +1246,8 @@ static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+       return pfvf->nix_blkaddr;
+ }
+-static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
++static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype,
++                                u16 pcifunc, struct rsrc_attach *attach)
+ {
+       int blkaddr;
+@@ -1250,6 +1255,14 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+       case BLKTYPE_NIX:
+               blkaddr = rvu_get_nix_blkaddr(rvu, pcifunc);
+               break;
++      case BLKTYPE_CPT:
++              if (attach->hdr.ver < RVU_MULTI_BLK_VER)
++                      return rvu_get_blkaddr(rvu, blktype, 0);
++              blkaddr = attach->cpt_blkaddr ? attach->cpt_blkaddr :
++                        BLKADDR_CPT0;
++              if (blkaddr != BLKADDR_CPT0 && blkaddr != BLKADDR_CPT1)
++                      return -ENODEV;
++              break;
+       default:
+               return rvu_get_blkaddr(rvu, blktype, 0);
+       };
+@@ -1260,8 +1273,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+       return -ENODEV;
+ }
+-static void rvu_attach_block(struct rvu *rvu, int pcifunc,
+-                           int blktype, int num_lfs)
++static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
++                           int num_lfs, struct rsrc_attach *attach)
+ {
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       struct rvu_hwinfo *hw = rvu->hw;
+@@ -1273,7 +1286,7 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc,
+       if (!num_lfs)
+               return;
+-      blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc);
++      blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc, attach);
+       if (blkaddr < 0)
+               return;
+@@ -1321,7 +1334,8 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
+       /* Only one NIX LF can be attached */
+       if (req->nixlf && !is_blktype_attached(pfvf, BLKTYPE_NIX)) {
+-              blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
++              blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX,
++                                               pcifunc, req);
+               if (blkaddr < 0)
+                       return blkaddr;
+               block = &hw->block[blkaddr];
+@@ -1383,7 +1397,11 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
+       }
+       if (req->cptlfs) {
+-              block = &hw->block[BLKADDR_CPT0];
++              blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_CPT,
++                                               pcifunc, req);
++              if (blkaddr < 0)
++                      return blkaddr;
++              block = &hw->block[blkaddr];
+               if (req->cptlfs > block->lf.max) {
+                       dev_err(&rvu->pdev->dev,
+                               "Func 0x%x: Invalid CPTLF req, %d > max %d\n",
+@@ -1404,6 +1422,22 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
+       return -ENOSPC;
+ }
++static bool rvu_attach_from_same_block(struct rvu *rvu, int blktype,
++                                     struct rsrc_attach *attach)
++{
++      int blkaddr, num_lfs;
++
++      blkaddr = rvu_get_attach_blkaddr(rvu, blktype,
++                                       attach->hdr.pcifunc, attach);
++      if (blkaddr < 0)
++              return false;
++
++      num_lfs = rvu_get_rsrc_mapcount(rvu_get_pfvf(rvu, attach->hdr.pcifunc),
++                                      blkaddr);
++      /* Requester already has LFs from given block ? */
++      return !!num_lfs;
++}
++
+ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
+                                     struct rsrc_attach *attach,
+                                     struct msg_rsp *rsp)
+@@ -1424,10 +1458,10 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
+       /* Now attach the requested resources */
+       if (attach->npalf)
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach);
+       if (attach->nixlf)
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach);
+       if (attach->sso) {
+               /* RVU func doesn't know which exact LF or slot is attached
+@@ -1437,25 +1471,30 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
+                */
+               if (attach->modify)
+                       rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO);
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO, attach->sso);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO,
++                               attach->sso, attach);
+       }
+       if (attach->ssow) {
+               if (attach->modify)
+                       rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW);
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW, attach->ssow);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW,
++                               attach->ssow, attach);
+       }
+       if (attach->timlfs) {
+               if (attach->modify)
+                       rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM);
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM, attach->timlfs);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM,
++                               attach->timlfs, attach);
+       }
+       if (attach->cptlfs) {
+-              if (attach->modify)
++              if (attach->modify &&
++                  rvu_attach_from_same_block(rvu, BLKTYPE_CPT, attach))
+                       rvu_detach_block(rvu, pcifunc, BLKTYPE_CPT);
+-              rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT, attach->cptlfs);
++              rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT,
++                               attach->cptlfs, attach);
+       }
+ exit:
+@@ -1533,7 +1572,7 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req,
+       struct rvu_hwinfo *hw = rvu->hw;
+       u16 pcifunc = req->hdr.pcifunc;
+       struct rvu_pfvf *pfvf;
+-      int lf, slot;
++      int lf, slot, blkaddr;
+       pfvf = rvu_get_pfvf(rvu, pcifunc);
+       if (!pfvf->msix.bmap)
+@@ -1543,8 +1582,14 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req,
+       lf = rvu_get_lf(rvu, &hw->block[BLKADDR_NPA], pcifunc, 0);
+       rsp->npa_msixoff = rvu_get_msix_offset(rvu, pfvf, BLKADDR_NPA, lf);
+-      lf = rvu_get_lf(rvu, &hw->block[BLKADDR_NIX0], pcifunc, 0);
+-      rsp->nix_msixoff = rvu_get_msix_offset(rvu, pfvf, BLKADDR_NIX0, lf);
++      /* Get BLKADDR from which LFs are attached to pcifunc */
++      blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
++      if (blkaddr < 0) {
++              rsp->nix_msixoff = MSIX_VECTOR_INVALID;
++      } else {
++              lf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
++              rsp->nix_msixoff = rvu_get_msix_offset(rvu, pfvf, blkaddr, lf);
++      }
+       rsp->sso = pfvf->sso;
+       for (slot = 0; slot < rsp->sso; slot++) {
+@@ -1573,6 +1618,14 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req,
+               rsp->cptlf_msixoff[slot] =
+                       rvu_get_msix_offset(rvu, pfvf, BLKADDR_CPT0, lf);
+       }
++
++      rsp->cpt1_lfs = pfvf->cpt1_lfs;
++      for (slot = 0; slot < rsp->cpt1_lfs; slot++) {
++              lf = rvu_get_lf(rvu, &hw->block[BLKADDR_CPT1], pcifunc, slot);
++              rsp->cpt1_lf_msixoff[slot] =
++                      rvu_get_msix_offset(rvu, pfvf, BLKADDR_CPT1, lf);
++      }
++
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index fb4b18be503c5..0a69d326f618c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -1179,6 +1179,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
+       cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
+       rsp->qints = ((cfg >> 12) & 0xFFF);
+       rsp->cints = ((cfg >> 24) & 0xFFF);
++      rsp->cgx_links = hw->cgx_links;
++      rsp->lbk_links = hw->lbk_links;
++      rsp->sdp_links = hw->sdp_links;
++
+       return rc;
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
+index 9d7c135c79659..e266f0c495595 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
+@@ -35,7 +35,7 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = {
+                             {0x1200, 0x12E0} } },
+       {NIX_TXSCH_LVL_TL3, 3, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608},
+                             {0x1610, 0x1618} } },
+-      {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x1768} } },
++      {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } },
+       {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } },
+ };
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
+index a3ecb5de90005..761e8e9f5299c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
+@@ -14,6 +14,8 @@
+ /* RVU Block revision IDs */
+ #define RVU_BLK_RVUM_REVID            0x01
++#define RVU_MULTI_BLK_VER             0x7ULL
++
+ /* RVU Block Address Enumeration */
+ enum rvu_block_addr_e {
+       BLKADDR_RVUM            = 0x0ULL,
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch b/queue-5.10/octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch
new file mode 100644 (file)
index 0000000..1beacc8
--- /dev/null
@@ -0,0 +1,67 @@
+From 2feee6ff37720b99b3afe4cba72f65f8ff750041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Oct 2020 10:45:47 +0530
+Subject: octeontx2-pf: Calculate LBK link instead of hardcoding
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit 8bcf5ced6526e1c4c8a2703f9ca9135fef7409d6 ]
+
+CGX links are followed by LBK links but number of
+CGX and LBK links varies between platforms. Hence
+get the number of links present in hardware from
+AF and use it to calculate LBK link number.
+
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Rakesh Babu <rsaladi2@marvell.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 8 ++++++--
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 2 ++
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index b062ed06235d2..3b4530bc30378 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -532,8 +532,10 @@ static int otx2_get_link(struct otx2_nic *pfvf)
+               link = 4 * ((map >> 8) & 0xF) + ((map >> 4) & 0xF);
+       }
+       /* LBK channel */
+-      if (pfvf->hw.tx_chan_base < SDP_CHAN_BASE)
+-              link = 12;
++      if (pfvf->hw.tx_chan_base < SDP_CHAN_BASE) {
++              map = pfvf->hw.tx_chan_base & 0x7FF;
++              link = pfvf->hw.cgx_links | ((map >> 8) & 0xF);
++      }
+       return link;
+ }
+@@ -1519,6 +1521,8 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
+       pfvf->hw.tx_chan_base = rsp->tx_chan_base;
+       pfvf->hw.lso_tsov4_idx = rsp->lso_tsov4_idx;
+       pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx;
++      pfvf->hw.cgx_links = rsp->cgx_links;
++      pfvf->hw.lbk_links = rsp->lbk_links;
+ }
+ EXPORT_SYMBOL(mbox_handler_nix_lf_alloc);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index d6253f2a414d3..386cb08497e48 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -197,6 +197,8 @@ struct otx2_hw {
+       struct otx2_drv_stats   drv_stats;
+       u64                     cgx_rx_stats[CGX_RX_STATS_COUNT];
+       u64                     cgx_tx_stats[CGX_TX_STATS_COUNT];
++      u8                      cgx_links;  /* No. of CGX links present in HW */
++      u8                      lbk_links;  /* No. of LBK links present in HW */
+ };
+ struct otx2_vf_config {
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch b/queue-5.10/octeontx2-pf-ethtool-fec-mode-support.patch
new file mode 100644 (file)
index 0000000..f8f0011
--- /dev/null
@@ -0,0 +1,337 @@
+From ad5f297a3dbe436e02aa4297b20cb343530928b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Feb 2021 16:05:27 +0530
+Subject: octeontx2-pf: ethtool fec mode support
+
+From: Christina Jacob <cjacob@marvell.com>
+
+[ Upstream commit d0cf9503e908ee7b235a5efecedeb74aabc482f3 ]
+
+Add ethtool support to configure fec modes baser/rs and
+support to fecth FEC stats from CGX as well PHY.
+
+Configure fec mode
+       - ethtool --set-fec eth0 encoding rs/baser/off/auto
+Query fec mode
+       - ethtool --show-fec eth0
+
+Signed-off-by: Christina Jacob <cjacob@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: e26f8eac6bb2 ("octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../marvell/octeontx2/nic/otx2_common.c       |  20 +++
+ .../marvell/octeontx2/nic/otx2_common.h       |   6 +
+ .../marvell/octeontx2/nic/otx2_ethtool.c      | 160 +++++++++++++++++-
+ .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |   3 +
+ 4 files changed, 188 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 3b4530bc30378..2b6baf0ad3f7d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -60,6 +60,19 @@ void otx2_update_lmac_stats(struct otx2_nic *pfvf)
+       mutex_unlock(&pfvf->mbox.lock);
+ }
++void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf)
++{
++      struct msg_req *req;
++
++      if (!netif_running(pfvf->netdev))
++              return;
++      mutex_lock(&pfvf->mbox.lock);
++      req = otx2_mbox_alloc_msg_cgx_fec_stats(&pfvf->mbox);
++      if (req)
++              otx2_sync_mbox_msg(&pfvf->mbox);
++      mutex_unlock(&pfvf->mbox.lock);
++}
++
+ int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx)
+ {
+       struct otx2_rcv_queue *rq = &pfvf->qset.rq[qidx];
+@@ -1492,6 +1505,13 @@ void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
+               pfvf->hw.cgx_tx_stats[id] = rsp->tx_stats[id];
+ }
++void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf,
++                              struct cgx_fec_stats_rsp *rsp)
++{
++      pfvf->hw.cgx_fec_corr_blks += rsp->fec_corr_blks;
++      pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks;
++}
++
+ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
+                                 struct nix_txsch_alloc_rsp *rsp)
+ {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 386cb08497e48..866b1a2cc9a12 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -197,6 +197,8 @@ struct otx2_hw {
+       struct otx2_drv_stats   drv_stats;
+       u64                     cgx_rx_stats[CGX_RX_STATS_COUNT];
+       u64                     cgx_tx_stats[CGX_TX_STATS_COUNT];
++      u64                     cgx_fec_corr_blks;
++      u64                     cgx_fec_uncorr_blks;
+       u8                      cgx_links;  /* No. of CGX links present in HW */
+       u8                      lbk_links;  /* No. of LBK links present in HW */
+ };
+@@ -627,6 +629,9 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
+                                 struct nix_txsch_alloc_rsp *rsp);
+ void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
+                           struct cgx_stats_rsp *rsp);
++void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf,
++                              struct cgx_fec_stats_rsp *rsp);
++void otx2_set_fec_stats_count(struct otx2_nic *pfvf);
+ void mbox_handler_nix_bp_enable(struct otx2_nic *pfvf,
+                               struct nix_bp_cfg_rsp *rsp);
+@@ -635,6 +640,7 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf);
+ void otx2_get_stats64(struct net_device *netdev,
+                     struct rtnl_link_stats64 *stats);
+ void otx2_update_lmac_stats(struct otx2_nic *pfvf);
++void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf);
+ int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx);
+ int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx);
+ void otx2_set_ethtool_ops(struct net_device *netdev);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+index fc4ca8246df24..540a16d0a3274 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+@@ -66,6 +66,8 @@ static const unsigned int otx2_n_dev_stats = ARRAY_SIZE(otx2_dev_stats);
+ static const unsigned int otx2_n_drv_stats = ARRAY_SIZE(otx2_drv_stats);
+ static const unsigned int otx2_n_queue_stats = ARRAY_SIZE(otx2_queue_stats);
++static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf);
++
+ static void otx2_get_drvinfo(struct net_device *netdev,
+                            struct ethtool_drvinfo *info)
+ {
+@@ -128,6 +130,10 @@ static void otx2_get_strings(struct net_device *netdev, u32 sset, u8 *data)
+       strcpy(data, "reset_count");
+       data += ETH_GSTRING_LEN;
++      sprintf(data, "Fec Corrected Errors: ");
++      data += ETH_GSTRING_LEN;
++      sprintf(data, "Fec Uncorrected Errors: ");
++      data += ETH_GSTRING_LEN;
+ }
+ static void otx2_get_qset_stats(struct otx2_nic *pfvf,
+@@ -160,11 +166,30 @@ static void otx2_get_qset_stats(struct otx2_nic *pfvf,
+       }
+ }
++static int otx2_get_phy_fec_stats(struct otx2_nic *pfvf)
++{
++      struct msg_req *req;
++      int rc = -ENOMEM;
++
++      mutex_lock(&pfvf->mbox.lock);
++      req = otx2_mbox_alloc_msg_cgx_get_phy_fec_stats(&pfvf->mbox);
++      if (!req)
++              goto end;
++
++      if (!otx2_sync_mbox_msg(&pfvf->mbox))
++              rc = 0;
++end:
++      mutex_unlock(&pfvf->mbox.lock);
++      return rc;
++}
++
+ /* Get device and per queue statistics */
+ static void otx2_get_ethtool_stats(struct net_device *netdev,
+                                  struct ethtool_stats *stats, u64 *data)
+ {
+       struct otx2_nic *pfvf = netdev_priv(netdev);
++      u64 fec_corr_blks, fec_uncorr_blks;
++      struct cgx_fw_data *rsp;
+       int stat;
+       otx2_get_dev_stats(pfvf);
+@@ -183,6 +208,32 @@ static void otx2_get_ethtool_stats(struct net_device *netdev,
+       for (stat = 0; stat < CGX_TX_STATS_COUNT; stat++)
+               *(data++) = pfvf->hw.cgx_tx_stats[stat];
+       *(data++) = pfvf->reset_count;
++
++      fec_corr_blks = pfvf->hw.cgx_fec_corr_blks;
++      fec_uncorr_blks = pfvf->hw.cgx_fec_uncorr_blks;
++
++      rsp = otx2_get_fwdata(pfvf);
++      if (!IS_ERR(rsp) && rsp->fwdata.phy.misc.has_fec_stats &&
++          !otx2_get_phy_fec_stats(pfvf)) {
++              /* Fetch fwdata again because it's been recently populated with
++               * latest PHY FEC stats.
++               */
++              rsp = otx2_get_fwdata(pfvf);
++              if (!IS_ERR(rsp)) {
++                      struct fec_stats_s *p = &rsp->fwdata.phy.fec_stats;
++
++                      if (pfvf->linfo.fec == OTX2_FEC_BASER) {
++                              fec_corr_blks   = p->brfec_corr_blks;
++                              fec_uncorr_blks = p->brfec_uncorr_blks;
++                      } else {
++                              fec_corr_blks   = p->rsfec_corr_cws;
++                              fec_uncorr_blks = p->rsfec_uncorr_cws;
++                      }
++              }
++      }
++
++      *(data++) = fec_corr_blks;
++      *(data++) = fec_uncorr_blks;
+ }
+ static int otx2_get_sset_count(struct net_device *netdev, int sset)
+@@ -195,9 +246,11 @@ static int otx2_get_sset_count(struct net_device *netdev, int sset)
+       qstats_count = otx2_n_queue_stats *
+                      (pfvf->hw.rx_queues + pfvf->hw.tx_queues);
++      otx2_update_lmac_fec_stats(pfvf);
+       return otx2_n_dev_stats + otx2_n_drv_stats + qstats_count +
+-              CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + 1;
++             CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + OTX2_FEC_STATS_CNT
++             + 1;
+ }
+ /* Get no of queues device supports and current queue count */
+@@ -700,6 +753,109 @@ static int otx2_get_ts_info(struct net_device *netdev,
+       return 0;
+ }
++static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf)
++{
++      struct cgx_fw_data *rsp = NULL;
++      struct msg_req *req;
++      int err = 0;
++
++      mutex_lock(&pfvf->mbox.lock);
++      req = otx2_mbox_alloc_msg_cgx_get_aux_link_info(&pfvf->mbox);
++      if (!req) {
++              mutex_unlock(&pfvf->mbox.lock);
++              return ERR_PTR(-ENOMEM);
++      }
++
++      err = otx2_sync_mbox_msg(&pfvf->mbox);
++      if (!err) {
++              rsp = (struct cgx_fw_data *)
++                      otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++      } else {
++              rsp = ERR_PTR(err);
++      }
++
++      mutex_unlock(&pfvf->mbox.lock);
++      return rsp;
++}
++
++static int otx2_get_fecparam(struct net_device *netdev,
++                           struct ethtool_fecparam *fecparam)
++{
++      struct otx2_nic *pfvf = netdev_priv(netdev);
++      struct cgx_fw_data *rsp;
++      const int fec[] = {
++              ETHTOOL_FEC_OFF,
++              ETHTOOL_FEC_BASER,
++              ETHTOOL_FEC_RS,
++              ETHTOOL_FEC_BASER | ETHTOOL_FEC_RS};
++#define FEC_MAX_INDEX 4
++      if (pfvf->linfo.fec < FEC_MAX_INDEX)
++              fecparam->active_fec = fec[pfvf->linfo.fec];
++
++      rsp = otx2_get_fwdata(pfvf);
++      if (IS_ERR(rsp))
++              return PTR_ERR(rsp);
++
++      if (rsp->fwdata.supported_fec <= FEC_MAX_INDEX) {
++              if (!rsp->fwdata.supported_fec)
++                      fecparam->fec = ETHTOOL_FEC_NONE;
++              else
++                      fecparam->fec = fec[rsp->fwdata.supported_fec];
++      }
++      return 0;
++}
++
++static int otx2_set_fecparam(struct net_device *netdev,
++                           struct ethtool_fecparam *fecparam)
++{
++      struct otx2_nic *pfvf = netdev_priv(netdev);
++      struct mbox *mbox = &pfvf->mbox;
++      struct fec_mode *req, *rsp;
++      int err = 0, fec = 0;
++
++      switch (fecparam->fec) {
++      /* Firmware does not support AUTO mode consider it as FEC_OFF */
++      case ETHTOOL_FEC_OFF:
++      case ETHTOOL_FEC_AUTO:
++              fec = OTX2_FEC_OFF;
++              break;
++      case ETHTOOL_FEC_RS:
++              fec = OTX2_FEC_RS;
++              break;
++      case ETHTOOL_FEC_BASER:
++              fec = OTX2_FEC_BASER;
++              break;
++      default:
++              netdev_warn(pfvf->netdev, "Unsupported FEC mode: %d",
++                          fecparam->fec);
++              return -EINVAL;
++      }
++
++      if (fec == pfvf->linfo.fec)
++              return 0;
++
++      mutex_lock(&mbox->lock);
++      req = otx2_mbox_alloc_msg_cgx_set_fec_param(&pfvf->mbox);
++      if (!req) {
++              err = -ENOMEM;
++              goto end;
++      }
++      req->fec = fec;
++      err = otx2_sync_mbox_msg(&pfvf->mbox);
++      if (err)
++              goto end;
++
++      rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
++                                                 0, &req->hdr);
++      if (rsp->fec >= 0)
++              pfvf->linfo.fec = rsp->fec;
++      else
++              err = rsp->fec;
++end:
++      mutex_unlock(&mbox->lock);
++      return err;
++}
++
+ static const struct ethtool_ops otx2_ethtool_ops = {
+       .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
+                                    ETHTOOL_COALESCE_MAX_FRAMES,
+@@ -725,6 +881,8 @@ static const struct ethtool_ops otx2_ethtool_ops = {
+       .get_pauseparam         = otx2_get_pauseparam,
+       .set_pauseparam         = otx2_set_pauseparam,
+       .get_ts_info            = otx2_get_ts_info,
++      .get_fecparam           = otx2_get_fecparam,
++      .set_fecparam           = otx2_set_fecparam,
+ };
+ void otx2_set_ethtool_ops(struct net_device *netdev)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index aada28868ac59..1516f24837754 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -787,6 +787,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf,
+       case MBOX_MSG_CGX_STATS:
+               mbox_handler_cgx_stats(pf, (struct cgx_stats_rsp *)msg);
+               break;
++      case MBOX_MSG_CGX_FEC_STATS:
++              mbox_handler_cgx_fec_stats(pf, (struct cgx_fec_stats_rsp *)msg);
++              break;
+       default:
+               if (msg->rc)
+                       dev_err(pf->dev,
+-- 
+2.43.0
+
diff --git a/queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch b/queue-5.10/octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch
new file mode 100644 (file)
index 0000000..6088cdc
--- /dev/null
@@ -0,0 +1,52 @@
+From ae3cee96bd1ff3baa6d878e124408f950487ab6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Oct 2024 19:02:29 +0000
+Subject: octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c
+
+From: Dipendra Khadka <kdipendra88@gmail.com>
+
+[ Upstream commit e26f8eac6bb20b20fdb8f7dc695711ebce4c7c5c ]
+
+Add error pointer check after calling otx2_mbox_get_rsp().
+
+Fixes: 75f36270990c ("octeontx2-pf: Support to enable/disable pause frames via ethtool")
+Fixes: d0cf9503e908 ("octeontx2-pf: ethtool fec mode support")
+Signed-off-by: Dipendra Khadka <kdipendra88@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c  | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+index 540a16d0a3274..3d0c090551e76 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+@@ -317,6 +317,11 @@ static void otx2_get_pauseparam(struct net_device *netdev,
+       if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
+               rsp = (struct cgx_pause_frm_cfg *)
+                      otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
++              if (IS_ERR(rsp)) {
++                      mutex_unlock(&pfvf->mbox.lock);
++                      return;
++              }
++
+               pause->rx_pause = rsp->rx_pause;
+               pause->tx_pause = rsp->tx_pause;
+       }
+@@ -847,6 +852,11 @@ static int otx2_set_fecparam(struct net_device *netdev,
+       rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
+                                                  0, &req->hdr);
++      if (IS_ERR(rsp)) {
++              err = PTR_ERR(rsp);
++              goto end;
++      }
++
+       if (rsp->fec >= 0)
+               pfvf->linfo.fec = rsp->fec;
+       else
+-- 
+2.43.0
+
diff --git a/queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch b/queue-5.10/pci-cpqphp-fix-pcibios_-return-value-confusion.patch
new file mode 100644 (file)
index 0000000..7ee0ca3
--- /dev/null
@@ -0,0 +1,85 @@
+From 72f820acc9518ecd05c9a9fe879cf531812747bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 12:11:37 +0300
+Subject: PCI: cpqphp: Fix PCIBIOS_* return value confusion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit e2226dbc4a4919d9c8bd9293299b532090bdf020 ]
+
+Code in and related to PCI_RefinedAccessConfig() has three types of return
+type confusion:
+
+ - PCI_RefinedAccessConfig() tests pci_bus_read_config_dword() return value
+   against -1.
+
+ - PCI_RefinedAccessConfig() returns both -1 and PCIBIOS_* return codes.
+
+ - Callers of PCI_RefinedAccessConfig() only test for -1.
+
+Make PCI_RefinedAccessConfig() return PCIBIOS_* codes consistently and
+adapt callers accordingly.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Link: https://lore.kernel.org/r/20241022091140.3504-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/cpqphp_pci.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
+index a20875da4ec70..ce6eb71a63599 100644
+--- a/drivers/pci/hotplug/cpqphp_pci.c
++++ b/drivers/pci/hotplug/cpqphp_pci.c
+@@ -135,11 +135,13 @@ int cpqhp_unconfigure_device(struct pci_func *func)
+ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
+ {
+       u32 vendID = 0;
++      int ret;
+-      if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
+-              return -1;
++      ret = pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID);
++      if (ret != PCIBIOS_SUCCESSFUL)
++              return PCIBIOS_DEVICE_NOT_FOUND;
+       if (PCI_POSSIBLE_ERROR(vendID))
+-              return -1;
++              return PCIBIOS_DEVICE_NOT_FOUND;
+       return pci_bus_read_config_dword(bus, devfn, offset, value);
+ }
+@@ -200,13 +202,15 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
+ {
+       u16 tdevice;
+       u32 work;
++      int ret;
+       u8 tbus;
+       ctrl->pci_bus->number = bus_num;
+       for (tdevice = 0; tdevice < 0xFF; tdevice++) {
+               /* Scan for access first */
+-              if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
++              ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work);
++              if (ret)
+                       continue;
+               dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
+               /* Yep we got one. Not a bridge ? */
+@@ -218,7 +222,8 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_
+       }
+       for (tdevice = 0; tdevice < 0xFF; tdevice++) {
+               /* Scan for access first */
+-              if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
++              ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work);
++              if (ret)
+                       continue;
+               dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
+               /* Yep we got one. bridge ? */
+-- 
+2.43.0
+
diff --git a/queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch b/queue-5.10/pci-cpqphp-use-pci_possible_error-to-check-config-re.patch
new file mode 100644 (file)
index 0000000..c1ef48a
--- /dev/null
@@ -0,0 +1,54 @@
+From 5f5a1f58a25084d7b02671d2e926a514db1b7392 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 14:50:50 +0800
+Subject: PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
+
+From: weiyufeng <weiyufeng@kylinos.cn>
+
+[ Upstream commit a18a025c2fb5fbf2d1d0606ea0d7441ac90e9c39 ]
+
+When config pci_ops.read() can detect failed PCI transactions, the data
+returned to the CPU is PCI_ERROR_RESPONSE (~0 or 0xffffffff).
+
+Obviously a successful PCI config read may *also* return that data if a
+config register happens to contain ~0, so it doesn't definitively indicate
+an error unless we know the register cannot contain ~0.
+
+Use PCI_POSSIBLE_ERROR() to check the response we get when we read data
+from hardware.  This unifies PCI error response checking and makes error
+checks consistent and easier to find.
+
+Link: https://lore.kernel.org/r/b12005c0d57bb9d4c8b486724d078b7bd92f8321.1637243717.git.naveennaidu479@gmail.com
+Signed-off-by: Naveen Naidu <naveennaidu479@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: e2226dbc4a49 ("PCI: cpqphp: Fix PCIBIOS_* return value confusion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/hotplug/cpqphp_pci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
+index 1b2b3f3b648bc..a20875da4ec70 100644
+--- a/drivers/pci/hotplug/cpqphp_pci.c
++++ b/drivers/pci/hotplug/cpqphp_pci.c
+@@ -138,7 +138,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 o
+       if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
+               return -1;
+-      if (vendID == 0xffffffff)
++      if (PCI_POSSIBLE_ERROR(vendID))
+               return -1;
+       return pci_bus_read_config_dword(bus, devfn, offset, value);
+ }
+@@ -251,7 +251,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
+                       *dev_num = tdevice;
+                       ctrl->pci_bus->number = tbus;
+                       pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
+-                      if (!nobridge || (work == 0xffffffff))
++                      if (!nobridge || PCI_POSSIBLE_ERROR(work))
+                               return 0;
+                       dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch b/queue-5.10/perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch
new file mode 100644 (file)
index 0000000..1dd7b47
--- /dev/null
@@ -0,0 +1,121 @@
+From 7667e3e4f0fe845394352ccda50bebacc07d419c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 14:57:32 +0100
+Subject: perf cs-etm: Don't flush when packet_queue fills up
+
+From: James Clark <james.clark@linaro.org>
+
+[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]
+
+cs_etm__flush(), like cs_etm__sample() is an operation that generates a
+sample and then swaps the current with the previous packet. Calling
+flush after processing the queues results in two swaps which corrupts
+the next sample. Therefore it wasn't appropriate to call flush here so
+remove it.
+
+Flushing is still done on a discontinuity to explicitly clear the last
+branch buffer, but when the packet_queue fills up before reaching a
+timestamp, that's not a discontinuity and the call to
+cs_etm__process_traceid_queue() already generated samples and drained
+the buffers correctly.
+
+This is visible by looking for a branch that has the same target as the
+previous branch and the following source is before the address of the
+last target, which is impossible as execution would have had to have
+gone backwards:
+
+  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
+   (packet_queue fills here before a timestamp, resulting in a flush and
+    branch target ffff80008011cadc is duplicated.)
+  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94
+  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
+
+After removing the flush the correct branch target is used for the
+second sample, and ffff8000801117c4 is no longer before the previous
+address:
+
+  ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
+  ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0
+  ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
+
+Make sure that a final branch stack is output at the end of the trace
+by calling cs_etm__end_block(). This is already done for both the
+timeless decode paths.
+
+Fixes: 21fe8dc1191a ("perf cs-etm: Add support for CPU-wide trace scenarios")
+Reported-by: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
+Closes: https://lore.kernel.org/all/20240719092619.274730-1-gankulkarni@os.amperecomputing.com/
+Reviewed-by: Leo Yan <leo.yan@arm.com>
+Signed-off-by: James Clark <james.clark@linaro.org>
+Tested-by: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>
+Cc: Ben Gainey <ben.gainey@arm.com>
+Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Ruidong Tian <tianruidong@linux.alibaba.com>
+Cc: Benjamin Gray <bgray@linux.ibm.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: coresight@lists.linaro.org
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: scclevenger@os.amperecomputing.com
+Link: https://lore.kernel.org/r/20240916135743.1490403-2-james.clark@linaro.org
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/cs-etm.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
+index a2a369e2fbb67..e3fa32b83367e 100644
+--- a/tools/perf/util/cs-etm.c
++++ b/tools/perf/util/cs-etm.c
+@@ -2098,12 +2098,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
+               /* Ignore return value */
+               cs_etm__process_traceid_queue(etmq, tidq);
+-
+-              /*
+-               * Generate an instruction sample with the remaining
+-               * branchstack entries.
+-               */
+-              cs_etm__flush(etmq, tidq);
+       }
+ }
+@@ -2186,7 +2180,7 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
+       while (1) {
+               if (!etm->heap.heap_cnt)
+-                      goto out;
++                      break;
+               /* Take the entry at the top of the min heap */
+               cs_queue_nr = etm->heap.heap_array[0].queue_nr;
+@@ -2269,6 +2263,23 @@ static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
+               ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, timestamp);
+       }
++      for (i = 0; i < etm->queues.nr_queues; i++) {
++              struct int_node *inode;
++
++              etmq = etm->queues.queue_array[i].priv;
++              if (!etmq)
++                      continue;
++
++              intlist__for_each_entry(inode, etmq->traceid_queues_list) {
++                      int idx = (int)(intptr_t)inode->priv;
++
++                      /* Flush any remaining branch stack entries */
++                      tidq = etmq->traceid_queues[idx];
++                      ret = cs_etm__end_block(etmq, tidq);
++                      if (ret)
++                              return ret;
++              }
++      }
+ out:
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch b/queue-5.10/perf-probe-correct-demangled-symbols-in-c-program.patch
new file mode 100644 (file)
index 0000000..47ebb79
--- /dev/null
@@ -0,0 +1,141 @@
+From ee61b049ac24bf8752a7c2c05e14f68434266028 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Oct 2024 15:14:32 +0100
+Subject: perf probe: Correct demangled symbols in C++ program
+
+From: Leo Yan <leo.yan@arm.com>
+
+[ Upstream commit 314909f13cc12d47c468602c37dace512d225eeb ]
+
+An issue can be observed when probe C++ demangled symbol with steps:
+
+  # nm test_cpp_mangle | grep print_data
+    0000000000000c94 t _GLOBAL__sub_I__Z10print_datai
+    0000000000000afc T _Z10print_datai
+    0000000000000b38 T _Z10print_dataR5Point
+
+  # perf probe -x /home/niayan01/test_cpp_mangle -F --demangle
+    ...
+    print_data(Point&)
+    print_data(int)
+    ...
+
+  # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
+    probe-definition(0): test=print_data(int)
+    symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
+    0 arguments
+    Open Debuginfo file: /home/niayan01/test_cpp_mangle
+    Try to find probe point from debuginfo.
+    Symbol print_data(int) address found : afc
+    Matched function: print_data [2ccf]
+    Probe point found: print_data+0
+    Found 1 probe_trace_events.
+    Opening /sys/kernel/tracing//uprobe_events write=1
+    Opening /sys/kernel/tracing//README write=0
+    Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xb38
+    ...
+
+When tried to probe symbol "print_data(int)", the log shows:
+
+    Symbol print_data(int) address found : afc
+
+The found address is 0xafc - which is right with verifying the output
+result from nm. Afterwards when write event, the command uses offset
+0xb38 in the last log, which is a wrong address.
+
+The dwarf_diename() gets a common function name, in above case, it
+returns string "print_data". As a result, the tool parses the offset
+based on the common name. This leads to probe at the wrong symbol
+"print_data(Point&)".
+
+To fix the issue, use the die_get_linkage_name() function to retrieve
+the distinct linkage name - this is the mangled name for the C++ case.
+Based on this unique name, the tool can get a correct offset for
+probing. Based on DWARF doc, it is possible the linkage name is missed
+in the DIE, it rolls back to use dwarf_diename().
+
+After:
+
+  # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
+    probe-definition(0): test=print_data(int)
+    symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
+    0 arguments
+    Open Debuginfo file: /home/niayan01/test_cpp_mangle
+    Try to find probe point from debuginfo.
+    Symbol print_data(int) address found : afc
+    Matched function: print_data [2d06]
+    Probe point found: print_data+0
+    Found 1 probe_trace_events.
+    Opening /sys/kernel/tracing//uprobe_events write=1
+    Opening /sys/kernel/tracing//README write=0
+    Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xafc
+    Added new event:
+      probe_test_cpp_mangle:test (on print_data(int) in /home/niayan01/test_cpp_mangle)
+
+    You can now use it in all perf tools, such as:
+
+            perf record -e probe_test_cpp_mangle:test -aR sleep 1
+
+  # perf --debug verbose=3 probe -x test_cpp_mangle --add "test2=print_data(Point&)"
+    probe-definition(0): test2=print_data(Point&)
+    symbol:print_data(Point&) file:(null) line:0 offset:0 return:0 lazy:(null)
+    0 arguments
+    Open Debuginfo file: /home/niayan01/test_cpp_mangle
+    Try to find probe point from debuginfo.
+    Symbol print_data(Point&) address found : b38
+    Matched function: print_data [2ccf]
+    Probe point found: print_data+0
+    Found 1 probe_trace_events.
+    Opening /sys/kernel/tracing//uprobe_events write=1
+    Parsing probe_events: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0x0000000000000afc
+    Group:probe_test_cpp_mangle Event:test probe:p
+    Opening /sys/kernel/tracing//README write=0
+    Writing event: p:probe_test_cpp_mangle/test2 /home/niayan01/test_cpp_mangle:0xb38
+    Added new event:
+      probe_test_cpp_mangle:test2 (on print_data(Point&) in /home/niayan01/test_cpp_mangle)
+
+    You can now use it in all perf tools, such as:
+
+            perf record -e probe_test_cpp_mangle:test2 -aR sleep 1
+
+Fixes: fb1587d869a3 ("perf probe: List probes with line number and file name")
+Signed-off-by: Leo Yan <leo.yan@arm.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20241012141432.877894-1-leo.yan@arm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/probe-finder.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
+index 31c779ce029db..8a98673fea380 100644
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -1729,8 +1729,21 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
+       /* Find a corresponding function (name, baseline and baseaddr) */
+       if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
+-              /* Get function entry information */
+-              func = basefunc = dwarf_diename(&spdie);
++              /*
++               * Get function entry information.
++               *
++               * As described in the document DWARF Debugging Information
++               * Format Version 5, section 2.22 Linkage Names, "mangled names,
++               * are used in various ways, ... to distinguish multiple
++               * entities that have the same name".
++               *
++               * Firstly try to get distinct linkage name, if fail then
++               * rollback to get associated name in DIE.
++               */
++              func = basefunc = die_get_linkage_name(&spdie);
++              if (!func)
++                      func = basefunc = dwarf_diename(&spdie);
++
+               if (!func ||
+                   die_entrypc(&spdie, &baseaddr) != 0 ||
+                   dwarf_decl_line(&spdie, &baseline) != 0) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-probe-fix-libdw-memory-leak.patch b/queue-5.10/perf-probe-fix-libdw-memory-leak.patch
new file mode 100644 (file)
index 0000000..a3919c4
--- /dev/null
@@ -0,0 +1,69 @@
+From fa366596647c9cc101682fcbc917e14bb2088633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 16:56:22 -0700
+Subject: perf probe: Fix libdw memory leak
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 4585038b8e186252141ef86e9f0d8e97f11dce8d ]
+
+Add missing dwarf_cfi_end to free memory associated with probe_finder
+cfi_eh which is allocated and owned via a call to
+dwarf_getcfi_elf. Confusingly cfi_dbg shouldn't be freed as its memory
+is owned by the passed in debuginfo struct. Add comments to highlight
+this.
+
+This addresses leak sanitizer issues seen in:
+tools/perf/tests/shell/test_uprobe_from_different_cu.sh
+
+Fixes: 270bde1e76f4 ("perf probe: Search both .eh_frame and .debug_frame sections for probe location")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Steinar H. Gunderson <sesse@google.com>
+Cc: Alexander Lobakin <aleksander.lobakin@intel.com>
+Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
+Link: https://lore.kernel.org/r/20241016235622.52166-3-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/probe-finder.c | 4 ++++
+ tools/perf/util/probe-finder.h | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
+index fdafbfcef6871..31c779ce029db 100644
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -1483,6 +1483,10 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
+       if (ret >= 0 && tf.pf.skip_empty_arg)
+               ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs);
++#if _ELFUTILS_PREREQ(0, 142)
++      dwarf_cfi_end(tf.pf.cfi_eh);
++#endif
++
+       if (ret < 0 || tf.ntevs == 0) {
+               for (i = 0; i < tf.ntevs; i++)
+                       clear_probe_trace_event(&tf.tevs[i]);
+diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
+index 2febb58756789..35eae263ffe74 100644
+--- a/tools/perf/util/probe-finder.h
++++ b/tools/perf/util/probe-finder.h
+@@ -81,9 +81,9 @@ struct probe_finder {
+       /* For variable searching */
+ #if _ELFUTILS_PREREQ(0, 142)
+-      /* Call Frame Information from .eh_frame */
++      /* Call Frame Information from .eh_frame. Owned by this struct. */
+       Dwarf_CFI               *cfi_eh;
+-      /* Call Frame Information from .debug_frame */
++      /* Call Frame Information from .debug_frame. Not owned. */
+       Dwarf_CFI               *cfi_dbg;
+ #endif
+       Dwarf_Op                *fb_ops;        /* Frame base attribute */
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-syscall.patch
new file mode 100644 (file)
index 0000000..20efb75
--- /dev/null
@@ -0,0 +1,63 @@
+From 74160c947438908c0593824ab95f4582a24864b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 23:21:27 +0000
+Subject: perf trace: Avoid garbage when not printing a syscall's arguments
+
+From: Benjamin Peterson <benjamin@engflow.com>
+
+[ Upstream commit 1302e352b26f34991b619b5d0b621b76d20a3883 ]
+
+syscall__scnprintf_args may not place anything in the output buffer
+(e.g., because the arguments are all zero). If that happened in
+trace__fprintf_sys_enter, its fprintf would receive an unitialized
+buffer leading to garbage output.
+
+Fix the problem by passing the (possibly zero) bounds of the argument
+buffer to the output fprintf.
+
+Fixes: a98392bb1e169a04 ("perf trace: Use beautifiers on syscalls:sys_enter_ handlers")
+Signed-off-by: Benjamin Peterson <benjamin@engflow.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Howard Chu <howardchu95@gmail.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241107232128.108981-2-benjamin@engflow.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 6fbdabd902802..68189e6347205 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2361,6 +2361,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
+       char msg[1024];
+       void *args, *augmented_args = NULL;
+       int augmented_args_size;
++      size_t printed = 0;
+       if (sc == NULL)
+               return -1;
+@@ -2376,8 +2377,8 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
+       args = perf_evsel__sc_tp_ptr(evsel, args, sample);
+       augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size);
+-      syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread);
+-      fprintf(trace->output, "%s", msg);
++      printed += syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread);
++      fprintf(trace->output, "%.*s", (int)printed, msg);
+       err = 0;
+ out_put:
+       thread__put(thread);
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch b/queue-5.10/perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch
new file mode 100644 (file)
index 0000000..803b68c
--- /dev/null
@@ -0,0 +1,41 @@
+From a6d3cfc04fdc214a5b5a4ee18a6d748c41028e85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Nov 2024 20:48:16 +0000
+Subject: perf trace: avoid garbage when not printing a trace event's arguments
+
+From: Benjamin Peterson <benjamin@engflow.com>
+
+[ Upstream commit 5fb8e56542a3cf469fdf25d77f50e21cbff3ae7e ]
+
+trace__fprintf_tp_fields may not print any tracepoint arguments. E.g., if the
+argument values are all zero. Previously, this would result in a totally
+uninitialized buffer being passed to fprintf, which could lead to garbage on the
+console. Fix the problem by passing the number of initialized bytes fprintf.
+
+Fixes: f11b2803bb88 ("perf trace: Allow choosing how to augment the tracepoint arguments")
+Signed-off-by: Benjamin Peterson <benjamin@engflow.com>
+Tested-by: Howard Chu <howardchu95@gmail.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Link: https://lore.kernel.org/r/20241103204816.7834-1-benjamin@engflow.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 8de0d0a740de4..3143601c1cb1f 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2748,7 +2748,7 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel,
+               printed += syscall_arg_fmt__scnprintf_val(arg, bf + printed, size - printed, &syscall_arg, val);
+       }
+-      return printed + fprintf(trace->output, "%s", bf);
++      return printed + fprintf(trace->output, "%.*s", (int)printed, bf);
+ }
+ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
+-- 
+2.43.0
+
diff --git a/queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch b/queue-5.10/perf-trace-do-not-lose-last-events-in-a-race.patch
new file mode 100644 (file)
index 0000000..4c04e9e
--- /dev/null
@@ -0,0 +1,74 @@
+From d41d5b8d524bca304216536935dc0275294cbc33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 23:21:26 +0000
+Subject: perf trace: Do not lose last events in a race
+
+From: Benjamin Peterson <benjamin@engflow.com>
+
+[ Upstream commit 3fd7c36973a250e17a4ee305a31545a9426021f4 ]
+
+If a perf trace event selector specifies a maximum number of events to output
+(i.e., "/nr=N/" syntax), the event printing handler, trace__event_handler,
+disables the event selector after the maximum number events are
+printed.
+
+Furthermore, trace__event_handler checked if the event selector was
+disabled before doing any work. This avoided exceeding the maximum
+number of events to print if more events were in the buffer before the
+selector was disabled.
+
+However, the event selector can be disabled for reasons other than
+exceeding the maximum number of events. In particular, when the traced
+subprocess exits, the main loop disables all event selectors. This meant
+the last events of a traced subprocess might be lost to the printing
+handler's short-circuiting logic.
+
+This nondeterministic problem could be seen by running the following many times:
+
+  $ perf trace -e syscalls:sys_enter_exit_group true
+
+trace__event_handler should simply check for exceeding the maximum number of
+events to print rather than the state of the event selector.
+
+Fixes: a9c5e6c1e9bff42c ("perf trace: Introduce per-event maximum number of events property")
+Signed-off-by: Benjamin Peterson <benjamin@engflow.com>
+Tested-by: Howard Chu <howardchu95@gmail.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20241107232128.108981-1-benjamin@engflow.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-trace.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 3143601c1cb1f..6fbdabd902802 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2757,13 +2757,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
+ {
+       struct thread *thread;
+       int callchain_ret = 0;
+-      /*
+-       * Check if we called perf_evsel__disable(evsel) due to, for instance,
+-       * this event's max_events having been hit and this is an entry coming
+-       * from the ring buffer that we should discard, since the max events
+-       * have already been considered/printed.
+-       */
+-      if (evsel->disabled)
++
++      if (evsel->nr_events_printed >= evsel->max_events)
+               return 0;
+       thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+-- 
+2.43.0
+
diff --git a/queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch b/queue-5.10/pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch
new file mode 100644 (file)
index 0000000..e23b454
--- /dev/null
@@ -0,0 +1,48 @@
+From 8e98b8901ef738946b6aee760e3ea710ebddfa22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 11:04:41 +0800
+Subject: pmdomain: ti-sci: Add missing of_node_put() for args.np
+
+From: Zhang Zekun <zhangzekun11@huawei.com>
+
+[ Upstream commit afc2331ef81657493c074592c409dac7c3cb8ccc ]
+
+of_parse_phandle_with_args() needs to call of_node_put() to decrement
+the refcount of args.np. So, Add the missing of_node_put() in the loop.
+
+Fixes: efa5c01cd7ee ("soc: ti: ti_sci_pm_domains: switch to use multiple genpds instead of one")
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Message-ID: <20241024030442.119506-2-zhangzekun11@huawei.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/ti_sci_pm_domains.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c
+index 17984a7bffba5..b21b152ed5d0f 100644
+--- a/drivers/soc/ti/ti_sci_pm_domains.c
++++ b/drivers/soc/ti/ti_sci_pm_domains.c
+@@ -165,6 +165,7 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+                               break;
+                       if (args.args_count >= 1 && args.np == dev->of_node) {
++                              of_node_put(args.np);
+                               if (args.args[0] > max_id) {
+                                       max_id = args.args[0];
+                               } else {
+@@ -192,7 +193,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev)
+                               pm_genpd_init(&pd->pd, NULL, true);
+                               list_add(&pd->node, &pd_provider->pd_list);
++                      } else {
++                              of_node_put(args.np);
+                       }
++
+                       index++;
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch b/queue-5.10/power-supply-bq27xxx-fix-registers-of-bq27426.patch
new file mode 100644 (file)
index 0000000..fdf5712
--- /dev/null
@@ -0,0 +1,88 @@
+From 684aea1875991c541bf5d471dbb2663939b519d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 20:54:05 +0200
+Subject: power: supply: bq27xxx: Fix registers of bq27426
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barnabás Czémán <barnabas.czeman@mainlining.org>
+
+[ Upstream commit 34f99d3b706a519e556841f405c224ca708b1f54 ]
+
+Correct bq27426 registers, according to technical reference manual
+it does not have Design Capacity register so it is not register
+compatible with bq27421.
+
+Fixes: 5ef6a16033b47 ("power: supply: bq27xxx: Add support for BQ27426")
+Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
+Link: https://lore.kernel.org/r/20241016-fix_bq27426-v2-1-aa6c0f51a9f6@mainlining.org
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 37 ++++++++++++++++++++++++--
+ 1 file changed, 35 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 21f6df21c3cc4..be2aac8fbf430 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -448,9 +448,29 @@ static u8
+               [BQ27XXX_REG_AP] = 0x18,
+               BQ27XXX_DM_REG_ROWS,
+       },
++      bq27426_regs[BQ27XXX_REG_MAX] = {
++              [BQ27XXX_REG_CTRL] = 0x00,
++              [BQ27XXX_REG_TEMP] = 0x02,
++              [BQ27XXX_REG_INT_TEMP] = 0x1e,
++              [BQ27XXX_REG_VOLT] = 0x04,
++              [BQ27XXX_REG_AI] = 0x10,
++              [BQ27XXX_REG_FLAGS] = 0x06,
++              [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_NAC] = 0x08,
++              [BQ27XXX_REG_RC] = 0x0c,
++              [BQ27XXX_REG_FCC] = 0x0e,
++              [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_SOC] = 0x1c,
++              [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_AP] = 0x18,
++              BQ27XXX_DM_REG_ROWS,
++      },
+ #define bq27411_regs bq27421_regs
+ #define bq27425_regs bq27421_regs
+-#define bq27426_regs bq27421_regs
+ #define bq27441_regs bq27421_regs
+ #define bq27621_regs bq27421_regs
+       bq27z561_regs[BQ27XXX_REG_MAX] = {
+@@ -747,10 +767,23 @@ static enum power_supply_property bq27421_props[] = {
+ };
+ #define bq27411_props bq27421_props
+ #define bq27425_props bq27421_props
+-#define bq27426_props bq27421_props
+ #define bq27441_props bq27421_props
+ #define bq27621_props bq27421_props
++static enum power_supply_property bq27426_props[] = {
++      POWER_SUPPLY_PROP_STATUS,
++      POWER_SUPPLY_PROP_PRESENT,
++      POWER_SUPPLY_PROP_VOLTAGE_NOW,
++      POWER_SUPPLY_PROP_CURRENT_NOW,
++      POWER_SUPPLY_PROP_CAPACITY,
++      POWER_SUPPLY_PROP_CAPACITY_LEVEL,
++      POWER_SUPPLY_PROP_TEMP,
++      POWER_SUPPLY_PROP_TECHNOLOGY,
++      POWER_SUPPLY_PROP_CHARGE_FULL,
++      POWER_SUPPLY_PROP_CHARGE_NOW,
++      POWER_SUPPLY_PROP_MANUFACTURER,
++};
++
+ static enum power_supply_property bq27z561_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_PRESENT,
+-- 
+2.43.0
+
diff --git a/queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch b/queue-5.10/power-supply-bq27xxx-support-charge_now-for-bq27z561.patch
new file mode 100644 (file)
index 0000000..f795153
--- /dev/null
@@ -0,0 +1,237 @@
+From 29482513a4da8210c4c02537c01d744b0e999a8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Dec 2020 19:07:20 +0800
+Subject: power: supply: bq27xxx: Support CHARGE_NOW for
+ bq27z561/bq28z610/bq34z100
+
+From: Hermes Zhang <chenhuiz@axis.com>
+
+[ Upstream commit 3ed510f06e12f8876c20474766cc2f101a41174f ]
+
+Currently REG_NAC (nominal available capacity) is mapped to
+power-supply's CHARGE_NOW property. Some chips do not have
+REG_NAC and do not expose CHARGE_NOW at the moment. Some
+bq27xxx chips also have another register REG_RM (remaining
+capacity). The difference between REG_NAC and REG_RM is load
+compensation.
+
+This patch adds register information for REG_RM for all
+supported fuel gauges. On systems having REG_NAC it is
+ignored, so behaviour does not change. On systems without
+REG_NAC, REG_RM will be used to provide CHARGE_NOW
+functionality.
+
+As a result there are three more chips exposing CHARGE_NOW:
+bq27z561, bq28z610 and bq34z100
+
+Signed-off-by: Hermes Zhang <chenhuiz@axis.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: 34f99d3b706a ("power: supply: bq27xxx: Fix registers of bq27426")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 35 +++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 0673e0fe0ffbd..21f6df21c3cc4 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -110,6 +110,7 @@ enum bq27xxx_reg_index {
+       BQ27XXX_REG_TTES,       /* Time-to-Empty Standby */
+       BQ27XXX_REG_TTECP,      /* Time-to-Empty at Constant Power */
+       BQ27XXX_REG_NAC,        /* Nominal Available Capacity */
++      BQ27XXX_REG_RC,         /* Remaining Capacity */
+       BQ27XXX_REG_FCC,        /* Full Charge Capacity */
+       BQ27XXX_REG_CYCT,       /* Cycle Count */
+       BQ27XXX_REG_AE,         /* Available Energy */
+@@ -145,6 +146,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -169,6 +171,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -193,6 +196,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1a,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -215,6 +219,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -237,6 +242,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1a,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x1e,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -257,6 +263,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -277,6 +284,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -297,6 +305,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = 0x26,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -317,6 +326,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1c,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x1e,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -337,6 +347,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_RC] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_FCC] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -361,6 +372,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -382,6 +394,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -405,6 +418,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x0c,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -425,6 +439,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = 0x08,
++              [BQ27XXX_REG_RC] = 0x0c,
+               [BQ27XXX_REG_FCC] = 0x0e,
+               [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
+@@ -450,6 +465,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -470,6 +486,7 @@ static u8
+               [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_RC] = 0x10,
+               [BQ27XXX_REG_FCC] = 0x12,
+               [BQ27XXX_REG_CYCT] = 0x2a,
+               [BQ27XXX_REG_AE] = 0x22,
+@@ -490,6 +507,7 @@ static u8
+               [BQ27XXX_REG_TTES] = 0x1e,
+               [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
+               [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
++              [BQ27XXX_REG_RC] = 0x04,
+               [BQ27XXX_REG_FCC] = 0x06,
+               [BQ27XXX_REG_CYCT] = 0x2c,
+               [BQ27XXX_REG_AE] = 0x24,
+@@ -745,6 +763,7 @@ static enum power_supply_property bq27z561_props[] = {
+       POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
++      POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CYCLE_COUNT,
+       POWER_SUPPLY_PROP_POWER_AVG,
+@@ -764,6 +783,7 @@ static enum power_supply_property bq28z610_props[] = {
+       POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
++      POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CYCLE_COUNT,
+       POWER_SUPPLY_PROP_POWER_AVG,
+@@ -784,6 +804,7 @@ static enum power_supply_property bq34z100_props[] = {
+       POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_CHARGE_FULL,
++      POWER_SUPPLY_PROP_CHARGE_NOW,
+       POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+       POWER_SUPPLY_PROP_CYCLE_COUNT,
+       POWER_SUPPLY_PROP_ENERGY_NOW,
+@@ -1508,6 +1529,15 @@ static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
+       return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
+ }
++/*
++ * Return the battery Remaining Capacity in ÂµAh
++ * Or < 0 if something fails.
++ */
++static inline int bq27xxx_battery_read_rc(struct bq27xxx_device_info *di)
++{
++      return bq27xxx_battery_read_charge(di, BQ27XXX_REG_RC);
++}
++
+ /*
+  * Return the battery Full Charge Capacity in ÂµAh
+  * Or < 0 if something fails.
+@@ -1979,7 +2009,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+                       val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_NOW:
+-              ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
++              if (di->regs[BQ27XXX_REG_NAC] != INVALID_REG_ADDR)
++                      ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
++              else
++                      ret = bq27xxx_simple_value(bq27xxx_battery_read_rc(di), val);
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_FULL:
+               ret = bq27xxx_simple_value(di->cache.charge_full, val);
+-- 
+2.43.0
+
diff --git a/queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch b/queue-5.10/power-supply-core-remove-might_sleep-from-power_supp.patch
new file mode 100644 (file)
index 0000000..17153d2
--- /dev/null
@@ -0,0 +1,44 @@
+From abf3cc4ef8379ef2ac10f5b107200f9c1aa0c9f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Sep 2024 12:39:14 -0700
+Subject: power: supply: core: Remove might_sleep() from power_supply_put()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit f6da4553ff24a5d1c959c9627c965323adc3d307 ]
+
+The put_device() call in power_supply_put() may call
+power_supply_dev_release(). The latter function does not sleep so
+power_supply_put() doesn't sleep either. Hence, remove the might_sleep()
+call from power_supply_put(). This patch suppresses false positive
+complaints about calling a sleeping function from atomic context if
+power_supply_put() is called from atomic context.
+
+Cc: Kyle Tso <kyletso@google.com>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Fixes: 1a352462b537 ("power_supply: Add power_supply_put for decrementing device reference counter")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240917193914.47566-1-bvanassche@acm.org
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/power_supply_core.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 5c8c117b396e7..61ba2b343b938 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -479,8 +479,6 @@ EXPORT_SYMBOL_GPL(power_supply_get_by_name);
+  */
+ void power_supply_put(struct power_supply *psy)
+ {
+-      might_sleep();
+-
+       atomic_dec(&psy->use_cnt);
+       put_device(&psy->dev);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch b/queue-5.10/powerpc-kexec-fix-return-of-uninitialized-variable.patch
new file mode 100644 (file)
index 0000000..4c4a5c6
--- /dev/null
@@ -0,0 +1,49 @@
+From 472c72843d35dc36b01bd19e71af63d03d798ec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 15:56:28 +0800
+Subject: powerpc/kexec: Fix return of uninitialized variable
+
+From: Zhang Zekun <zhangzekun11@huawei.com>
+
+[ Upstream commit 83b5a407fbb73e6965adfb4bd0a803724bf87f96 ]
+
+of_property_read_u64() can fail and leave the variable uninitialized,
+which will then be used. Return error if reading the property failed.
+
+Fixes: 2e6bd221d96f ("powerpc/kexec_file: Enable early kernel OPAL calls")
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://patch.msgid.link/20240930075628.125138-1-zhangzekun11@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kexec/file_load_64.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index a8a7cb71086b3..cb3fc0042cc25 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -909,13 +909,18 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
+       if (dn) {
+               u64 val;
+-              of_property_read_u64(dn, "opal-base-address", &val);
++              ret = of_property_read_u64(dn, "opal-base-address", &val);
++              if (ret)
++                      goto out;
++
+               ret = kexec_purgatory_get_set_symbol(image, "opal_base", &val,
+                                                    sizeof(val), false);
+               if (ret)
+                       goto out;
+-              of_property_read_u64(dn, "opal-entry-address", &val);
++              ret = of_property_read_u64(dn, "opal-entry-address", &val);
++              if (ret)
++                      goto out;
+               ret = kexec_purgatory_get_set_symbol(image, "opal_entry", &val,
+                                                    sizeof(val), false);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch b/queue-5.10/powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch
new file mode 100644 (file)
index 0000000..b66518b
--- /dev/null
@@ -0,0 +1,153 @@
+From cd29675884e6f4c885424c2163b30c831b51e554 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 22:24:01 +1000
+Subject: powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit cadae3a45d23aa4f6485938a67cbc47aaaa25e38 ]
+
+The dtl_access_lock needs to be a rw_sempahore, a sleeping lock, because
+the code calls kmalloc() while holding it, which can sleep:
+
+  # echo 1 > /proc/powerpc/vcpudispatch_stats
+  BUG: sleeping function called from invalid context at include/linux/sched/mm.h:337
+  in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 199, name: sh
+  preempt_count: 1, expected: 0
+  3 locks held by sh/199:
+   #0: c00000000a0743f8 (sb_writers#3){.+.+}-{0:0}, at: vfs_write+0x324/0x438
+   #1: c0000000028c7058 (dtl_enable_mutex){+.+.}-{3:3}, at: vcpudispatch_stats_write+0xd4/0x5f4
+   #2: c0000000028c70b8 (dtl_access_lock){+.+.}-{2:2}, at: vcpudispatch_stats_write+0x220/0x5f4
+  CPU: 0 PID: 199 Comm: sh Not tainted 6.10.0-rc4 #152
+  Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries
+  Call Trace:
+    dump_stack_lvl+0x130/0x148 (unreliable)
+    __might_resched+0x174/0x410
+    kmem_cache_alloc_noprof+0x340/0x3d0
+    alloc_dtl_buffers+0x124/0x1ac
+    vcpudispatch_stats_write+0x2a8/0x5f4
+    proc_reg_write+0xf4/0x150
+    vfs_write+0xfc/0x438
+    ksys_write+0x88/0x148
+    system_call_exception+0x1c4/0x5a0
+    system_call_common+0xf4/0x258
+
+Fixes: 06220d78f24a ("powerpc/pseries: Introduce rwlock to gatekeep DTLB usage")
+Tested-by: Kajol Jain <kjain@linux.ibm.com>
+Reviewed-by: Nysal Jan K.A <nysal@linux.ibm.com>
+Reviewed-by: Kajol Jain <kjain@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://patch.msgid.link/20240819122401.513203-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/dtl.h        | 4 ++--
+ arch/powerpc/platforms/pseries/dtl.c  | 8 ++++----
+ arch/powerpc/platforms/pseries/lpar.c | 8 ++++----
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/dtl.h b/arch/powerpc/include/asm/dtl.h
+index 1625888f27ef6..5e40f27aa76e5 100644
+--- a/arch/powerpc/include/asm/dtl.h
++++ b/arch/powerpc/include/asm/dtl.h
+@@ -1,8 +1,8 @@
+ #ifndef _ASM_POWERPC_DTL_H
+ #define _ASM_POWERPC_DTL_H
++#include <linux/rwsem.h>
+ #include <asm/lppaca.h>
+-#include <linux/spinlock_types.h>
+ /*
+  * Layout of entries in the hypervisor's dispatch trace log buffer.
+@@ -35,7 +35,7 @@ struct dtl_entry {
+ #define DTL_LOG_ALL           (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
+ extern struct kmem_cache *dtl_cache;
+-extern rwlock_t dtl_access_lock;
++extern struct rw_semaphore dtl_access_lock;
+ /*
+  * When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE = y, the cpu accounting code controls
+diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
+index 982f069e4c318..36a2eb23dbdc4 100644
+--- a/arch/powerpc/platforms/pseries/dtl.c
++++ b/arch/powerpc/platforms/pseries/dtl.c
+@@ -181,7 +181,7 @@ static int dtl_enable(struct dtl *dtl)
+               return -EBUSY;
+       /* ensure there are no other conflicting dtl users */
+-      if (!read_trylock(&dtl_access_lock))
++      if (!down_read_trylock(&dtl_access_lock))
+               return -EBUSY;
+       n_entries = dtl_buf_entries;
+@@ -189,7 +189,7 @@ static int dtl_enable(struct dtl *dtl)
+       if (!buf) {
+               printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
+                               __func__, dtl->cpu);
+-              read_unlock(&dtl_access_lock);
++              up_read(&dtl_access_lock);
+               return -ENOMEM;
+       }
+@@ -207,7 +207,7 @@ static int dtl_enable(struct dtl *dtl)
+       spin_unlock(&dtl->lock);
+       if (rc) {
+-              read_unlock(&dtl_access_lock);
++              up_read(&dtl_access_lock);
+               kmem_cache_free(dtl_cache, buf);
+       }
+@@ -222,7 +222,7 @@ static void dtl_disable(struct dtl *dtl)
+       dtl->buf = NULL;
+       dtl->buf_entries = 0;
+       spin_unlock(&dtl->lock);
+-      read_unlock(&dtl_access_lock);
++      up_read(&dtl_access_lock);
+ }
+ /* file interface */
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index aed67f1a1bc56..b19de0faf913c 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -166,7 +166,7 @@ struct vcpu_dispatch_data {
+  */
+ #define NR_CPUS_H     NR_CPUS
+-DEFINE_RWLOCK(dtl_access_lock);
++DECLARE_RWSEM(dtl_access_lock);
+ static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data);
+ static DEFINE_PER_CPU(u64, dtl_entry_ridx);
+ static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
+@@ -460,7 +460,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
+ {
+       int rc = 0, state;
+-      if (!write_trylock(&dtl_access_lock)) {
++      if (!down_write_trylock(&dtl_access_lock)) {
+               rc = -EBUSY;
+               goto out;
+       }
+@@ -476,7 +476,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
+               pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n");
+               free_dtl_buffers(time_limit);
+               reset_global_dtl_mask();
+-              write_unlock(&dtl_access_lock);
++              up_write(&dtl_access_lock);
+               rc = -EINVAL;
+               goto out;
+       }
+@@ -491,7 +491,7 @@ static void dtl_worker_disable(unsigned long *time_limit)
+       cpuhp_remove_state(dtl_worker_state);
+       free_dtl_buffers(time_limit);
+       reset_global_dtl_mask();
+-      write_unlock(&dtl_access_lock);
++      up_write(&dtl_access_lock);
+ }
+ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
+-- 
+2.43.0
+
diff --git a/queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch b/queue-5.10/powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch
new file mode 100644 (file)
index 0000000..4d9b5a4
--- /dev/null
@@ -0,0 +1,76 @@
+From 25b31fc3b578bb24ea66b20b27faf09404564212 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 15:03:49 +0200
+Subject: powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
+
+From: Michal Suchanek <msuchanek@suse.de>
+
+[ Upstream commit a26c4dbb3d9c1821cb0fc11cb2dbc32d5bf3463b ]
+
+These functions are not used outside of sstep.c
+
+Fixes: 350779a29f11 ("powerpc: Handle most loads and stores in instruction emulation code")
+Signed-off-by: Michal Suchanek <msuchanek@suse.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://patch.msgid.link/20241001130356.14664-1-msuchanek@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/sstep.h |  5 -----
+ arch/powerpc/lib/sstep.c         | 12 ++++--------
+ 2 files changed, 4 insertions(+), 13 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
+index 972ed0df154d6..35765c30fef2c 100644
+--- a/arch/powerpc/include/asm/sstep.h
++++ b/arch/powerpc/include/asm/sstep.h
+@@ -174,9 +174,4 @@ extern int emulate_step(struct pt_regs *regs, struct ppc_inst instr);
+  */
+ extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op);
+-extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+-                           const void *mem, bool cross_endian);
+-extern void emulate_vsx_store(struct instruction_op *op,
+-                            const union vsx_reg *reg, void *mem,
+-                            bool cross_endian);
+ extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
+diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
+index ca4733fbd02de..568a888d169d7 100644
+--- a/arch/powerpc/lib/sstep.c
++++ b/arch/powerpc/lib/sstep.c
+@@ -706,8 +706,8 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea,
+ #endif /* __powerpc64 */
+ #ifdef CONFIG_VSX
+-void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+-                    const void *mem, bool rev)
++static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
++                                           const void *mem, bool rev)
+ {
+       int size, read_size;
+       int i, j;
+@@ -787,11 +787,9 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+               break;
+       }
+ }
+-EXPORT_SYMBOL_GPL(emulate_vsx_load);
+-NOKPROBE_SYMBOL(emulate_vsx_load);
+-void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
+-                     void *mem, bool rev)
++static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
++                                            void *mem, bool rev)
+ {
+       int size, write_size;
+       int i, j;
+@@ -863,8 +861,6 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
+               break;
+       }
+ }
+-EXPORT_SYMBOL_GPL(emulate_vsx_store);
+-NOKPROBE_SYMBOL(emulate_vsx_store);
+ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
+                                      unsigned long ea, struct pt_regs *regs,
+-- 
+2.43.0
+
diff --git a/queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch b/queue-5.10/powerpc-vdso-flag-vdso64-entry-points-as-functions.patch
new file mode 100644 (file)
index 0000000..25906a4
--- /dev/null
@@ -0,0 +1,112 @@
+From 68ce987d25214357b0b0f7c1ccf3770a839b7209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Oct 2024 00:17:57 +0200
+Subject: powerpc/vdso: Flag VDSO64 entry points as functions
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 0161bd38c24312853ed5ae9a425a1c41c4ac674a ]
+
+On powerpc64 as shown below by readelf, vDSO functions symbols have
+type NOTYPE.
+
+$ powerpc64-linux-gnu-readelf -a arch/powerpc/kernel/vdso/vdso64.so.dbg
+ELF Header:
+  Magic:   7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00
+  Class:                             ELF64
+  Data:                              2's complement, big endian
+  Version:                           1 (current)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN (Shared object file)
+  Machine:                           PowerPC64
+  Version:                           0x1
+...
+
+Symbol table '.dynsym' contains 12 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+...
+     1: 0000000000000524    84 NOTYPE  GLOBAL DEFAULT    8 __[...]@@LINUX_2.6.15
+...
+     4: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LINUX_2.6.15
+     5: 00000000000006c0    48 NOTYPE  GLOBAL DEFAULT    8 __[...]@@LINUX_2.6.15
+
+Symbol table '.symtab' contains 56 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+...
+    45: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LINUX_2.6.15
+    46: 00000000000006c0    48 NOTYPE  GLOBAL DEFAULT    8 __kernel_getcpu
+    47: 0000000000000524    84 NOTYPE  GLOBAL DEFAULT    8 __kernel_clock_getres
+
+To overcome that, commit ba83b3239e65 ("selftests: vDSO: fix vDSO
+symbols lookup for powerpc64") was applied to have selftests also
+look for NOTYPE symbols, but the correct fix should be to flag VDSO
+entry points as functions.
+
+The original commit that brought VDSO support into powerpc/64 has the
+following explanation:
+
+    Note that the symbols exposed by the vDSO aren't "normal" function symbols, apps
+    can't be expected to link against them directly, the vDSO's are both seen
+    as if they were linked at 0 and the symbols just contain offsets to the
+    various functions.  This is done on purpose to avoid a relocation step
+    (ppc64 functions normally have descriptors with abs addresses in them).
+    When glibc uses those functions, it's expected to use it's own trampolines
+    that know how to reach them.
+
+The descriptors it's talking about are the OPD function descriptors
+used on ABI v1 (big endian). But it would be more correct for a text
+symbol to have type function, even if there's no function descriptor
+for it.
+
+glibc has a special case already for handling the VDSO symbols which
+creates a fake opd pointing at the kernel symbol. So changing the VDSO
+symbol type to function shouldn't affect that.
+
+For ABI v2, there is no function descriptors and VDSO functions can
+safely have function type.
+
+So lets flag VDSO entry points as functions and revert the
+selftest change.
+
+Link: https://github.com/mpe/linux-fullhistory/commit/5f2dd691b62da9d9cc54b938f8b29c22c93cb805
+Fixes: ba83b3239e65 ("selftests: vDSO: fix vDSO symbols lookup for powerpc64")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-By: Segher Boessenkool <segher@kernel.crashing.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://patch.msgid.link/b6ad2f1ee9887af3ca5ecade2a56f4acda517a85.1728512263.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/vdso.h           | 1 +
+ tools/testing/selftests/vDSO/parse_vdso.c | 3 +--
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h
+index 2ff884853f975..e3768f1161d23 100644
+--- a/arch/powerpc/include/asm/vdso.h
++++ b/arch/powerpc/include/asm/vdso.h
+@@ -27,6 +27,7 @@ int vdso_getcpu_init(void);
+ #ifdef __VDSO64__
+ #define V_FUNCTION_BEGIN(name)                \
+       .globl name;                    \
++      .type name,@function;           \
+       name:                           \
+ #define V_FUNCTION_END(name)          \
+diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
+index d9ccc5acac182..4ae417372e9eb 100644
+--- a/tools/testing/selftests/vDSO/parse_vdso.c
++++ b/tools/testing/selftests/vDSO/parse_vdso.c
+@@ -216,8 +216,7 @@ void *vdso_sym(const char *version, const char *name)
+               ELF(Sym) *sym = &vdso_info.symtab[chain];
+               /* Check for a defined global or weak function w/ right name. */
+-              if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC &&
+-                  ELF64_ST_TYPE(sym->st_info) != STT_NOTYPE)
++              if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+                       continue;
+               if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+                   ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+-- 
+2.43.0
+
diff --git a/queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch b/queue-5.10/pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch
new file mode 100644 (file)
index 0000000..aa99e05
--- /dev/null
@@ -0,0 +1,190 @@
+From d1f6febb18315044f2b13013e2b615c9cbc39f50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 15:41:23 -0400
+Subject: pwm: imx27: Workaround of the pwm output bug when decrease the duty
+ cycle
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Clark Wang <xiaoning.wang@nxp.com>
+
+[ Upstream commit a25351e4c7740eb22561a3ee4ef17611c6f410b0 ]
+
+Implement workaround for ERR051198
+(https://www.nxp.com/docs/en/errata/IMX8MN_0N14Y.pdf)
+
+PWM output may not function correctly if the FIFO is empty when a new SAR
+value is programmed.
+
+Description:
+  When the PWM FIFO is empty, a new value programmed to the PWM Sample
+  register (PWM_PWMSAR) will be directly applied even if the current timer
+  period has not expired. If the new SAMPLE value programmed in the
+  PWM_PWMSAR register is less than the previous value, and the PWM counter
+  register (PWM_PWMCNR) that contains the current COUNT value is greater
+  than the new programmed SAMPLE value, the current period will not flip
+  the level. This may result in an output pulse with a duty cycle of 100%.
+
+Workaround:
+  Program the current SAMPLE value in the PWM_PWMSAR register before
+  updating the new duty cycle to the SAMPLE value in the PWM_PWMSAR
+  register. This will ensure that the new SAMPLE value is modified during
+  a non-empty FIFO, and can be successfully updated after the period
+  expires.
+
+Write the old SAR value before updating the new duty cycle to SAR. This
+avoids writing the new value into an empty FIFO.
+
+This only resolves the issue when the PWM period is longer than 2us
+(or <500kHz) because write register is not quick enough when PWM period is
+very short.
+
+Reproduce steps:
+  cd /sys/class/pwm/pwmchip1/pwm0
+  echo 2000000000 > period     # It is easy to observe by using long period
+  echo 1000000000 > duty_cycle
+  echo 1 > enable
+  echo       8000 > duty_cycle # One full high pulse will be seen by scope
+
+Fixes: 166091b1894d ("[ARM] MXC: add pwm driver for i.MX SoCs")
+Reviewed-by: Jun Li <jun.li@nxp.com>
+Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20241008194123.1943141-1-Frank.Li@nxp.com
+Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-imx27.c | 98 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 96 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
+index 86bcafd23e4f6..3c7929ca3b921 100644
+--- a/drivers/pwm/pwm-imx27.c
++++ b/drivers/pwm/pwm-imx27.c
+@@ -26,6 +26,7 @@
+ #define MX3_PWMSR                     0x04    /* PWM Status Register */
+ #define MX3_PWMSAR                    0x0C    /* PWM Sample Register */
+ #define MX3_PWMPR                     0x10    /* PWM Period Register */
++#define MX3_PWMCNR                    0x14    /* PWM Counter Register */
+ #define MX3_PWMCR_FWM                 GENMASK(27, 26)
+ #define MX3_PWMCR_STOPEN              BIT(25)
+@@ -215,11 +216,13 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
+ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+                          const struct pwm_state *state)
+ {
+-      unsigned long period_cycles, duty_cycles, prescale;
++      unsigned long period_cycles, duty_cycles, prescale, period_us, tmp;
+       struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
+       struct pwm_state cstate;
+       unsigned long long c;
+       unsigned long long clkrate;
++      unsigned long flags;
++      int val;
+       int ret;
+       u32 cr;
+@@ -262,7 +265,98 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+               pwm_imx27_sw_reset(chip);
+       }
+-      writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
++      val = readl(imx->mmio_base + MX3_PWMPR);
++      val = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val;
++      cr = readl(imx->mmio_base + MX3_PWMCR);
++      tmp = NSEC_PER_SEC * (u64)(val + 2) * MX3_PWMCR_PRESCALER_GET(cr);
++      tmp = DIV_ROUND_UP_ULL(tmp, clkrate);
++      period_us = DIV_ROUND_UP_ULL(tmp, 1000);
++
++      /*
++       * ERR051198:
++       * PWM: PWM output may not function correctly if the FIFO is empty when
++       * a new SAR value is programmed
++       *
++       * Description:
++       * When the PWM FIFO is empty, a new value programmed to the PWM Sample
++       * register (PWM_PWMSAR) will be directly applied even if the current
++       * timer period has not expired.
++       *
++       * If the new SAMPLE value programmed in the PWM_PWMSAR register is
++       * less than the previous value, and the PWM counter register
++       * (PWM_PWMCNR) that contains the current COUNT value is greater than
++       * the new programmed SAMPLE value, the current period will not flip
++       * the level. This may result in an output pulse with a duty cycle of
++       * 100%.
++       *
++       * Consider a change from
++       *     ________
++       *    /        \______/
++       *    ^      *        ^
++       * to
++       *     ____
++       *    /    \__________/
++       *    ^               ^
++       * At the time marked by *, the new write value will be directly applied
++       * to SAR even the current period is not over if FIFO is empty.
++       *
++       *     ________        ____________________
++       *    /        \______/                    \__________/
++       *    ^               ^      *        ^               ^
++       *    |<-- old SAR -->|               |<-- new SAR -->|
++       *
++       * That is the output is active for a whole period.
++       *
++       * Workaround:
++       * Check new SAR less than old SAR and current counter is in errata
++       * windows, write extra old SAR into FIFO and new SAR will effect at
++       * next period.
++       *
++       * Sometime period is quite long, such as over 1 second. If add old SAR
++       * into FIFO unconditional, new SAR have to wait for next period. It
++       * may be too long.
++       *
++       * Turn off the interrupt to ensure that not IRQ and schedule happen
++       * during above operations. If any irq and schedule happen, counter
++       * in PWM will be out of data and take wrong action.
++       *
++       * Add a safety margin 1.5us because it needs some time to complete
++       * IO write.
++       *
++       * Use writel_relaxed() to minimize the interval between two writes to
++       * the SAR register to increase the fastest PWM frequency supported.
++       *
++       * When the PWM period is longer than 2us(or <500kHz), this workaround
++       * can solve this problem. No software workaround is available if PWM
++       * period is shorter than IO write. Just try best to fill old data
++       * into FIFO.
++       */
++      c = clkrate * 1500;
++      do_div(c, NSEC_PER_SEC);
++
++      local_irq_save(flags);
++      val = FIELD_GET(MX3_PWMSR_FIFOAV, readl_relaxed(imx->mmio_base + MX3_PWMSR));
++
++      if (duty_cycles < imx->duty_cycle && (cr & MX3_PWMCR_EN)) {
++              if (period_us < 2) { /* 2us = 500 kHz */
++                      /* Best effort attempt to fix up >500 kHz case */
++                      udelay(3 * period_us);
++                      writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++                      writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++              } else if (val < MX3_PWMSR_FIFOAV_2WORDS) {
++                      val = readl_relaxed(imx->mmio_base + MX3_PWMCNR);
++                      /*
++                       * If counter is close to period, controller may roll over when
++                       * next IO write.
++                       */
++                      if ((val + c >= duty_cycles && val < imx->duty_cycle) ||
++                          val + c >= period_cycles)
++                              writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR);
++              }
++      }
++      writel_relaxed(duty_cycles, imx->mmio_base + MX3_PWMSAR);
++      local_irq_restore(flags);
++
+       writel(period_cycles, imx->mmio_base + MX3_PWMPR);
+       /*
+-- 
+2.43.0
+
diff --git a/queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch b/queue-5.10/rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch
new file mode 100644 (file)
index 0000000..8d341fc
--- /dev/null
@@ -0,0 +1,80 @@
+From 38f3f0678620ec06d988d712b2d058812baa1ca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 03:06:54 -0700
+Subject: RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 808ca6de989c598bc5af1ae0ad971a66077efac0 ]
+
+Invalidate rkey is cpu endian and immediate data is in big endian format.
+Both immediate data and invalidate the remote key returned by
+HW is in little endian format.
+
+While handling the commit in fixes tag, the difference between
+immediate data and invalidate rkey endianness was not considered.
+
+Without changes of this patch, Kernel ULP was failing while processing
+inv_rkey.
+
+dmesg log snippet -
+nvme nvme0: Bogus remote invalidation for rkey 0x2000019Fix in this patch
+
+Do endianness conversion based on completion queue entry flag.
+Also, the HW completions are already converted to host endianness in
+bnxt_qplib_cq_process_res_rc and bnxt_qplib_cq_process_res_ud and there
+is no need to convert it again in bnxt_re_poll_cq. Modified the union to
+hold the correct data type.
+
+Fixes: 95b087f87b78 ("bnxt_re: Fix imm_data endianness")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://patch.msgid.link/1730110014-20755-1-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +++++--
+ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index f16e0b2c7895e..9ffd28ab526a8 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -3334,7 +3334,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
+       wc->byte_len = orig_cqe->length;
+       wc->qp = &gsi_qp->ib_qp;
+-      wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata));
++      wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata);
+       wc->src_qp = orig_cqe->src_qp;
+       memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
+       if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
+@@ -3474,7 +3474,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
+                               continue;
+                       }
+                       wc->qp = &qp->ib_qp;
+-                      wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata));
++                      if (cqe->flags & CQ_RES_RC_FLAGS_IMM)
++                              wc->ex.imm_data = cpu_to_be32(cqe->immdata);
++                      else
++                              wc->ex.invalidate_rkey = cqe->invrkey;
+                       wc->src_qp = cqe->src_qp;
+                       memcpy(wc->smac, cqe->smac, ETH_ALEN);
+                       wc->port_num = 1;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+index 01cb48caa9dbd..6803162261a7d 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+@@ -372,7 +372,7 @@ struct bnxt_qplib_cqe {
+       u16                             cfa_meta;
+       u64                             wr_id;
+       union {
+-              __le32                  immdata;
++              u32                     immdata;
+               u32                     invrkey;
+       };
+       u64                             qp_handle;
+-- 
+2.43.0
+
diff --git a/queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch b/queue-5.10/rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch
new file mode 100644 (file)
index 0000000..66821ea
--- /dev/null
@@ -0,0 +1,57 @@
+From 203d4f3869d2ef1d2a91d03e150e909db2cdd82d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2024 15:57:43 +0800
+Subject: RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 6b526d17eed850352d880b93b9bf20b93006bd92 ]
+
+ib_map_mr_sg() allows ULPs to specify NULL as the sg_offset argument.
+The driver needs to check whether it is a NULL pointer before
+dereferencing it.
+
+Fixes: d387d4b54eb8 ("RDMA/hns: Fix missing pagesize and alignment check in FRMR")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20241108075743.2652258-3-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_mr.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 5f038bd5571d1..b062301258683 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -478,15 +478,16 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr)
+ }
+ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
+-                     unsigned int *sg_offset)
++                     unsigned int *sg_offset_p)
+ {
++      unsigned int sg_offset = sg_offset_p ? *sg_offset_p : 0;
+       struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
+       struct ib_device *ibdev = &hr_dev->ib_dev;
+       struct hns_roce_mr *mr = to_hr_mr(ibmr);
+       struct hns_roce_mtr *mtr = &mr->pbl_mtr;
+       int ret, sg_num = 0;
+-      if (!IS_ALIGNED(*sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
++      if (!IS_ALIGNED(sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
+           ibmr->page_size < HNS_HW_PAGE_SIZE ||
+           ibmr->page_size > HNS_HW_MAX_PAGE_SIZE)
+               return sg_num;
+@@ -497,7 +498,7 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
+       if (!mr->page_list)
+               return sg_num;
+-      sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, hns_roce_set_page);
++      sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page);
+       if (sg_num < 1) {
+               ibdev_err(ibdev, "failed to store sg pages %u %u, cnt = %d.\n",
+                         mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num);
+-- 
+2.43.0
+
diff --git a/queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch b/queue-5.10/regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch
new file mode 100644 (file)
index 0000000..a55cda6
--- /dev/null
@@ -0,0 +1,85 @@
+From ed383c6fb72817f8008644f6994f07c119b79632 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Nov 2024 18:55:53 +0200
+Subject: regmap: irq: Set lockdep class for hierarchical IRQ domains
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 953e549471cabc9d4980f1da2e9fa79f4c23da06 ]
+
+Lockdep gives a false positive splat as it can't distinguish the lock
+which is taken by different IRQ descriptors from different IRQ chips
+that are organized in a way of a hierarchy:
+
+   ======================================================
+   WARNING: possible circular locking dependency detected
+   6.12.0-rc5-next-20241101-00148-g9fabf8160b53 #562 Tainted: G        W
+   ------------------------------------------------------
+   modprobe/141 is trying to acquire lock:
+   ffff899446947868 (intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock){+.+.}-{4:4}, at: regmap_update_bits_base+0x33/0x90
+
+   but task is already holding lock:
+   ffff899446947c68 (&d->lock){+.+.}-{4:4}, at: __setup_irq+0x682/0x790
+
+   which lock already depends on the new lock.
+
+   -> #3 (&d->lock){+.+.}-{4:4}:
+   -> #2 (&desc->request_mutex){+.+.}-{4:4}:
+   -> #1 (ipclock){+.+.}-{4:4}:
+   -> #0 (intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock){+.+.}-{4:4}:
+
+   Chain exists of:
+     intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock --> &desc->request_mutex --> &d->lock
+
+    Possible unsafe locking scenario:
+
+          CPU0                    CPU1
+          ----                    ----
+     lock(&d->lock);
+                                  lock(&desc->request_mutex);
+                                  lock(&d->lock);
+     lock(intel_soc_pmic_bxtwc:502:(&bxtwc_regmap_config)->lock);
+
+    *** DEADLOCK ***
+
+   3 locks held by modprobe/141:
+    #0: ffff8994419368f8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xf6/0x250
+    #1: ffff89944690b250 (&desc->request_mutex){+.+.}-{4:4}, at: __setup_irq+0x1a2/0x790
+    #2: ffff899446947c68 (&d->lock){+.+.}-{4:4}, at: __setup_irq+0x682/0x790
+
+Set a lockdep class when we map the IRQ so that it doesn't warn about
+a lockdep bug that doesn't exist.
+
+Fixes: 4af8be67fd99 ("regmap: Convert regmap_irq to use irq_domain")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20241101165553.4055617-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regmap-irq.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
+index 4466f8bdab2e1..301e849a87d1c 100644
+--- a/drivers/base/regmap/regmap-irq.c
++++ b/drivers/base/regmap/regmap-irq.c
+@@ -539,12 +539,16 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
+               return IRQ_NONE;
+ }
++static struct lock_class_key regmap_irq_lock_class;
++static struct lock_class_key regmap_irq_request_class;
++
+ static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
+                         irq_hw_number_t hw)
+ {
+       struct regmap_irq_chip_data *data = h->host_data;
+       irq_set_chip_data(virq, data);
++      irq_set_lockdep_class(virq, &regmap_irq_lock_class, &regmap_irq_request_class);
+       irq_set_chip(virq, &data->irq_chip);
+       irq_set_nested_thread(virq, 1);
+       irq_set_parent(virq, data->irq);
+-- 
+2.43.0
+
diff --git a/queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch b/queue-5.10/remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch
new file mode 100644 (file)
index 0000000..5682c12
--- /dev/null
@@ -0,0 +1,42 @@
+From dd3b654b2c9be052948b05bb386dc3b092687260 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 13:00:20 +0530
+Subject: remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region
+
+From: Sibi Sankar <quic_sibis@quicinc.com>
+
+[ Upstream commit 7b22b7719fc17d5979a991c918c868ab041be5c8 ]
+
+Any write access to the IMEM region when the Q6 is setting up XPU
+protection on it will result in a XPU violation. Fix this by ensuring
+IMEM writes related to the MBA post-mortem logs happen before the Q6
+is brought out of reset.
+
+Fixes: 318130cc9362 ("remoteproc: qcom_q6v5_mss: Add MBA log extraction support")
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20240819073020.3291287-1-quic_sibis@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_mss.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
+index 3d975ecd93360..876223e6c9291 100644
+--- a/drivers/remoteproc/qcom_q6v5_mss.c
++++ b/drivers/remoteproc/qcom_q6v5_mss.c
+@@ -980,6 +980,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
+               goto disable_active_clks;
+       }
++      if (qproc->has_mba_logs)
++              qcom_pil_info_store("mba", qproc->mba_phys, MBA_LOG_SIZE);
++
+       writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
+       if (qproc->dp_size) {
+               writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG);
+-- 
+2.43.0
+
diff --git a/queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch b/queue-5.10/revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch
new file mode 100644 (file)
index 0000000..c7601fb
--- /dev/null
@@ -0,0 +1,43 @@
+From 8d599b0914d975962d1794015911f4c5c68f64e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Oct 2024 08:15:19 +0000
+Subject: Revert "cgroup: Fix memory leak caused by missing cgroup_bpf_offline"
+
+From: Chen Ridong <chenridong@huawei.com>
+
+[ Upstream commit feb301c60970bd2a1310a53ce2d6e4375397a51b ]
+
+This reverts commit 04f8ef5643bcd8bcde25dfdebef998aea480b2ba.
+
+Only cgroup v2 can be attached by cgroup by BPF programs. Revert this
+commit and cgroup_bpf_inherit and cgroup_bpf_offline won't be called in
+cgroup v1. The memory leak issue will be fixed with next patch.
+
+Fixes: 04f8ef5643bc ("cgroup: Fix memory leak caused by missing cgroup_bpf_offline")
+Link: https://lore.kernel.org/cgroups/aka2hk5jsel5zomucpwlxsej6iwnfw4qu5jkrmjhyfhesjlfdw@46zxhg5bdnr7/
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cgroup.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index e0fd62d56110a..c5e51bad62473 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -2187,10 +2187,8 @@ static void cgroup_kill_sb(struct super_block *sb)
+        * And don't kill the default root.
+        */
+       if (list_empty(&root->cgrp.self.children) && root != &cgrp_dfl_root &&
+-          !percpu_ref_is_dying(&root->cgrp.self.refcnt)) {
+-              cgroup_bpf_offline(&root->cgrp);
++          !percpu_ref_is_dying(&root->cgrp.self.refcnt))
+               percpu_ref_kill(&root->cgrp.self.refcnt);
+-      }
+       cgroup_put(&root->cgrp);
+       kernfs_kill_sb(sb);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch b/queue-5.10/rpmsg-glink-add-tx_data_cont-command-while-sending.patch
new file mode 100644 (file)
index 0000000..061eed7
--- /dev/null
@@ -0,0 +1,92 @@
+From 9f1aebe7e7e18f52bdaee9efb5764c26a482f784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jul 2020 10:48:13 +0530
+Subject: rpmsg: glink: Add TX_DATA_CONT command while sending
+
+From: Arun Kumar Neelakantam <aneela@codeaurora.org>
+
+[ Upstream commit 8956927faed366b60b0355f4a4317a10e281ced7 ]
+
+With current design the transport can send packets of size upto
+FIFO_SIZE which is 16k and return failure for all packets above 16k.
+
+Add TX_DATA_CONT command to send packets greater than 16k by splitting
+into 8K chunks.
+
+Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
+Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1596086296-28529-4-git-send-email-deesin@codeaurora.org
+Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 38 +++++++++++++++++++++++++++----
+ 1 file changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 28b6ae0e1a2fd..a8486264f11f3 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -1276,6 +1276,8 @@ static int __qcom_glink_send(struct glink_channel *channel,
+       } __packed req;
+       int ret;
+       unsigned long flags;
++      int chunk_size = len;
++      int left_size = 0;
+       if (!glink->intentless) {
+               while (!intent) {
+@@ -1309,18 +1311,46 @@ static int __qcom_glink_send(struct glink_channel *channel,
+               iid = intent->id;
+       }
++      if (wait && chunk_size > SZ_8K) {
++              chunk_size = SZ_8K;
++              left_size = len - chunk_size;
++      }
+       req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA);
+       req.msg.param1 = cpu_to_le16(channel->lcid);
+       req.msg.param2 = cpu_to_le32(iid);
+-      req.chunk_size = cpu_to_le32(len);
+-      req.left_size = cpu_to_le32(0);
++      req.chunk_size = cpu_to_le32(chunk_size);
++      req.left_size = cpu_to_le32(left_size);
+-      ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait);
++      ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
+       /* Mark intent available if we failed */
+-      if (ret && intent)
++      if (ret && intent) {
+               intent->in_use = false;
++              return ret;
++      }
++      while (left_size > 0) {
++              data = (void *)((char *)data + chunk_size);
++              chunk_size = left_size;
++              if (chunk_size > SZ_8K)
++                      chunk_size = SZ_8K;
++              left_size -= chunk_size;
++
++              req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT);
++              req.msg.param1 = cpu_to_le16(channel->lcid);
++              req.msg.param2 = cpu_to_le32(iid);
++              req.chunk_size = cpu_to_le32(chunk_size);
++              req.left_size = cpu_to_le32(left_size);
++
++              ret = qcom_glink_tx(glink, &req, sizeof(req), data,
++                                  chunk_size, wait);
++
++              /* Mark intent available if we failed */
++              if (ret && intent) {
++                      intent->in_use = false;
++                      break;
++              }
++      }
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch b/queue-5.10/rpmsg-glink-fix-glink-command-prefix.patch
new file mode 100644 (file)
index 0000000..5210a37
--- /dev/null
@@ -0,0 +1,284 @@
+From 81ac020c60472c1743f3f035a248b5442023961b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 14:59:33 -0800
+Subject: rpmsg: glink: Fix GLINK command prefix
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit 4e816d0318fdfe8932da80dbf04ba318b13e4b3a ]
+
+The upstream GLINK driver was first introduced to communicate with the
+RPM on MSM8996, presumably as an artifact from that era the command
+defines was prefixed RPM_CMD, while they actually are GLINK_CMDs.
+
+Let's rename these, to keep things tidy. No functional change.
+
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Reviewed-by: Chris Lew <quic_clew@quicinc.com>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230214225933.2025595-1-quic_bjorande@quicinc.com
+Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 98 +++++++++++++++----------------
+ 1 file changed, 49 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 8128da8646db1..831a5d1cd4806 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -191,20 +191,20 @@ struct glink_channel {
+ static const struct rpmsg_endpoint_ops glink_endpoint_ops;
+-#define RPM_CMD_VERSION                       0
+-#define RPM_CMD_VERSION_ACK           1
+-#define RPM_CMD_OPEN                  2
+-#define RPM_CMD_CLOSE                 3
+-#define RPM_CMD_OPEN_ACK              4
+-#define RPM_CMD_INTENT                        5
+-#define RPM_CMD_RX_DONE                       6
+-#define RPM_CMD_RX_INTENT_REQ         7
+-#define RPM_CMD_RX_INTENT_REQ_ACK     8
+-#define RPM_CMD_TX_DATA                       9
+-#define RPM_CMD_CLOSE_ACK             11
+-#define RPM_CMD_TX_DATA_CONT          12
+-#define RPM_CMD_READ_NOTIF            13
+-#define RPM_CMD_RX_DONE_W_REUSE               14
++#define GLINK_CMD_VERSION             0
++#define GLINK_CMD_VERSION_ACK         1
++#define GLINK_CMD_OPEN                        2
++#define GLINK_CMD_CLOSE                       3
++#define GLINK_CMD_OPEN_ACK            4
++#define GLINK_CMD_INTENT              5
++#define GLINK_CMD_RX_DONE             6
++#define GLINK_CMD_RX_INTENT_REQ               7
++#define GLINK_CMD_RX_INTENT_REQ_ACK   8
++#define GLINK_CMD_TX_DATA             9
++#define GLINK_CMD_CLOSE_ACK           11
++#define GLINK_CMD_TX_DATA_CONT                12
++#define GLINK_CMD_READ_NOTIF          13
++#define GLINK_CMD_RX_DONE_W_REUSE     14
+ #define GLINK_FEATURE_INTENTLESS      BIT(1)
+@@ -313,7 +313,7 @@ static void qcom_glink_send_read_notify(struct qcom_glink *glink)
+ {
+       struct glink_msg msg;
+-      msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF);
++      msg.cmd = cpu_to_le16(GLINK_CMD_READ_NOTIF);
+       msg.param1 = 0;
+       msg.param2 = 0;
+@@ -375,7 +375,7 @@ static int qcom_glink_send_version(struct qcom_glink *glink)
+ {
+       struct glink_msg msg;
+-      msg.cmd = cpu_to_le16(RPM_CMD_VERSION);
++      msg.cmd = cpu_to_le16(GLINK_CMD_VERSION);
+       msg.param1 = cpu_to_le16(GLINK_VERSION_1);
+       msg.param2 = cpu_to_le32(glink->features);
+@@ -386,7 +386,7 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink)
+ {
+       struct glink_msg msg;
+-      msg.cmd = cpu_to_le16(RPM_CMD_VERSION_ACK);
++      msg.cmd = cpu_to_le16(GLINK_CMD_VERSION_ACK);
+       msg.param1 = cpu_to_le16(GLINK_VERSION_1);
+       msg.param2 = cpu_to_le32(glink->features);
+@@ -398,7 +398,7 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink,
+ {
+       struct glink_msg msg;
+-      msg.cmd = cpu_to_le16(RPM_CMD_OPEN_ACK);
++      msg.cmd = cpu_to_le16(GLINK_CMD_OPEN_ACK);
+       msg.param1 = cpu_to_le16(channel->rcid);
+       msg.param2 = cpu_to_le32(0);
+@@ -424,11 +424,11 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
+ }
+ /**
+- * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote
++ * qcom_glink_send_open_req() - send a GLINK_CMD_OPEN request to the remote
+  * @glink: Ptr to the glink edge
+  * @channel: Ptr to the channel that the open req is sent
+  *
+- * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote.
++ * Allocates a local channel id and sends a GLINK_CMD_OPEN message to the remote.
+  * Will return with refcount held, regardless of outcome.
+  *
+  * Returns 0 on success, negative errno otherwise.
+@@ -457,7 +457,7 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink,
+       channel->lcid = ret;
+-      req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN);
++      req.msg.cmd = cpu_to_le16(GLINK_CMD_OPEN);
+       req.msg.param1 = cpu_to_le16(channel->lcid);
+       req.msg.param2 = cpu_to_le32(name_len);
+       strcpy(req.name, channel->name);
+@@ -482,7 +482,7 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink,
+ {
+       struct glink_msg req;
+-      req.cmd = cpu_to_le16(RPM_CMD_CLOSE);
++      req.cmd = cpu_to_le16(GLINK_CMD_CLOSE);
+       req.param1 = cpu_to_le16(channel->lcid);
+       req.param2 = 0;
+@@ -494,7 +494,7 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink,
+ {
+       struct glink_msg req;
+-      req.cmd = cpu_to_le16(RPM_CMD_CLOSE_ACK);
++      req.cmd = cpu_to_le16(GLINK_CMD_CLOSE_ACK);
+       req.param1 = cpu_to_le16(rcid);
+       req.param2 = 0;
+@@ -525,7 +525,7 @@ static void qcom_glink_rx_done_work(struct work_struct *work)
+               iid = intent->id;
+               reuse = intent->reuse;
+-              cmd.id = reuse ? RPM_CMD_RX_DONE_W_REUSE : RPM_CMD_RX_DONE;
++              cmd.id = reuse ? GLINK_CMD_RX_DONE_W_REUSE : GLINK_CMD_RX_DONE;
+               cmd.lcid = cid;
+               cmd.liid = iid;
+@@ -637,7 +637,7 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink,
+ {
+       struct glink_msg msg;
+-      msg.cmd = cpu_to_le16(RPM_CMD_RX_INTENT_REQ_ACK);
++      msg.cmd = cpu_to_le16(GLINK_CMD_RX_INTENT_REQ_ACK);
+       msg.param1 = cpu_to_le16(channel->lcid);
+       msg.param2 = cpu_to_le32(granted);
+@@ -668,7 +668,7 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink,
+       } __packed;
+       struct command cmd;
+-      cmd.id = cpu_to_le16(RPM_CMD_INTENT);
++      cmd.id = cpu_to_le16(GLINK_CMD_INTENT);
+       cmd.lcid = cpu_to_le16(channel->lcid);
+       cmd.count = cpu_to_le32(1);
+       cmd.size = cpu_to_le32(intent->size);
+@@ -1033,42 +1033,42 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
+               param2 = le32_to_cpu(msg.param2);
+               switch (cmd) {
+-              case RPM_CMD_VERSION:
+-              case RPM_CMD_VERSION_ACK:
+-              case RPM_CMD_CLOSE:
+-              case RPM_CMD_CLOSE_ACK:
+-              case RPM_CMD_RX_INTENT_REQ:
++              case GLINK_CMD_VERSION:
++              case GLINK_CMD_VERSION_ACK:
++              case GLINK_CMD_CLOSE:
++              case GLINK_CMD_CLOSE_ACK:
++              case GLINK_CMD_RX_INTENT_REQ:
+                       ret = qcom_glink_rx_defer(glink, 0);
+                       break;
+-              case RPM_CMD_OPEN_ACK:
++              case GLINK_CMD_OPEN_ACK:
+                       ret = qcom_glink_rx_open_ack(glink, param1);
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       break;
+-              case RPM_CMD_OPEN:
++              case GLINK_CMD_OPEN:
+                       ret = qcom_glink_rx_defer(glink, param2);
+                       break;
+-              case RPM_CMD_TX_DATA:
+-              case RPM_CMD_TX_DATA_CONT:
++              case GLINK_CMD_TX_DATA:
++              case GLINK_CMD_TX_DATA_CONT:
+                       ret = qcom_glink_rx_data(glink, avail);
+                       break;
+-              case RPM_CMD_READ_NOTIF:
++              case GLINK_CMD_READ_NOTIF:
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       mbox_send_message(glink->mbox_chan, NULL);
+                       mbox_client_txdone(glink->mbox_chan, 0);
+                       break;
+-              case RPM_CMD_INTENT:
++              case GLINK_CMD_INTENT:
+                       qcom_glink_handle_intent(glink, param1, param2, avail);
+                       break;
+-              case RPM_CMD_RX_DONE:
++              case GLINK_CMD_RX_DONE:
+                       qcom_glink_handle_rx_done(glink, param1, param2, false);
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       break;
+-              case RPM_CMD_RX_DONE_W_REUSE:
++              case GLINK_CMD_RX_DONE_W_REUSE:
+                       qcom_glink_handle_rx_done(glink, param1, param2, true);
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       break;
+-              case RPM_CMD_RX_INTENT_REQ_ACK:
++              case GLINK_CMD_RX_INTENT_REQ_ACK:
+                       qcom_glink_handle_intent_req_ack(glink, param1, param2);
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       break;
+@@ -1271,7 +1271,7 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
+       reinit_completion(&channel->intent_req_comp);
+-      cmd.id = RPM_CMD_RX_INTENT_REQ;
++      cmd.id = GLINK_CMD_RX_INTENT_REQ;
+       cmd.cid = channel->lcid;
+       cmd.size = size;
+@@ -1345,7 +1345,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
+               chunk_size = SZ_8K;
+               left_size = len - chunk_size;
+       }
+-      req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA);
++      req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA);
+       req.msg.param1 = cpu_to_le16(channel->lcid);
+       req.msg.param2 = cpu_to_le32(iid);
+       req.chunk_size = cpu_to_le32(chunk_size);
+@@ -1366,7 +1366,7 @@ static int __qcom_glink_send(struct glink_channel *channel,
+                       chunk_size = SZ_8K;
+               left_size -= chunk_size;
+-              req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT);
++              req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA_CONT);
+               req.msg.param1 = cpu_to_le16(channel->lcid);
+               req.msg.param2 = cpu_to_le32(iid);
+               req.chunk_size = cpu_to_le32(chunk_size);
+@@ -1605,22 +1605,22 @@ static void qcom_glink_work(struct work_struct *work)
+               param2 = le32_to_cpu(msg->param2);
+               switch (cmd) {
+-              case RPM_CMD_VERSION:
++              case GLINK_CMD_VERSION:
+                       qcom_glink_receive_version(glink, param1, param2);
+                       break;
+-              case RPM_CMD_VERSION_ACK:
++              case GLINK_CMD_VERSION_ACK:
+                       qcom_glink_receive_version_ack(glink, param1, param2);
+                       break;
+-              case RPM_CMD_OPEN:
++              case GLINK_CMD_OPEN:
+                       qcom_glink_rx_open(glink, param1, msg->data);
+                       break;
+-              case RPM_CMD_CLOSE:
++              case GLINK_CMD_CLOSE:
+                       qcom_glink_rx_close(glink, param1);
+                       break;
+-              case RPM_CMD_CLOSE_ACK:
++              case GLINK_CMD_CLOSE_ACK:
+                       qcom_glink_rx_close_ack(glink, param1);
+                       break;
+-              case RPM_CMD_RX_INTENT_REQ:
++              case GLINK_CMD_RX_INTENT_REQ:
+                       qcom_glink_handle_intent_req(glink, param1, param2);
+                       break;
+               default:
+-- 
+2.43.0
+
diff --git a/queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch b/queue-5.10/rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch
new file mode 100644 (file)
index 0000000..9b31a9d
--- /dev/null
@@ -0,0 +1,123 @@
+From 24d629a6756e527a18f1f3dbe0d6063222253d15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jul 2020 10:48:16 +0530
+Subject: rpmsg: glink: Send READ_NOTIFY command in FIFO full case
+
+From: Arun Kumar Neelakantam <aneela@codeaurora.org>
+
+[ Upstream commit b16a37e1846c9573a847a56fa2f31ba833dae45a ]
+
+The current design sleeps unconditionally in TX FIFO full case and
+wakeup only after sleep timer expires which adds random delays in
+clients TX path.
+
+Avoid sleep and use READ_NOTIFY command so that writer can be woken up
+when remote notifies about read completion by sending IRQ.
+
+Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
+Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1596086296-28529-7-git-send-email-deesin@codeaurora.org
+Stable-dep-of: 06c59d97f63c ("rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 36 ++++++++++++++++++++++++++++++-
+ 1 file changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index a8486264f11f3..8128da8646db1 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -92,6 +92,8 @@ struct glink_core_rx_intent {
+  * @rcids:    idr of all channels with a known remote channel id
+  * @features: remote features
+  * @intentless:       flag to indicate that there is no intent
++ * @tx_avail_notify: Waitqueue for pending tx tasks
++ * @sent_read_notify: flag to check cmd sent or not
+  */
+ struct qcom_glink {
+       struct device *dev;
+@@ -118,6 +120,8 @@ struct qcom_glink {
+       unsigned long features;
+       bool intentless;
++      wait_queue_head_t tx_avail_notify;
++      bool sent_read_notify;
+ };
+ enum {
+@@ -305,6 +309,20 @@ static void qcom_glink_tx_write(struct qcom_glink *glink,
+       glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen);
+ }
++static void qcom_glink_send_read_notify(struct qcom_glink *glink)
++{
++      struct glink_msg msg;
++
++      msg.cmd = cpu_to_le16(RPM_CMD_READ_NOTIF);
++      msg.param1 = 0;
++      msg.param2 = 0;
++
++      qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0);
++
++      mbox_send_message(glink->mbox_chan, NULL);
++      mbox_client_txdone(glink->mbox_chan, 0);
++}
++
+ static int qcom_glink_tx(struct qcom_glink *glink,
+                        const void *hdr, size_t hlen,
+                        const void *data, size_t dlen, bool wait)
+@@ -325,12 +343,21 @@ static int qcom_glink_tx(struct qcom_glink *glink,
+                       goto out;
+               }
++              if (!glink->sent_read_notify) {
++                      glink->sent_read_notify = true;
++                      qcom_glink_send_read_notify(glink);
++              }
++
+               /* Wait without holding the tx_lock */
+               spin_unlock_irqrestore(&glink->tx_lock, flags);
+-              usleep_range(10000, 15000);
++              wait_event_timeout(glink->tx_avail_notify,
++                                 qcom_glink_tx_avail(glink) >= tlen, 10 * HZ);
+               spin_lock_irqsave(&glink->tx_lock, flags);
++
++              if (qcom_glink_tx_avail(glink) >= tlen)
++                      glink->sent_read_notify = false;
+       }
+       qcom_glink_tx_write(glink, hdr, hlen, data, dlen);
+@@ -991,6 +1018,9 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
+       unsigned int cmd;
+       int ret = 0;
++      /* To wakeup any blocking writers */
++      wake_up_all(&glink->tx_avail_notify);
++
+       for (;;) {
+               avail = qcom_glink_rx_avail(glink);
+               if (avail < sizeof(msg))
+@@ -1530,6 +1560,9 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid)
+       struct glink_channel *channel;
+       unsigned long flags;
++      /* To wakeup any blocking writers */
++      wake_up_all(&glink->tx_avail_notify);
++
+       spin_lock_irqsave(&glink->idr_lock, flags);
+       channel = idr_find(&glink->lcids, lcid);
+       if (WARN(!channel, "close ack on unknown channel\n")) {
+@@ -1691,6 +1724,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev,
+       spin_lock_init(&glink->rx_lock);
+       INIT_LIST_HEAD(&glink->rx_queue);
+       INIT_WORK(&glink->rx_work, qcom_glink_work);
++      init_waitqueue_head(&glink->tx_avail_notify);
+       spin_lock_init(&glink->idr_lock);
+       idr_init(&glink->lcids);
+-- 
+2.43.0
+
diff --git a/queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch b/queue-5.10/rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch
new file mode 100644 (file)
index 0000000..694be24
--- /dev/null
@@ -0,0 +1,44 @@
+From 77fcb38297a860a98650e5fd464c3fc46748a515 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 19:59:35 -0400
+Subject: rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name
+ length
+
+From: Jonathan Marek <jonathan@marek.ca>
+
+[ Upstream commit 06c59d97f63c1b8af521fa5aef8a716fb988b285 ]
+
+The name len field of the CMD_OPEN packet is only 16-bits and the upper
+16-bits of "param2" are a different "prio" field, which can be nonzero in
+certain situations, and CMD_OPEN packets can be unexpectedly dropped
+because of this.
+
+Fix this by masking out the upper 16 bits of param2.
+
+Fixes: b4f8e52b89f6 ("rpmsg: Introduce Qualcomm RPM glink driver")
+Signed-off-by: Jonathan Marek <jonathan@marek.ca>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20241007235935.6216-1-jonathan@marek.ca
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_glink_native.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
+index 831a5d1cd4806..82670cb063f5a 100644
+--- a/drivers/rpmsg/qcom_glink_native.c
++++ b/drivers/rpmsg/qcom_glink_native.c
+@@ -1045,7 +1045,8 @@ static irqreturn_t qcom_glink_native_intr(int irq, void *data)
+                       qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8));
+                       break;
+               case GLINK_CMD_OPEN:
+-                      ret = qcom_glink_rx_defer(glink, param2);
++                      /* upper 16 bits of param2 are the "prio" field */
++                      ret = qcom_glink_rx_defer(glink, param2 & 0xffff);
+                       break;
+               case GLINK_CMD_TX_DATA:
+               case GLINK_CMD_TX_DATA_CONT:
+-- 
+2.43.0
+
diff --git a/queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch b/queue-5.10/s390-syscalls-avoid-creation-of-arch-arch-directory.patch
new file mode 100644 (file)
index 0000000..9524cf3
--- /dev/null
@@ -0,0 +1,54 @@
+From 318d69eed41a142e33d5d095b40bead165c79af4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Nov 2024 22:45:52 +0900
+Subject: s390/syscalls: Avoid creation of arch/arch/ directory
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 0708967e2d56e370231fd07defa0d69f9ad125e8 ]
+
+Building the kernel with ARCH=s390 creates a weird arch/arch/ directory.
+
+  $ find arch/arch
+  arch/arch
+  arch/arch/s390
+  arch/arch/s390/include
+  arch/arch/s390/include/generated
+  arch/arch/s390/include/generated/asm
+  arch/arch/s390/include/generated/uapi
+  arch/arch/s390/include/generated/uapi/asm
+
+The root cause is 'targets' in arch/s390/kernel/syscalls/Makefile,
+where the relative path is incorrect.
+
+Strictly speaking, 'targets' was not necessary in the first place
+because this Makefile uses 'filechk' instead of 'if_changed'.
+
+However, this commit keeps it, as it will be useful when converting
+'filechk' to 'if_changed' later.
+
+Fixes: 5c75824d915e ("s390/syscalls: add Makefile to generate system call header files")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Link: https://lore.kernel.org/r/20241111134603.2063226-1-masahiroy@kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/syscalls/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/syscalls/Makefile b/arch/s390/kernel/syscalls/Makefile
+index b98f25029b8e6..7b77ed779c7b2 100644
+--- a/arch/s390/kernel/syscalls/Makefile
++++ b/arch/s390/kernel/syscalls/Makefile
+@@ -12,7 +12,7 @@ kapi-hdrs-y := $(kapi)/unistd_nr.h
+ uapi-hdrs-y := $(uapi)/unistd_32.h
+ uapi-hdrs-y += $(uapi)/unistd_64.h
+-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
++targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
+ PHONY += kapi uapi
+-- 
+2.43.0
+
diff --git a/queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch b/queue-5.10/scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch
new file mode 100644 (file)
index 0000000..1882281
--- /dev/null
@@ -0,0 +1,109 @@
+From 99b7db587de1f394405a62ba5d4a2dcb6eb64c1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 09:18:09 +0800
+Subject: scsi: bfa: Fix use-after-free in bfad_im_module_exit()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit 178b8f38932d635e90f5f0e9af1986c6f4a89271 ]
+
+BUG: KASAN: slab-use-after-free in __lock_acquire+0x2aca/0x3a20
+Read of size 8 at addr ffff8881082d80c8 by task modprobe/25303
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x95/0xe0
+ print_report+0xcb/0x620
+ kasan_report+0xbd/0xf0
+ __lock_acquire+0x2aca/0x3a20
+ lock_acquire+0x19b/0x520
+ _raw_spin_lock+0x2b/0x40
+ attribute_container_unregister+0x30/0x160
+ fc_release_transport+0x19/0x90 [scsi_transport_fc]
+ bfad_im_module_exit+0x23/0x60 [bfa]
+ bfad_init+0xdb/0xff0 [bfa]
+ do_one_initcall+0xdc/0x550
+ do_init_module+0x22d/0x6b0
+ load_module+0x4e96/0x5ff0
+ init_module_from_file+0xcd/0x130
+ idempotent_init_module+0x330/0x620
+ __x64_sys_finit_module+0xb3/0x110
+ do_syscall_64+0xc1/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+
+Allocated by task 25303:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ __kasan_kmalloc+0x7f/0x90
+ fc_attach_transport+0x4f/0x4740 [scsi_transport_fc]
+ bfad_im_module_init+0x17/0x80 [bfa]
+ bfad_init+0x23/0xff0 [bfa]
+ do_one_initcall+0xdc/0x550
+ do_init_module+0x22d/0x6b0
+ load_module+0x4e96/0x5ff0
+ init_module_from_file+0xcd/0x130
+ idempotent_init_module+0x330/0x620
+ __x64_sys_finit_module+0xb3/0x110
+ do_syscall_64+0xc1/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Freed by task 25303:
+ kasan_save_stack+0x24/0x50
+ kasan_save_track+0x14/0x30
+ kasan_save_free_info+0x3b/0x60
+ __kasan_slab_free+0x38/0x50
+ kfree+0x212/0x480
+ bfad_im_module_init+0x7e/0x80 [bfa]
+ bfad_init+0x23/0xff0 [bfa]
+ do_one_initcall+0xdc/0x550
+ do_init_module+0x22d/0x6b0
+ load_module+0x4e96/0x5ff0
+ init_module_from_file+0xcd/0x130
+ idempotent_init_module+0x330/0x620
+ __x64_sys_finit_module+0xb3/0x110
+ do_syscall_64+0xc1/0x1d0
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Above issue happens as follows:
+
+bfad_init
+  error = bfad_im_module_init()
+    fc_release_transport(bfad_im_scsi_transport_template);
+  if (error)
+    goto ext;
+
+ext:
+  bfad_im_module_exit();
+    fc_release_transport(bfad_im_scsi_transport_template);
+    --> Trigger double release
+
+Don't call bfad_im_module_exit() if bfad_im_module_init() failed.
+
+Fixes: 7725ccfda597 ("[SCSI] bfa: Brocade BFA FC SCSI driver")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Link: https://lore.kernel.org/r/20241023011809.63466-1-yebin@huaweicloud.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/bfa/bfad.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
+index 440ef32be048f..45b5f83ad6da1 100644
+--- a/drivers/scsi/bfa/bfad.c
++++ b/drivers/scsi/bfa/bfad.c
+@@ -1705,9 +1705,8 @@ bfad_init(void)
+       error = bfad_im_module_init();
+       if (error) {
+-              error = -ENOMEM;
+               printk(KERN_WARNING "bfad_im_module_init failure\n");
+-              goto ext;
++              return -ENOMEM;
+       }
+       if (strcmp(FCPI_NAME, " fcpim") == 0)
+-- 
+2.43.0
+
diff --git a/queue-5.10/scsi-fusion-remove-unused-variable-rc.patch b/queue-5.10/scsi-fusion-remove-unused-variable-rc.patch
new file mode 100644 (file)
index 0000000..3ba07ab
--- /dev/null
@@ -0,0 +1,46 @@
+From c9661ea8708c187c0f17c8487b3b15de2c955e66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 16:44:17 +0800
+Subject: scsi: fusion: Remove unused variable 'rc'
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit bd65694223f7ad11c790ab63ad1af87a771192ee ]
+
+The return value of scsi_device_reprobe() is currently ignored in
+_scsih_reprobe_lun(). Fixing the calling code to deal with the potential
+error is non-trivial, so for now just WARN_ON().
+
+The handling of scsi_device_reprobe()'s return value refers to
+_scsih_reprobe_lun() and the following link:
+
+https://lore.kernel.org/all/094fdbf57487af4f395238c0525b2a560c8f68f0.1469766027.git.calvinowens@fb.com/
+
+Fixes: f99be43b3024 ("[SCSI] fusion: power pc and miscellaneous bug fixs")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Link: https://lore.kernel.org/r/20241024084417.154655-1-zengheng4@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/message/fusion/mptsas.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
+index 18b91ea1a353f..e56e96671da99 100644
+--- a/drivers/message/fusion/mptsas.c
++++ b/drivers/message/fusion/mptsas.c
+@@ -4205,10 +4205,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
+ static void
+ mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
+ {
+-      int rc;
+-
+       sdev->no_uld_attach = data ? 1 : 0;
+-      rc = scsi_device_reprobe(sdev);
++      WARN_ON(scsi_device_reprobe(sdev));
+ }
+ static void
+-- 
+2.43.0
+
diff --git a/queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch b/queue-5.10/scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch
new file mode 100644 (file)
index 0000000..4fce186
--- /dev/null
@@ -0,0 +1,37 @@
+From c1cc9231e3d46f9b613e3fe9d844a04f1294a377 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 20:57:10 +0800
+Subject: scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit c62c30429db3eb4ced35c7fcf6f04a61ce3a01bb ]
+
+Hook "qed_ops->common->sb_init = qed_sb_init" does not release the DMA
+memory sb_virt when it fails. Add dma_free_coherent() to free it. This
+is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
+
+Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20241026125711.484-2-thunder.leizhen@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedf/qedf_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index 2536da96130ea..912845415d9b4 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -2725,6 +2725,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf,
+           sb_id, QED_SB_TYPE_STORAGE);
+       if (ret) {
++              dma_free_coherent(&qedf->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
+               QEDF_ERR(&qedf->dbg_ctx,
+                        "Status block initialization failed (0x%x) for id = %d.\n",
+                        ret, sb_id);
+-- 
+2.43.0
+
diff --git a/queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch b/queue-5.10/scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch
new file mode 100644 (file)
index 0000000..0ed1b50
--- /dev/null
@@ -0,0 +1,37 @@
+From 51255a321ca1896be1fb078549cd9f5ea023e2cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Oct 2024 20:57:11 +0800
+Subject: scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 95bbdca4999bc59a72ebab01663d421d6ce5775d ]
+
+Hook "qedi_ops->common->sb_init = qed_sb_init" does not release the DMA
+memory sb_virt when it fails. Add dma_free_coherent() to free it. This
+is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
+
+Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20241026125711.484-3-thunder.leizhen@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qedi/qedi_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
+index 96e470746767a..3bf75d466b2c6 100644
+--- a/drivers/scsi/qedi/qedi_main.c
++++ b/drivers/scsi/qedi/qedi_main.c
+@@ -371,6 +371,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi,
+       ret = qedi_ops->common->sb_init(qedi->cdev, sb_info, sb_virt, sb_phys,
+                                      sb_id, QED_SB_TYPE_STORAGE);
+       if (ret) {
++              dma_free_coherent(&qedi->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
+               QEDI_ERR(&qedi->dbg_ctx,
+                        "Status block initialization failed for id = %d.\n",
+                         sb_id);
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch b/queue-5.10/selftests-bpf-add-one-test-for-sockmap-with-strparse.patch
new file mode 100644 (file)
index 0000000..87ca8da
--- /dev/null
@@ -0,0 +1,104 @@
+From 4736acd935c7d50ad81cbc56983935d467d52d50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Oct 2021 22:12:16 +0800
+Subject: selftests, bpf: Add one test for sockmap with strparser
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit d69672147faa2a7671c0779fa5b9ad99e4fca4e3 ]
+
+Add the test to check sockmap with strparser is working well.
+
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20211029141216.211899-3-liujian56@huawei.com
+Stable-dep-of: 523dffccbade ("selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 33 ++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 46a1ca4f699e2..89d215416a34e 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -141,6 +141,7 @@ struct sockmap_options {
+       bool sendpage;
+       bool data_test;
+       bool drop_expected;
++      bool check_recved_len;
+       int iov_count;
+       int iov_length;
+       int rate;
+@@ -564,8 +565,12 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+       int err, i, flags = MSG_NOSIGNAL;
+       bool drop = opt->drop_expected;
+       bool data = opt->data_test;
++      int iov_alloc_length = iov_length;
+-      err = msg_alloc_iov(&msg, iov_count, iov_length, data, tx);
++      if (!tx && opt->check_recved_len)
++              iov_alloc_length *= 2;
++
++      err = msg_alloc_iov(&msg, iov_count, iov_alloc_length, data, tx);
+       if (err)
+               goto out_errno;
+       if (peek_flag) {
+@@ -678,6 +683,13 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                       if (recv > 0)
+                               s->bytes_recvd += recv;
++                      if (opt->check_recved_len && s->bytes_recvd > total_bytes) {
++                              errno = EMSGSIZE;
++                              fprintf(stderr, "recv failed(), bytes_recvd:%zd, total_bytes:%f\n",
++                                              s->bytes_recvd, total_bytes);
++                              goto out_errno;
++                      }
++
+                       if (data) {
+                               int chunk_sz = opt->sendpage ?
+                                               iov_length :
+@@ -759,7 +771,8 @@ static int sendmsg_test(struct sockmap_options *opt)
+       rxpid = fork();
+       if (rxpid == 0) {
+-              iov_buf -= (txmsg_pop - txmsg_start_pop + 1);
++              if (txmsg_pop || txmsg_start_pop)
++                      iov_buf -= (txmsg_pop - txmsg_start_pop + 1);
+               if (opt->drop_expected || txmsg_ktls_skb_drop)
+                       _exit(0);
+@@ -1708,6 +1721,19 @@ static void test_txmsg_ingress_parser(int cgrp, struct sockmap_options *opt)
+       test_exec(cgrp, opt);
+ }
++static void test_txmsg_ingress_parser2(int cgrp, struct sockmap_options *opt)
++{
++      if (ktls == 1)
++              return;
++      skb_use_parser = 10;
++      opt->iov_length = 20;
++      opt->iov_count = 1;
++      opt->rate = 1;
++      opt->check_recved_len = true;
++      test_exec(cgrp, opt);
++      opt->check_recved_len = false;
++}
++
+ char *map_names[] = {
+       "sock_map",
+       "sock_map_txmsg",
+@@ -1802,7 +1828,8 @@ struct _test test[] = {
+       {"txmsg test pull-data", test_txmsg_pull},
+       {"txmsg test pop-data", test_txmsg_pop},
+       {"txmsg test push/pop data", test_txmsg_push_pop},
+-      {"txmsg text ingress parser", test_txmsg_ingress_parser},
++      {"txmsg test ingress parser", test_txmsg_ingress_parser},
++      {"txmsg test ingress parser2", test_txmsg_ingress_parser2},
+ };
+ static int check_whitelist(struct _test *t, struct sockmap_options *opt)
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch b/queue-5.10/selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch
new file mode 100644 (file)
index 0000000..bbbed5a
--- /dev/null
@@ -0,0 +1,246 @@
+From 001549ac01a272c0450ddc1dd1fcda0cc018b1ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:16 +0000
+Subject: selftests/bpf: Add push/pop checking for msg_verify_data in
+ test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 862087c3d36219ed44569666eb263efc97f00c9a ]
+
+Add push/pop checking for msg_verify_data in test_sockmap, except for
+pop/push with cork tests, in these tests the logic will be different.
+1. With corking, pop/push might not be invoked in each sendmsg, it makes
+the layout of the received data difficult
+2. It makes it hard to calculate the total_bytes in the recvmsg
+Temporarily skip the data integrity test for these cases now, added a TODO
+
+Fixes: ee9b352ce465 ("selftests/bpf: Fix msg_verify_data in test_sockmap")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-5-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 106 ++++++++++++++++++++-
+ 1 file changed, 101 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 85d6fac7124bd..5b4390d643b21 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -89,6 +89,10 @@ int ktls;
+ int peek_flag;
+ int skb_use_parser;
+ int txmsg_omit_skb_parser;
++int verify_push_start;
++int verify_push_len;
++int verify_pop_start;
++int verify_pop_len;
+ static const struct option long_options[] = {
+       {"help",        no_argument,            NULL, 'h' },
+@@ -514,12 +518,41 @@ static int msg_alloc_iov(struct msghdr *msg,
+       return -ENOMEM;
+ }
+-/* TODO: Add verification logic for push, pull and pop data */
++/* In push or pop test, we need to do some calculations for msg_verify_data */
++static void msg_verify_date_prep(void)
++{
++      int push_range_end = txmsg_start_push + txmsg_end_push - 1;
++      int pop_range_end = txmsg_start_pop + txmsg_pop - 1;
++
++      if (txmsg_end_push && txmsg_pop &&
++          txmsg_start_push <= pop_range_end && txmsg_start_pop <= push_range_end) {
++              /* The push range and the pop range overlap */
++              int overlap_len;
++
++              verify_push_start = txmsg_start_push;
++              verify_pop_start = txmsg_start_pop;
++              if (txmsg_start_push < txmsg_start_pop)
++                      overlap_len = min(push_range_end - txmsg_start_pop + 1, txmsg_pop);
++              else
++                      overlap_len = min(pop_range_end - txmsg_start_push + 1, txmsg_end_push);
++              verify_push_len = max(txmsg_end_push - overlap_len, 0);
++              verify_pop_len = max(txmsg_pop - overlap_len, 0);
++      } else {
++              /* Otherwise */
++              verify_push_start = txmsg_start_push;
++              verify_pop_start = txmsg_start_pop;
++              verify_push_len = txmsg_end_push;
++              verify_pop_len = txmsg_pop;
++      }
++}
++
+ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
+-                               unsigned char *k_p, int *bytes_cnt_p)
++                         unsigned char *k_p, int *bytes_cnt_p,
++                         int *check_cnt_p, int *push_p)
+ {
+-      int i, j, bytes_cnt = *bytes_cnt_p;
++      int bytes_cnt = *bytes_cnt_p, check_cnt = *check_cnt_p, push = *push_p;
+       unsigned char k = *k_p;
++      int i, j;
+       for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) {
+               unsigned char *d = msg->msg_iov[i].iov_base;
+@@ -538,6 +571,37 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
+               }
+               for (; j < msg->msg_iov[i].iov_len && size; j++) {
++                      if (push > 0 &&
++                          check_cnt == verify_push_start + verify_push_len - push) {
++                              int skipped;
++revisit_push:
++                              skipped = push;
++                              if (j + push >= msg->msg_iov[i].iov_len)
++                                      skipped = msg->msg_iov[i].iov_len - j;
++                              push -= skipped;
++                              size -= skipped;
++                              j += skipped - 1;
++                              check_cnt += skipped;
++                              continue;
++                      }
++
++                      if (verify_pop_len > 0 && check_cnt == verify_pop_start) {
++                              bytes_cnt += verify_pop_len;
++                              check_cnt += verify_pop_len;
++                              k += verify_pop_len;
++
++                              if (bytes_cnt == chunk_sz) {
++                                      k = 0;
++                                      bytes_cnt = 0;
++                                      check_cnt = 0;
++                                      push = verify_push_len;
++                              }
++
++                              if (push > 0 &&
++                                  check_cnt == verify_push_start + verify_push_len - push)
++                                      goto revisit_push;
++                      }
++
+                       if (d[j] != k++) {
+                               fprintf(stderr,
+                                       "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
+@@ -545,15 +609,20 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
+                               return -EDATAINTEGRITY;
+                       }
+                       bytes_cnt++;
++                      check_cnt++;
+                       if (bytes_cnt == chunk_sz) {
+                               k = 0;
+                               bytes_cnt = 0;
++                              check_cnt = 0;
++                              push = verify_push_len;
+                       }
+                       size--;
+               }
+       }
+       *k_p = k;
+       *bytes_cnt_p = bytes_cnt;
++      *check_cnt_p = check_cnt;
++      *push_p = push;
+       return 0;
+ }
+@@ -608,6 +677,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+               struct timeval timeout;
+               unsigned char k = 0;
+               int bytes_cnt = 0;
++              int check_cnt = 0;
++              int push = 0;
+               fd_set w;
+               fcntl(fd, fd_flags);
+@@ -633,6 +704,10 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+               }
+               total_bytes += txmsg_push_total;
+               total_bytes -= txmsg_pop_total;
++              if (data) {
++                      msg_verify_date_prep();
++                      push = verify_push_len;
++              }
+               err = clock_gettime(CLOCK_MONOTONIC, &s->start);
+               if (err < 0)
+                       perror("recv start time");
+@@ -699,7 +774,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                                               iov_length :
+                                               iov_length * iov_count;
+-                              errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt);
++                              errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt,
++                                                      &check_cnt, &push);
+                               if (errno) {
+                                       perror("data verify msg failed");
+                                       goto out_errno;
+@@ -709,7 +785,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                                                               recvp,
+                                                               chunk_sz,
+                                                               &k,
+-                                                              &bytes_cnt);
++                                                              &bytes_cnt,
++                                                              &check_cnt,
++                                                              &push);
+                                       if (errno) {
+                                               perror("data verify msg_peek failed");
+                                               goto out_errno;
+@@ -1600,6 +1678,8 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ {
++      bool data = opt->data_test;
++
+       /* Test basic pop */
+       txmsg_pass = 1;
+       txmsg_start_pop = 1;
+@@ -1618,6 +1698,12 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+       txmsg_pop = 2;
+       test_send_many(opt, cgrp);
++      /* TODO: Test for pop + cork should be different,
++       * - It makes the layout of the received data difficult
++       * - It makes it hard to calculate the total_bytes in the recvmsg
++       * Temporarily skip the data integrity test for this case now.
++       */
++      opt->data_test = false;
+       /* Test pop + cork */
+       txmsg_redir = 0;
+       txmsg_cork = 512;
+@@ -1631,10 +1717,13 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+       txmsg_start_pop = 1;
+       txmsg_pop = 2;
+       test_send_many(opt, cgrp);
++      opt->data_test = data;
+ }
+ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+ {
++      bool data = opt->data_test;
++
+       /* Test basic push */
+       txmsg_pass = 1;
+       txmsg_start_push = 1;
+@@ -1653,12 +1742,19 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+       txmsg_end_push = 2;
+       test_send_many(opt, cgrp);
++      /* TODO: Test for push + cork should be different,
++       * - It makes the layout of the received data difficult
++       * - It makes it hard to calculate the total_bytes in the recvmsg
++       * Temporarily skip the data integrity test for this case now.
++       */
++      opt->data_test = false;
+       /* Test push + cork */
+       txmsg_redir = 0;
+       txmsg_cork = 512;
+       txmsg_start_push = 1;
+       txmsg_end_push = 2;
+       test_send_many(opt, cgrp);
++      opt->data_test = data;
+ }
+ static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt)
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch b/queue-5.10/selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch
new file mode 100644 (file)
index 0000000..9ea42ba
--- /dev/null
@@ -0,0 +1,80 @@
+From 0bcca23933b607b669783fd98423ecd28d6b545e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:13 +0000
+Subject: selftests/bpf: Add txmsg_pass to pull/push/pop in test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 66c54c20408d994be34be2c070fba08472f69eee ]
+
+Add txmsg_pass to test_txmsg_pull/push/pop. If txmsg_pass is missing,
+tx_prog will be NULL, and no program will be attached to the sockmap.
+As a result, pull/push/pop are never invoked.
+
+Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-2-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 157a3c7b735e2..cd3ecf12535c1 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -1547,11 +1547,13 @@ static void test_txmsg_cork_hangs(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+ {
+       /* Test basic start/end */
++      txmsg_pass = 1;
+       txmsg_start = 1;
+       txmsg_end = 2;
+       test_send(opt, cgrp);
+       /* Test >4k pull */
++      txmsg_pass = 1;
+       txmsg_start = 4096;
+       txmsg_end = 9182;
+       test_send_large(opt, cgrp);
+@@ -1580,11 +1582,13 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ {
+       /* Test basic pop */
++      txmsg_pass = 1;
+       txmsg_start_pop = 1;
+       txmsg_pop = 2;
+       test_send_many(opt, cgrp);
+       /* Test pop with >4k */
++      txmsg_pass = 1;
+       txmsg_start_pop = 4096;
+       txmsg_pop = 4096;
+       test_send_large(opt, cgrp);
+@@ -1613,11 +1617,13 @@ static void test_txmsg_pop(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+ {
+       /* Test basic push */
++      txmsg_pass = 1;
+       txmsg_start_push = 1;
+       txmsg_end_push = 1;
+       test_send(opt, cgrp);
+       /* Test push 4kB >4k */
++      txmsg_pass = 1;
+       txmsg_start_push = 4096;
+       txmsg_end_push = 4096;
+       test_send_large(opt, cgrp);
+@@ -1638,6 +1644,7 @@ static void test_txmsg_push(int cgrp, struct sockmap_options *opt)
+ static void test_txmsg_push_pop(int cgrp, struct sockmap_options *opt)
+ {
++      txmsg_pass = 1;
+       txmsg_start_push = 1;
+       txmsg_end_push = 10;
+       txmsg_start_pop = 5;
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch b/queue-5.10/selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch
new file mode 100644 (file)
index 0000000..5fb92cc
--- /dev/null
@@ -0,0 +1,150 @@
+From 2e970d42a024bfe4dac34bbbc64d46c8e32d63c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Oct 2024 20:37:30 +0000
+Subject: selftests/bpf: Fix msg_verify_data in test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit ee9b352ce4650ffc0d8ca0ac373d7c009c7e561e ]
+
+Function msg_verify_data should have context of bytes_cnt and k instead of
+assuming they are zero. Otherwise, test_sockmap with data integrity test
+will report some errors. I also fix the logic related to size and index j
+
+1/ 6  sockmap::txmsg test passthrough:FAIL
+2/ 6  sockmap::txmsg test redirect:FAIL
+7/12  sockmap::txmsg test apply:FAIL
+10/11  sockmap::txmsg test push_data:FAIL
+11/17  sockmap::txmsg test pull-data:FAIL
+12/ 9  sockmap::txmsg test pop-data:FAIL
+13/ 1  sockmap::txmsg test push/pop data:FAIL
+...
+Pass: 24 Fail: 52
+
+After applying this patch, some of the errors are solved, but for push,
+pull and pop, we may need more fixes to msg_verify_data, added a TODO
+
+10/11  sockmap::txmsg test push_data:FAIL
+11/17  sockmap::txmsg test pull-data:FAIL
+12/ 9  sockmap::txmsg test pop-data:FAIL
+...
+Pass: 37 Fail: 15
+
+Besides, added a custom errno EDATAINTEGRITY for msg_verify_data, we
+shall not ignore the error in txmsg_cork case.
+
+Fixes: 753fb2ee0934 ("bpf: sockmap, add msg_peek tests to test_sockmap")
+Fixes: 16edddfe3c5d ("selftests/bpf: test_sockmap, check test failure")
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Link: https://lore.kernel.org/r/20241012203731.1248619-2-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 30 ++++++++++++++--------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 61be5993416e9..48c8f24cf9964 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -58,6 +58,8 @@ static void running_handler(int a);
+ #define BPF_SOCKHASH_FILENAME "test_sockhash_kern.o"
+ #define CG_PATH "/sockmap"
++#define EDATAINTEGRITY 2001
++
+ /* global sockets */
+ int s1, s2, c1, c2, p1, p2;
+ int test_cnt;
+@@ -509,23 +511,25 @@ static int msg_alloc_iov(struct msghdr *msg,
+       return -ENOMEM;
+ }
+-static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz)
++/* TODO: Add verification logic for push, pull and pop data */
++static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz,
++                               unsigned char *k_p, int *bytes_cnt_p)
+ {
+-      int i, j = 0, bytes_cnt = 0;
+-      unsigned char k = 0;
++      int i, j, bytes_cnt = *bytes_cnt_p;
++      unsigned char k = *k_p;
+-      for (i = 0; i < msg->msg_iovlen; i++) {
++      for (i = 0, j = 0; i < msg->msg_iovlen && size; i++, j = 0) {
+               unsigned char *d = msg->msg_iov[i].iov_base;
+               /* Special case test for skb ingress + ktls */
+               if (i == 0 && txmsg_ktls_skb) {
+                       if (msg->msg_iov[i].iov_len < 4)
+-                              return -EIO;
++                              return -EDATAINTEGRITY;
+                       if (memcmp(d, "PASS", 4) != 0) {
+                               fprintf(stderr,
+                                       "detected skb data error with skb ingress update @iov[%i]:%i \"%02x %02x %02x %02x\" != \"PASS\"\n",
+                                       i, 0, d[0], d[1], d[2], d[3]);
+-                              return -EIO;
++                              return -EDATAINTEGRITY;
+                       }
+                       j = 4; /* advance index past PASS header */
+               }
+@@ -535,7 +539,7 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz)
+                               fprintf(stderr,
+                                       "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
+                                       i, j, d[j], k - 1, d[j+1], k);
+-                              return -EIO;
++                              return -EDATAINTEGRITY;
+                       }
+                       bytes_cnt++;
+                       if (bytes_cnt == chunk_sz) {
+@@ -545,6 +549,8 @@ static int msg_verify_data(struct msghdr *msg, int size, int chunk_sz)
+                       size--;
+               }
+       }
++      *k_p = k;
++      *bytes_cnt_p = bytes_cnt;
+       return 0;
+ }
+@@ -593,6 +599,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+               float total_bytes, txmsg_pop_total;
+               int fd_flags = O_NONBLOCK;
+               struct timeval timeout;
++              unsigned char k = 0;
++              int bytes_cnt = 0;
+               fd_set w;
+               fcntl(fd, fd_flags);
+@@ -671,7 +679,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                                               iov_length * cnt :
+                                               iov_length * iov_count;
+-                              errno = msg_verify_data(&msg, recv, chunk_sz);
++                              errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt);
+                               if (errno) {
+                                       perror("data verify msg failed");
+                                       goto out_errno;
+@@ -679,7 +687,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                               if (recvp) {
+                                       errno = msg_verify_data(&msg_peek,
+                                                               recvp,
+-                                                              chunk_sz);
++                                                              chunk_sz,
++                                                              &k,
++                                                              &bytes_cnt);
+                                       if (errno) {
+                                               perror("data verify msg_peek failed");
+                                               goto out_errno;
+@@ -770,7 +780,7 @@ static int sendmsg_test(struct sockmap_options *opt)
+                               s.bytes_sent, sent_Bps, sent_Bps/giga,
+                               s.bytes_recvd, recvd_Bps, recvd_Bps/giga,
+                               peek_flag ? "(peek_msg)" : "");
+-              if (err && txmsg_cork)
++              if (err && err != -EDATAINTEGRITY && txmsg_cork)
+                       err = 0;
+               exit(err ? 1 : 0);
+       } else if (rxpid == -1) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch b/queue-5.10/selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch
new file mode 100644 (file)
index 0000000..7fe4c2a
--- /dev/null
@@ -0,0 +1,86 @@
+From a303f2096a15e7a2f582e904f610dace8c32b49b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:14 +0000
+Subject: selftests/bpf: Fix SENDPAGE data logic in test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 4095031463d4e99b534d2cd82035a417295764ae ]
+
+In the SENDPAGE test, "opt->iov_length * cnt" size of data will be sent
+cnt times by sendfile.
+1. In push/pop tests, they will be invoked cnt times, for the simplicity of
+msg_verify_data, change chunk_sz to iov_length
+2. Change iov_length in test_send_large from 1024 to 8192. We have pop test
+where txmsg_start_pop is 4096. 4096 > 1024, an error will be returned.
+
+Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-3-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index cd3ecf12535c1..46a1ca4f699e2 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -419,16 +419,18 @@ static int msg_loop_sendpage(int fd, int iov_length, int cnt,
+ {
+       bool drop = opt->drop_expected;
+       unsigned char k = 0;
++      int i, j, fp;
+       FILE *file;
+-      int i, fp;
+       file = tmpfile();
+       if (!file) {
+               perror("create file for sendpage");
+               return 1;
+       }
+-      for (i = 0; i < iov_length * cnt; i++, k++)
+-              fwrite(&k, sizeof(char), 1, file);
++      for (i = 0; i < cnt; i++, k = 0) {
++              for (j = 0; j < iov_length; j++, k++)
++                      fwrite(&k, sizeof(char), 1, file);
++      }
+       fflush(file);
+       fseek(file, 0, SEEK_SET);
+@@ -614,7 +616,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                * This is really only useful for testing edge cases in code
+                * paths.
+                */
+-              total_bytes = (float)iov_count * (float)iov_length * (float)cnt;
++              total_bytes = (float)iov_length * (float)cnt;
++              if (!opt->sendpage)
++                      total_bytes *= (float)iov_count;
+               if (txmsg_apply)
+                       txmsg_pop_total = txmsg_pop * (total_bytes / txmsg_apply);
+               else
+@@ -676,7 +680,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+                       if (data) {
+                               int chunk_sz = opt->sendpage ?
+-                                              iov_length * cnt :
++                                              iov_length :
+                                               iov_length * iov_count;
+                               errno = msg_verify_data(&msg, recv, chunk_sz, &k, &bytes_cnt);
+@@ -1425,8 +1429,8 @@ static void test_send_many(struct sockmap_options *opt, int cgrp)
+ static void test_send_large(struct sockmap_options *opt, int cgrp)
+ {
+-      opt->iov_length = 256;
+-      opt->iov_count = 1024;
++      opt->iov_length = 8192;
++      opt->iov_count = 32;
+       opt->rate = 2;
+       test_exec(cgrp, opt);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch b/queue-5.10/selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch
new file mode 100644 (file)
index 0000000..89902f0
--- /dev/null
@@ -0,0 +1,71 @@
+From 8b23b22ddc044aa73937cc765843bddbae2db7b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 22:25:15 +0000
+Subject: selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit 523dffccbadea0cfd65f1ff04944b864c558c4a8 ]
+
+total_bytes in msg_loop_rx should also take push into account, otherwise
+total_bytes will be a smaller value, which makes the msg_loop_rx end early.
+
+Besides, total_bytes has already taken pop into account, so we don't need
+to subtract some bytes from iov_buf in sendmsg_test. The additional
+subtraction may make total_bytes a negative number, and msg_loop_rx will
+just end without checking anything.
+
+Fixes: 18d4e900a450 ("bpf: Selftests, improve test_sockmap total bytes counter")
+Fixes: d69672147faa ("selftests, bpf: Add one test for sockmap with strparser")
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Reviewed-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20241106222520.527076-4-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 89d215416a34e..85d6fac7124bd 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -602,8 +602,8 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+               }
+               clock_gettime(CLOCK_MONOTONIC, &s->end);
+       } else {
++              float total_bytes, txmsg_pop_total, txmsg_push_total;
+               int slct, recvp = 0, recv, max_fd = fd;
+-              float total_bytes, txmsg_pop_total;
+               int fd_flags = O_NONBLOCK;
+               struct timeval timeout;
+               unsigned char k = 0;
+@@ -624,10 +624,14 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
+               total_bytes = (float)iov_length * (float)cnt;
+               if (!opt->sendpage)
+                       total_bytes *= (float)iov_count;
+-              if (txmsg_apply)
++              if (txmsg_apply) {
++                      txmsg_push_total = txmsg_end_push * (total_bytes / txmsg_apply);
+                       txmsg_pop_total = txmsg_pop * (total_bytes / txmsg_apply);
+-              else
++              } else {
++                      txmsg_push_total = txmsg_end_push * cnt;
+                       txmsg_pop_total = txmsg_pop * cnt;
++              }
++              total_bytes += txmsg_push_total;
+               total_bytes -= txmsg_pop_total;
+               err = clock_gettime(CLOCK_MONOTONIC, &s->start);
+               if (err < 0)
+@@ -771,8 +775,6 @@ static int sendmsg_test(struct sockmap_options *opt)
+       rxpid = fork();
+       if (rxpid == 0) {
+-              if (txmsg_pop || txmsg_start_pop)
+-                      iov_buf -= (txmsg_pop - txmsg_start_pop + 1);
+               if (opt->drop_expected || txmsg_ktls_skb_drop)
+                       _exit(0);
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch b/queue-5.10/selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch
new file mode 100644 (file)
index 0000000..6901c25
--- /dev/null
@@ -0,0 +1,38 @@
+From 272c3cf81a7cf38295feaf607361d91b148fbd58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Oct 2024 20:37:31 +0000
+Subject: selftests/bpf: Fix txmsg_redir of test_txmsg_pull in test_sockmap
+
+From: Zijian Zhang <zijianzhang@bytedance.com>
+
+[ Upstream commit b29e231d66303c12b7b8ac3ac2a057df06b161e8 ]
+
+txmsg_redir in "Test pull + redirect" case of test_txmsg_pull should be
+1 instead of 0.
+
+Fixes: 328aa08a081b ("bpf: Selftests, break down test_sockmap into subtests")
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
+Link: https://lore.kernel.org/r/20241012203731.1248619-3-zijianzhang@bytedance.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_sockmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/test_sockmap.c b/tools/testing/selftests/bpf/test_sockmap.c
+index 48c8f24cf9964..157a3c7b735e2 100644
+--- a/tools/testing/selftests/bpf/test_sockmap.c
++++ b/tools/testing/selftests/bpf/test_sockmap.c
+@@ -1557,7 +1557,7 @@ static void test_txmsg_pull(int cgrp, struct sockmap_options *opt)
+       test_send_large(opt, cgrp);
+       /* Test pull + redirect */
+-      txmsg_redir = 0;
++      txmsg_redir = 1;
+       txmsg_start = 1;
+       txmsg_end = 2;
+       test_send(opt, cgrp);
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-net-really-check-for-bg-process-completion.patch b/queue-5.10/selftests-net-really-check-for-bg-process-completion.patch
new file mode 100644 (file)
index 0000000..0a52039
--- /dev/null
@@ -0,0 +1,43 @@
+From 0617b931f4b510e4cdcf7ff2ad594ae683cd88cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 19:23:51 +0100
+Subject: selftests: net: really check for bg process completion
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 52ed077aa6336dbef83a2d6d21c52d1706fb7f16 ]
+
+A recent refactor transformed the check for process completion
+in a true statement, due to a typo.
+
+As a result, the relevant test-case is unable to catch the
+regression it was supposed to detect.
+
+Restore the correct condition.
+
+Fixes: 691bb4e49c98 ("selftests: net: avoid just another constant wait")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/0e6f213811f8e93a235307e683af8225cc6277ae.1730828007.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/pmtu.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
+index 9cd5cf800a5b5..f4116f0723e3f 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -1587,7 +1587,7 @@ check_running() {
+       pid=${1}
+       cmd=${2}
+-      [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "{cmd}" ]
++      [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "${cmd}" ]
+ }
+ test_cleanup_vxlanX_exception() {
+-- 
+2.43.0
+
diff --git a/queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch b/queue-5.10/selftests-resctrl-protect-against-array-overrun-duri.patch
new file mode 100644 (file)
index 0000000..09a2d9b
--- /dev/null
@@ -0,0 +1,67 @@
+From b09717be20895a61d5df76e0a2156deddff3f599 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Oct 2024 14:18:41 -0700
+Subject: selftests/resctrl: Protect against array overrun during iMC config
+ parsing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Reinette Chatre <reinette.chatre@intel.com>
+
+[ Upstream commit 48ed4e799e8fbebae838dca404a8527763d41191 ]
+
+The MBM and MBA tests need to discover the event and umask with which to
+configure the performance event used to measure read memory bandwidth.
+This is done by parsing the
+/sys/bus/event_source/devices/uncore_imc_<imc instance>/events/cas_count_read
+file for each iMC instance that contains the formatted
+output: "event=<event>,umask=<umask>"
+
+Parsing of cas_count_read contents is done by initializing an array of
+MAX_TOKENS elements with tokens (deliminated by "=,") from this file.
+Remove the unnecessary append of a delimiter to the string needing to be
+parsed. Per the strtok() man page: "delimiter bytes at the start or end of
+the string are ignored". This has no impact on the token placement within
+the array.
+
+After initialization, the actual event and umask is determined by
+parsing the tokens directly following the "event" and "umask" tokens
+respectively.
+
+Iterating through the array up to index "i < MAX_TOKENS" but then
+accessing index "i + 1" risks array overrun during the final iteration.
+Avoid array overrun by ensuring that the index used within for
+loop will always be valid.
+
+Fixes: 1d3f08687d76 ("selftests/resctrl: Read memory bandwidth from perf IMC counter and from resctrl file system")
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl_val.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 8df557894059a..a93fab28f97ec 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -102,13 +102,12 @@ void get_event_and_umask(char *cas_count_cfg, int count, bool op)
+       char *token[MAX_TOKENS];
+       int i = 0;
+-      strcat(cas_count_cfg, ",");
+       token[0] = strtok(cas_count_cfg, "=,");
+       for (i = 1; i < MAX_TOKENS; i++)
+               token[i] = strtok(NULL, "=,");
+-      for (i = 0; i < MAX_TOKENS; i++) {
++      for (i = 0; i < MAX_TOKENS - 1; i++) {
+               if (!token[i])
+                       break;
+               if (strcmp(token[i], "event") == 0) {
+-- 
+2.43.0
+
index 1ad8851164b3cfecf2ac8ed1544a742e6d52a821..c9d7e1e1b3e926714d6110f8b23a5243a93102fa 100644 (file)
@@ -40,3 +40,194 @@ rcu-tasks-idle-tasks-on-offline-cpus-are-in-quiescen.patch
 x86-stackprotector-work-around-strict-clang-tls-symb.patch
 cifs-fix-buffer-overflow-when-parsing-nfs-reparse-po.patch
 nvme-fix-metadata-handling-in-nvme-passthrough.patch
+x86-barrier-do-not-serialize-msr-accesses-on-amd.patch
+kselftest-arm64-mte-fix-printf-type-warnings-about-l.patch
+x86-xen-pvh-annotate-indirect-branch-as-safe.patch
+x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch
+x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch
+mips-asm-fix-warning-when-disabling-mips_fp_support.patch
+initramfs-avoid-filename-buffer-overrun.patch
+nvme-pci-fix-freeing-of-the-hmb-descriptor-table.patch
+m68k-mvme147-fix-scsi-controller-irq-numbers.patch
+m68k-mvme16x-add-and-use-mvme16x.h.patch
+m68k-mvme147-reinstate-early-console.patch
+arm64-fix-.data.rel.ro-size-assertion-when-config_lt.patch
+acpi-arm64-adjust-error-handling-procedure-in-gtdt_p.patch
+s390-syscalls-avoid-creation-of-arch-arch-directory.patch
+hfsplus-don-t-query-the-device-logical-block-size-mu.patch
+crypto-caam-fix-the-pointer-passed-to-caam_qi_shutdo.patch
+firmware-google-unregister-driver_info-on-failure.patch
+edac-bluefield-fix-potential-integer-overflow.patch
+edac-fsl_ddr-fix-bad-bit-shift-operations.patch
+crypto-pcrypt-call-crypto-layer-directly-when-padata.patch
+crypto-cavium-fix-the-if-condition-to-exit-loop-afte.patch
+crypto-caam-add-error-check-to-caam_rsa_set_priv_key.patch
+crypto-bcm-add-error-check-in-the-ahash_hmac_init-fu.patch
+crypto-cavium-fix-an-error-handling-path-in-cpt_ucod.patch
+time-fix-references-to-_msecs_to_jiffies-handling-of.patch
+kcsan-seqlock-fix-incorrect-assumption-in-read_seqbe.patch
+clkdev-remove-config_clkdev_lookup.patch
+clocksource-drivers-sp804-make-user-selectable.patch
+clocksource-drivers-timer-ti-dm-fix-child-node-refco.patch
+spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch
+spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch
+soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch
+soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch
+mmc-mmc_spi-drop-buggy-snprintf.patch
+tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch
+arm64-dts-mt8183-krane-fix-the-address-of-eeprom-at-.patch
+arm64-dts-mediatek-mt8173-elm-hana-add-vdd-supply-to.patch
+revert-cgroup-fix-memory-leak-caused-by-missing-cgro.patch
+cgroup-bpf-only-cgroup-v2-can-be-attached-by-bpf-pro.patch
+pwm-imx27-workaround-of-the-pwm-output-bug-when-decr.patch
+arm-dts-cubieboard4-fix-dcdc5-regulator-constraints.patch
+pmdomain-ti-sci-add-missing-of_node_put-for-args.np.patch
+regmap-irq-set-lockdep-class-for-hierarchical-irq-do.patch
+selftests-resctrl-protect-against-array-overrun-duri.patch
+firmware-arm_scpi-check-the-dvfs-opp-count-returned-.patch
+media-atomisp-remove-ifdef-has_no_hmem.patch
+media-atomisp-add-check-for-rgby_data-memory-allocat.patch
+drm-mm-mark-drm_mm_interval_tree-functions-with-__ma.patch
+wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch
+drm-omap-fix-locking-in-omap_gem_new_dmabuf.patch
+wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch
+wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch
+drm-imx-dcss-use-irqf_no_autoen-flag-in-request_irq.patch
+drm-imx-ipuv3-use-irqf_no_autoen-flag-in-request_irq.patch
+drm-v3d-address-race-condition-in-mmu-flush.patch
+wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch
+wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150
+dt-bindings-vendor-prefixes-add-neofidelity-inc.patch
+asoc-fsl_micfil-drop-unnecessary-register-read.patch
+asoc-fsl_micfil-do-not-define-shift-mask-for-single-.patch
+asoc-fsl_micfil-use-genmask-to-define-register-bit-f.patch
+asoc-fsl_micfil-fix-regmap_write_bits-usage.patch
+asoc-dt-bindings-mt6359-update-generic-node-name-and.patch
+bpf-fix-the-xdp_adjust_tail-sample-prog-issue.patch
+xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch
+xfrm-store-and-rely-on-direction-to-construct-offloa.patch
+netdevsim-rely-on-xfrm-state-direction-instead-of-fl.patch
+netdevsim-copy-addresses-for-both-in-and-out-paths.patch
+drm-bridge-tc358767-fix-link-properties-discovery.patch
+selftests-bpf-fix-msg_verify_data-in-test_sockmap.patch
+selftests-bpf-fix-txmsg_redir-of-test_txmsg_pull-in-.patch
+wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch
+drm-fsl-dcu-convert-to-linux-irq-interfaces.patch
+drm-fsl-dcu-enable-pixclk-on-ls1021a.patch
+octeontx2-af-mbox-changes-for-98xx.patch
+octeontx2-pf-calculate-lbk-link-instead-of-hardcodin.patch
+octeontx2-af-forward-error-correction-configuration.patch
+octeontx2-af-add-new-cgx_cmd-to-get-phy-fec-statisti.patch
+octeontx2-pf-ethtool-fec-mode-support.patch
+octeontx2-pf-handle-otx2_mbox_get_rsp-errors-in-otx2.patch
+drm-panfrost-remove-unused-id_mask-from-struct-panfr.patch
+drm-msm-adreno-use-irqf_no_autoen-flag-in-request_ir.patch
+drm-etnaviv-rework-linear-window-offset-calculation.patch
+drm-etnaviv-request-pages-from-dma32-zone-on-address.patch
+drm-etnaviv-dump-fix-sparse-warnings.patch
+drm-etnaviv-fix-power-register-offset-on-gc300.patch
+drm-etnaviv-hold-gpu-lock-across-perfmon-sampling.patch
+wifi-wfx-fix-error-handling-in-wfx_core_init.patch
+drm-msm-dpu-cast-crtc_clk-calculation-to-u64-in-_dpu.patch
+netlink-typographical-error-in-nlmsg_type-constants-.patch
+selftests-bpf-add-txmsg_pass-to-pull-push-pop-in-tes.patch
+selftests-bpf-fix-sendpage-data-logic-in-test_sockma.patch
+selftests-bpf-add-one-test-for-sockmap-with-strparse.patch
+selftests-bpf-fix-total_bytes-in-msg_loop_rx-in-test.patch
+selftests-bpf-add-push-pop-checking-for-msg_verify_d.patch
+bpf-sockmap-several-fixes-to-bpf_msg_push_data.patch
+bpf-sockmap-several-fixes-to-bpf_msg_pop_data.patch
+bpf-sockmap-fix-sk_msg_reset_curr.patch
+selftests-net-really-check-for-bg-process-completion.patch
+drm-amdkfd-fix-wrong-usage-of-init_work.patch
+net-rfkill-gpio-add-check-for-clk_enable.patch
+alsa-usx2y-fix-spaces.patch
+alsa-usx2y-coding-style-fixes.patch
+alsa-usx2y-cleanup-probe-and-disconnect-callbacks.patch
+alsa-usx2y-use-snd_card_free_when_closed-at-disconne.patch
+alsa-us122l-use-snd_card_free_when_closed-at-disconn.patch
+alsa-caiaq-use-snd_card_free_when_closed-at-disconne.patch
+alsa-6fire-release-resources-at-card-release.patch
+driver-core-introduce-device_find_any_child-helper.patch
+bluetooth-fix-use-after-free-in-device_for_each_chil.patch
+netpoll-use-rcu_access_pointer-in-netpoll_poll_lock.patch
+wireguard-selftests-load-nf_conntrack-if-not-present.patch
+trace-trace_event_perf-remove-duplicate-samples-on-t.patch
+powerpc-vdso-flag-vdso64-entry-points-as-functions.patch
+mfd-tps65010-use-irqf_no_autoen-flag-in-request_irq-.patch
+mfd-da9052-spi-change-read-mask-to-write-mask.patch
+mfd-intel_soc_pmic_bxtwc-use-dev_err_probe.patch
+mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-usb-type.patch
+mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-tmu-devi.patch
+mfd-intel_soc_pmic_bxtwc-use-irq-domain-for-pmic-dev.patch
+cpufreq-loongson2-unregister-platform_driver-on-fail.patch
+mtd-rawnand-atmel-fix-possible-memory-leak.patch
+powerpc-pseries-fix-dtl_access_lock-to-be-a-rw_semap.patch
+rdma-bnxt_re-check-cqe-flags-to-know-imm_data-vs-inv.patch
+mfd-rt5033-fix-missing-regmap_del_irq_chip.patch
+scsi-bfa-fix-use-after-free-in-bfad_im_module_exit.patch
+scsi-fusion-remove-unused-variable-rc.patch
+scsi-qedf-fix-a-possible-memory-leak-in-qedf_alloc_a.patch
+scsi-qedi-fix-a-possible-memory-leak-in-qedi_alloc_a.patch
+rdma-hns-fix-null-pointer-derefernce-in-hns_roce_map.patch
+ocfs2-fix-uninitialized-value-in-ocfs2_file_read_ite.patch
+powerpc-sstep-make-emulate_vsx_load-and-emulate_vsx_.patch
+powerpc-kexec-fix-return-of-uninitialized-variable.patch
+fbdev-sh7760fb-alloc-dma-memory-from-hardware-device.patch
+fbdev-sh7760fb-fix-a-possible-memory-leak-in-sh7760f.patch
+dt-bindings-clock-adi-axi-clkgen-convert-old-binding.patch
+dt-bindings-clock-axi-clkgen-include-axi-clk.patch
+clk-axi-clkgen-use-devm_platform_ioremap_resource-sh.patch
+clk-clk-axi-clkgen-make-sure-to-enable-the-axi-bus-c.patch
+perf-cs-etm-don-t-flush-when-packet_queue-fills-up.patch
+perf-probe-fix-libdw-memory-leak.patch
+perf-probe-correct-demangled-symbols-in-c-program.patch
+pci-cpqphp-use-pci_possible_error-to-check-config-re.patch
+pci-cpqphp-fix-pcibios_-return-value-confusion.patch
+f2fs-fix-the-wrong-f2fs_bug_on-condition-in-f2fs_do_.patch
+f2fs-avoid-using-native-allocate_segment_by_default.patch
+f2fs-remove-struct-segment_allocation-default_salloc.patch
+f2fs-open-code-allocate_segment_by_default.patch
+f2fs-remove-the-unused-flush-argument-to-change_curs.patch
+f2fs-check-curseg-inited-before-write_sum_page-in-ch.patch
+perf-trace-avoid-garbage-when-not-printing-a-trace-e.patch
+m68k-mcfgpio-fix-incorrect-register-offset-for-confi.patch
+m68k-coldfire-device.c-only-build-fec-when-hw-macros.patch
+perf-trace-do-not-lose-last-events-in-a-race.patch
+perf-trace-avoid-garbage-when-not-printing-a-syscall.patch
+rpmsg-glink-add-tx_data_cont-command-while-sending.patch
+rpmsg-glink-send-read_notify-command-in-fifo-full-ca.patch
+rpmsg-glink-fix-glink-command-prefix.patch
+rpmsg-glink-use-only-lower-16-bits-of-param2-for-cmd.patch
+remoteproc-qcom_q6v5_mss-re-order-writes-to-the-imem.patch
+nfsd-prevent-null-dereference-in-nfsd4_process_cb_up.patch
+nfsd-cap-the-number-of-bytes-copied-by-nfs4_reset_re.patch
+nfsd-fix-nfsd4_shutdown_copy.patch
+vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch
+vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch
+fs_parser-update-mount_api-doc-to-match-function-sig.patch
+power-supply-core-remove-might_sleep-from-power_supp.patch
+power-supply-bq27xxx-support-charge_now-for-bq27z561.patch
+power-supply-bq27xxx-fix-registers-of-bq27426.patch
+net-usb-lan78xx-fix-memory-leak-on-device-unplug-by-.patch
+tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch
+net-usb-lan78xx-fix-refcounting-and-autosuspend-on-i.patch
+marvell-pxa168_eth-fix-call-balance-of-pep-clk-handl.patch
+net-stmmac-dwmac-socfpga-set-rx-watchdog-interrupt-a.patch
+spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch
+net-introduce-a-netdev-feature-for-udp-gro-forwardin.patch
+net-hsr-fix-hsr_init_sk-vs-network-transport-headers.patch
+bnxt_en-reserve-rings-after-pcie-aer-recovery-if-nic.patch
+ipmr-convert-proc-handlers-to-rcu_read_lock.patch
+ipmr-fix-tables-suspicious-rcu-usage.patch
+iio-light-al3010-fix-an-error-handling-path-in-al301.patch
+usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch
+usb-yurex-make-waiting-on-yurex_write-interruptible.patch
+usb-chaoskey-fail-open-after-removal.patch
+usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch
+misc-apds990x-fix-missing-pm_runtime_disable.patch
+staging-greybus-uart-clean-up-tiocgserial.patch
+staging-greybus-uart-fix-atomicity-violation-in-get_.patch
+alsa-hda-realtek-add-type-for-alc287.patch
+alsa-hda-realtek-update-alc256-depop-procedure.patch
+apparmor-fix-do-simple-duplicate-message-elimination.patch
diff --git a/queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch b/queue-5.10/soc-qcom-geni-se-fix-array-underflow-in-geni_se_clk_.patch
new file mode 100644 (file)
index 0000000..b8210cf
--- /dev/null
@@ -0,0 +1,40 @@
+From 113682d80d99f9b4ebf05801a26f45d3bab7bc90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 10:51:31 +0300
+Subject: soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 78261cb08f06c93d362cab5c5034bf5899bc7552 ]
+
+This loop is supposed to break if the frequency returned from
+clk_round_rate() is the same as on the previous iteration.  However,
+that check doesn't make sense on the first iteration through the loop.
+It leads to reading before the start of these->clk_perf_tbl[] array.
+
+Fixes: eddac5af0654 ("soc: qcom: Add GENI based QUP Wrapper driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/8cd12678-f44a-4b16-a579-c8f11175ee8c@stanley.mountain
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/qcom-geni-se.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
+index 0dbca679bd32f..0d4b48f135855 100644
+--- a/drivers/soc/qcom/qcom-geni-se.c
++++ b/drivers/soc/qcom/qcom-geni-se.c
+@@ -553,7 +553,8 @@ int geni_se_clk_tbl_get(struct geni_se *se, unsigned long **tbl)
+       for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) {
+               freq = clk_round_rate(se->clk, freq + 1);
+-              if (freq <= 0 || freq == se->clk_perf_tbl[i - 1])
++              if (freq <= 0 ||
++                  (i > 0 && freq == se->clk_perf_tbl[i - 1]))
+                       break;
+               se->clk_perf_tbl[i] = freq;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch b/queue-5.10/soc-ti-smartreflex-use-irqf_no_autoen-flag-in-reques.patch
new file mode 100644 (file)
index 0000000..0186bde
--- /dev/null
@@ -0,0 +1,45 @@
+From 54f388470c66c0e5e0ff03f9bad3c8db56e241e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 11:41:47 +0800
+Subject: soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 16a0a69244240cfa32c525c021c40f85e090557a ]
+
+If request_irq() fails in sr_late_init(), there is no need to enable
+the irq, and if it succeeds, disable_irq() after request_irq() still has
+a time gap in which interrupts can come.
+
+request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable when
+request IRQ.
+
+Fixes: 1279ba5916f6 ("OMAP3+: SR: disable interrupt by default")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20240912034147.3014213-1-ruanjinjie@huawei.com
+Signed-off-by: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/ti/smartreflex.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
+index 1228a0cba1320..8330098b45df9 100644
+--- a/drivers/soc/ti/smartreflex.c
++++ b/drivers/soc/ti/smartreflex.c
+@@ -213,10 +213,10 @@ static int sr_late_init(struct omap_sr *sr_info)
+       if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
+               ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
+-                                     sr_interrupt, 0, sr_info->name, sr_info);
++                                     sr_interrupt, IRQF_NO_AUTOEN,
++                                     sr_info->name, sr_info);
+               if (ret)
+                       goto error;
+-              disable_irq(sr_info->irq);
+       }
+       if (pdata && pdata->enable_on_init)
+-- 
+2.43.0
+
diff --git a/queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch b/queue-5.10/spi-atmel-quadspi-fix-register-name-in-verbose-loggi.patch
new file mode 100644 (file)
index 0000000..88f632d
--- /dev/null
@@ -0,0 +1,43 @@
+From 08893b2c6b5872c908f46f4721aa620328307071 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 15:13:02 +0100
+Subject: spi: atmel-quadspi: Fix register name in verbose logging function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Csókás, Bence <csokas.bence@prolan.hu>
+
+[ Upstream commit 2ac40e6d0ccdd93031f8b1af61b0fe5cdd704923 ]
+
+`atmel_qspi_reg_name()` is used for pretty-printing register offsets
+for verbose logging of register accesses. However, due to a typo
+(likely a copy-paste error), QSPI_RD's offset prints as "MR", the
+name of the previous register. Fix this typo.
+
+Fixes: c528ecfbef04 ("spi: atmel-quadspi: Add verbose debug facilities to monitor register accesses")
+Signed-off-by: Csókás, Bence <csokas.bence@prolan.hu>
+Reviewed-by: Alexander Dahl <ada@thorsis.com>
+Link: https://patch.msgid.link/20241122141302.2599636-1-csokas.bence@prolan.hu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/atmel-quadspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
+index 8aa89d93db118..17217cc5e4052 100644
+--- a/drivers/spi/atmel-quadspi.c
++++ b/drivers/spi/atmel-quadspi.c
+@@ -182,7 +182,7 @@ static const char *atmel_qspi_reg_name(u32 offset, char *tmp, size_t sz)
+       case QSPI_MR:
+               return "MR";
+       case QSPI_RD:
+-              return "MR";
++              return "RD";
+       case QSPI_TD:
+               return "TD";
+       case QSPI_SR:
+-- 
+2.43.0
+
diff --git a/queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch b/queue-5.10/spi-spi-fsl-lpspi-downgrade-log-level-for-pio-mode.patch
new file mode 100644 (file)
index 0000000..bf7e9fa
--- /dev/null
@@ -0,0 +1,38 @@
+From 8bcedf8c260791a7cd106395d4f4615df0ef32fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 May 2023 09:28:49 +0200
+Subject: spi: spi-fsl-lpspi: downgrade log level for pio mode
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit d5786c88cacbb859f465e8e93c26154585c1008d ]
+
+Having no DMA is not an error. The simplest reason is not having it
+configured. SPI will still be usable, so raise a warning instead to
+get still some attention.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20230531072850.739021-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 003c7e01916c ("spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index 8ab3105ae8c07..efd2a9b6a9b26 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -909,7 +909,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+       if (ret == -EPROBE_DEFER)
+               goto out_pm_get;
+       if (ret < 0)
+-              dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret);
++              dev_warn(&pdev->dev, "dma setup error %d, use pio\n", ret);
+       else
+               /*
+                * disable LPSPI module IRQ when enable DMA mode successfully,
+-- 
+2.43.0
+
diff --git a/queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch b/queue-5.10/spi-spi-fsl-lpspi-use-irqf_no_autoen-flag-in-request.patch
new file mode 100644 (file)
index 0000000..2618c47
--- /dev/null
@@ -0,0 +1,56 @@
+From cdcbe683f03d64da2a40349de2ded83fbb1dc0d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 10:28:28 +0800
+Subject: spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 003c7e01916c5e2af95add9b0cbda2e6163873e8 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 9728fb3ce117 ("spi: lpspi: disable lpspi module irq in DMA mode")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240906022828.891812-1-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index efd2a9b6a9b26..bf3f600bdd2c8 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -871,7 +871,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+               goto out_controller_put;
+       }
+-      ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
++      ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, IRQF_NO_AUTOEN,
+                              dev_name(&pdev->dev), fsl_lpspi);
+       if (ret) {
+               dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
+@@ -908,14 +908,10 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+       ret = fsl_lpspi_dma_init(&pdev->dev, fsl_lpspi, controller);
+       if (ret == -EPROBE_DEFER)
+               goto out_pm_get;
+-      if (ret < 0)
++      if (ret < 0) {
+               dev_warn(&pdev->dev, "dma setup error %d, use pio\n", ret);
+-      else
+-              /*
+-               * disable LPSPI module IRQ when enable DMA mode successfully,
+-               * to prevent the unexpected LPSPI module IRQ events.
+-               */
+-              disable_irq(irq);
++              enable_irq(irq);
++      }
+       ret = devm_spi_register_controller(&pdev->dev, controller);
+       if (ret < 0) {
+-- 
+2.43.0
+
diff --git a/queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch b/queue-5.10/staging-greybus-uart-clean-up-tiocgserial.patch
new file mode 100644 (file)
index 0000000..170fb3c
--- /dev/null
@@ -0,0 +1,60 @@
+From 3c894fa939bbe56314fa7c33ece04c809acb1565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Apr 2021 12:23:25 +0200
+Subject: staging: greybus: uart: clean up TIOCGSERIAL
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit d38be702452137fa82a56ff7cc577d829add1637 ]
+
+TIOCSSERIAL is a horrid, underspecified, legacy interface which for most
+serial devices is only useful for setting the close_delay and
+closing_wait parameters.
+
+The xmit_fifo_size parameter could be used to set the hardware transmit
+fifo size of a legacy UART when it could not be detected, but the
+interface is limited to eight bits and should be left unset when not
+used.
+
+Similarly, baud_base could be used to set the UART base clock when it
+could not be detected but might as well be left unset when it is not
+known.
+
+The type parameter could be used to set the UART type, but is
+better left unspecified (type unknown) when it isn't used.
+
+Note that some applications have historically expected TIOCGSERIAL to be
+implemented, but judging from the Debian sources, the port type not
+being PORT_UNKNOWN is only used to check for the existence of legacy
+serial ports (ttySn). Notably USB serial drivers like ftdi_sio have been
+using PORT_UNKNOWN for twenty years without any problems.
+
+Drop the bogus values provided by the greybus implementation.
+
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210407102334.32361-8-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: fe0ebeafc3b7 ("staging: greybus: uart: Fix atomicity violation in get_serial_info()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/greybus/uart.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
+index edaa83a693d27..5cdc5dff9f55b 100644
+--- a/drivers/staging/greybus/uart.c
++++ b/drivers/staging/greybus/uart.c
+@@ -610,10 +610,7 @@ static int get_serial_info(struct tty_struct *tty,
+ {
+       struct gb_tty *gb_tty = tty->driver_data;
+-      ss->type = PORT_16550A;
+       ss->line = gb_tty->minor;
+-      ss->xmit_fifo_size = 16;
+-      ss->baud_base = 9600;
+       ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10;
+       ss->closing_wait =
+               gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+-- 
+2.43.0
+
diff --git a/queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch b/queue-5.10/staging-greybus-uart-fix-atomicity-violation-in-get_.patch
new file mode 100644 (file)
index 0000000..f12e002
--- /dev/null
@@ -0,0 +1,49 @@
+From 063dd345b5a511167552b9dfcd2dd8fc565f48bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Nov 2024 19:33:37 +0800
+Subject: staging: greybus: uart: Fix atomicity violation in get_serial_info()
+
+From: Qiu-ji Chen <chenqiuji666@gmail.com>
+
+[ Upstream commit fe0ebeafc3b723b2f8edf27ecec6d353b08397df ]
+
+Our static checker found a bug where set_serial_info() uses a mutex, but
+get_serial_info() does not. Fortunately, the impact of this is relatively
+minor. It doesn't cause a crash or any other serious issues. However, if a
+race condition occurs between set_serial_info() and get_serial_info(),
+there is a chance that the data returned by get_serial_info() will be
+meaningless.
+
+Signed-off-by: Qiu-ji Chen <chenqiuji666@gmail.com>
+Fixes: 0aad5ad563c8 ("greybus/uart: switch to ->[sg]et_serial()")
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Alex Elder <elder@riscstar.com>
+Link: https://lore.kernel.org/r/20241107113337.402042-1-chenqiuji666@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/greybus/uart.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
+index 5cdc5dff9f55b..257f917a93745 100644
+--- a/drivers/staging/greybus/uart.c
++++ b/drivers/staging/greybus/uart.c
+@@ -611,11 +611,13 @@ static int get_serial_info(struct tty_struct *tty,
+       struct gb_tty *gb_tty = tty->driver_data;
+       ss->line = gb_tty->minor;
++      mutex_lock(&gb_tty->port.mutex);
+       ss->close_delay = jiffies_to_msecs(gb_tty->port.close_delay) / 10;
+       ss->closing_wait =
+               gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+               ASYNC_CLOSING_WAIT_NONE :
+               jiffies_to_msecs(gb_tty->port.closing_wait) / 10;
++      mutex_unlock(&gb_tty->port.mutex);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch b/queue-5.10/tg3-set-coherent-dma-mask-bits-to-31-for-bcm57766-ch.patch
new file mode 100644 (file)
index 0000000..ce2b23f
--- /dev/null
@@ -0,0 +1,61 @@
+From 3862196fd9b065cf8ac75077473f132492ea6e9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Nov 2024 21:57:41 -0800
+Subject: tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets
+
+From: Pavan Chebbi <pavan.chebbi@broadcom.com>
+
+[ Upstream commit 614f4d166eeeb9bd709b0ad29552f691c0f45776 ]
+
+The hardware on Broadcom 1G chipsets have a known limitation
+where they cannot handle DMA addresses that cross over 4GB.
+When such an address is encountered, the hardware sets the
+address overflow error bit in the DMA status register and
+triggers a reset.
+
+However, BCM57766 hardware is setting the overflow bit and
+triggering a reset in some cases when there is no actual
+underlying address overflow. The hardware team analyzed the
+issue and concluded that it is happening when the status
+block update has an address with higher (b16 to b31) bits
+as 0xffff following a previous update that had lowest bits
+as 0xffff.
+
+To work around this bug in the BCM57766 hardware, set the
+coherent dma mask from the current 64b to 31b. This will
+ensure that upper bits of the status block DMA address are
+always at most 0x7fff, thus avoiding the improper overflow
+check described above. This work around is intended for only
+status block and ring memories and has no effect on TX and
+RX buffers as they do not require coherent memory.
+
+Fixes: 72f2afb8a685 ("[TG3]: Add DMA address workaround")
+Reported-by: Salam Noureddine <noureddine@arista.com>
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Link: https://patch.msgid.link/20241119055741.147144-1-pavan.chebbi@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/tg3.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index fe2c9b110e606..937579817f226 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -17807,6 +17807,9 @@ static int tg3_init_one(struct pci_dev *pdev,
+       } else
+               persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
++      if (tg3_asic_rev(tp) == ASIC_REV_57766)
++              persist_dma_mask = DMA_BIT_MASK(31);
++
+       /* Configure DMA attributes. */
+       if (dma_mask > DMA_BIT_MASK(32)) {
+               err = pci_set_dma_mask(pdev, dma_mask);
+-- 
+2.43.0
+
diff --git a/queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch b/queue-5.10/time-fix-references-to-_msecs_to_jiffies-handling-of.patch
new file mode 100644 (file)
index 0000000..5881015
--- /dev/null
@@ -0,0 +1,55 @@
+From 43aba77dab02a79d1b698d83b5221eeca448f606 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Oct 2024 13:01:41 +0200
+Subject: time: Fix references to _msecs_to_jiffies() handling of values
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 92b043fd995a63a57aae29ff85a39b6f30cd440c ]
+
+The details about the handling of the "normal" values were moved
+to the _msecs_to_jiffies() helpers in commit ca42aaf0c861 ("time:
+Refactor msecs_to_jiffies"). However, the same commit still mentioned
+__msecs_to_jiffies() in the added documentation.
+
+Thus point to _msecs_to_jiffies() instead.
+
+Fixes: ca42aaf0c861 ("time: Refactor msecs_to_jiffies")
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/all/20241025110141.157205-2-ojeda@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/jiffies.h | 2 +-
+ kernel/time/time.c      | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
+index 5e13f801c9021..3778e26f7b14c 100644
+--- a/include/linux/jiffies.h
++++ b/include/linux/jiffies.h
+@@ -349,7 +349,7 @@ static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+  * - all other values are converted to jiffies by either multiplying
+  *   the input value by a factor or dividing it with a factor and
+  *   handling any 32-bit overflows.
+- *   for the details see __msecs_to_jiffies()
++ *   for the details see _msecs_to_jiffies()
+  *
+  * msecs_to_jiffies() checks for the passed in value being a constant
+  * via __builtin_constant_p() allowing gcc to eliminate most of the
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 3985b2b32d083..483f8a3e24d0c 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -539,7 +539,7 @@ EXPORT_SYMBOL(ns_to_timespec64);
+  * - all other values are converted to jiffies by either multiplying
+  *   the input value by a factor or dividing it with a factor and
+  *   handling any 32-bit overflows.
+- *   for the details see __msecs_to_jiffies()
++ *   for the details see _msecs_to_jiffies()
+  *
+  * msecs_to_jiffies() checks for the passed in value being a constant
+  * via __builtin_constant_p() allowing gcc to eliminate most of the
+-- 
+2.43.0
+
diff --git a/queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch b/queue-5.10/tpm-fix-signed-unsigned-bug-when-checking-event-logs.patch
new file mode 100644 (file)
index 0000000..fc9139b
--- /dev/null
@@ -0,0 +1,83 @@
+From e41f4d728dc2387fb2e126353359772ecd0ff42d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 19:19:51 -0400
+Subject: tpm: fix signed/unsigned bug when checking event logs
+
+From: Gregory Price <gourry@gourry.net>
+
+[ Upstream commit e6d654e9f5a97742cfe794b1c4bb5d3fb2d25e98 ]
+
+A prior bugfix that fixes a signed/unsigned error causes
+another signed unsigned error.
+
+A situation where log_tbl->size is invalid can cause the
+size passed to memblock_reserve to become negative.
+
+log_size from the main event log is an unsigned int, and
+the code reduces to the following
+
+u64 value = (int)unsigned_value;
+
+This results in sign extension, and the value sent to
+memblock_reserve becomes effectively negative.
+
+Fixes: be59d57f9806 ("efi/tpm: Fix sanity check of unsigned tbl_size being less than zero")
+Signed-off-by: Gregory Price <gourry@gourry.net>
+Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/tpm.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c
+index e8d69bd548f3f..9c3613e6af158 100644
+--- a/drivers/firmware/efi/tpm.c
++++ b/drivers/firmware/efi/tpm.c
+@@ -40,7 +40,8 @@ int __init efi_tpm_eventlog_init(void)
+ {
+       struct linux_efi_tpm_eventlog *log_tbl;
+       struct efi_tcg2_final_events_table *final_tbl;
+-      int tbl_size;
++      unsigned int tbl_size;
++      int final_tbl_size;
+       int ret = 0;
+       if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) {
+@@ -80,26 +81,26 @@ int __init efi_tpm_eventlog_init(void)
+               goto out;
+       }
+-      tbl_size = 0;
++      final_tbl_size = 0;
+       if (final_tbl->nr_events != 0) {
+               void *events = (void *)efi.tpm_final_log
+                               + sizeof(final_tbl->version)
+                               + sizeof(final_tbl->nr_events);
+-              tbl_size = tpm2_calc_event_log_size(events,
+-                                                  final_tbl->nr_events,
+-                                                  log_tbl->log);
++              final_tbl_size = tpm2_calc_event_log_size(events,
++                                                        final_tbl->nr_events,
++                                                        log_tbl->log);
+       }
+-      if (tbl_size < 0) {
++      if (final_tbl_size < 0) {
+               pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
+               ret = -EINVAL;
+               goto out_calc;
+       }
+       memblock_reserve(efi.tpm_final_log,
+-                       tbl_size + sizeof(*final_tbl));
+-      efi_tpm_final_log_size = tbl_size;
++                       final_tbl_size + sizeof(*final_tbl));
++      efi_tpm_final_log_size = final_tbl_size;
+ out_calc:
+       early_memunmap(final_tbl, sizeof(*final_tbl));
+-- 
+2.43.0
+
diff --git a/queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch b/queue-5.10/trace-trace_event_perf-remove-duplicate-samples-on-t.patch
new file mode 100644 (file)
index 0000000..2afb88b
--- /dev/null
@@ -0,0 +1,83 @@
+From 6e99234923ab7be15830c0a961633c304763e5e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 03:13:47 +0100
+Subject: trace/trace_event_perf: remove duplicate samples on the first
+ tracepoint event
+
+From: Levi Yun <yeoreum.yun@arm.com>
+
+[ Upstream commit afe5960dc208fe069ddaaeb0994d857b24ac19d1 ]
+
+When a tracepoint event is created with attr.freq = 1,
+'hwc->period_left' is not initialized correctly. As a result,
+in the perf_swevent_overflow() function, when the first time the event occurs,
+it calculates the event overflow and the perf_swevent_set_period() returns 3,
+this leads to the event are recorded for three duplicate times.
+
+Step to reproduce:
+    1. Enable the tracepoint event & starting tracing
+         $ echo 1 > /sys/kernel/tracing/events/module/module_free
+         $ echo 1 > /sys/kernel/tracing/tracing_on
+
+    2. Record with perf
+         $ perf record -a --strict-freq -F 1 -e "module:module_free"
+
+    3. Trigger module_free event.
+         $ modprobe -i sunrpc
+         $ modprobe -r sunrpc
+
+Result:
+     - Trace pipe result:
+         $ cat trace_pipe
+         modprobe-174509  [003] .....  6504.868896: module_free: sunrpc
+
+     - perf sample:
+         modprobe  174509 [003]  6504.868980: module:module_free: sunrpc
+         modprobe  174509 [003]  6504.868980: module:module_free: sunrpc
+         modprobe  174509 [003]  6504.868980: module:module_free: sunrpc
+
+By setting period_left via perf_swevent_set_period() as other sw_event did,
+This problem could be solved.
+
+After patch:
+     - Trace pipe result:
+         $ cat trace_pipe
+         modprobe 1153096 [068] 613468.867774: module:module_free: xfs
+
+     - perf sample
+         modprobe 1153096 [068] 613468.867794: module:module_free: xfs
+
+Link: https://lore.kernel.org/20240913021347.595330-1-yeoreum.yun@arm.com
+Fixes: bd2b5b12849a ("perf_counter: More aggressive frequency adjustment")
+Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_event_perf.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
+index eb81ad523a553..b3a863c10c0a7 100644
+--- a/kernel/trace/trace_event_perf.c
++++ b/kernel/trace/trace_event_perf.c
+@@ -355,10 +355,16 @@ void perf_uprobe_destroy(struct perf_event *p_event)
+ int perf_trace_add(struct perf_event *p_event, int flags)
+ {
+       struct trace_event_call *tp_event = p_event->tp_event;
++      struct hw_perf_event *hwc = &p_event->hw;
+       if (!(flags & PERF_EF_START))
+               p_event->hw.state = PERF_HES_STOPPED;
++      if (is_sampling_event(p_event)) {
++              hwc->last_period = hwc->sample_period;
++              perf_swevent_set_period(p_event);
++      }
++
+       /*
+        * If TRACE_REG_PERF_ADD returns false; no custom action was performed
+        * and we need to take the default action of enqueueing our event on
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-chaoskey-fail-open-after-removal.patch b/queue-5.10/usb-chaoskey-fail-open-after-removal.patch
new file mode 100644 (file)
index 0000000..53d73a8
--- /dev/null
@@ -0,0 +1,146 @@
+From 63240ff71145aff1c3d12f0257b5014a60786578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Oct 2024 15:21:41 +0200
+Subject: USB: chaoskey: fail open after removal
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 422dc0a4d12d0b80dd3aab3fe5943f665ba8f041 ]
+
+chaoskey_open() takes the lock only to increase the
+counter of openings. That means that the mutual exclusion
+with chaoskey_disconnect() cannot prevent an increase
+of the counter and chaoskey_open() returning a success.
+
+If that race is hit, chaoskey_disconnect() will happily
+free all resources associated with the device after
+it has dropped the lock, as it has read the counter
+as zero.
+
+To prevent this race chaoskey_open() has to check
+the presence of the device under the lock.
+However, the current per device lock cannot be used,
+because it is a part of the data structure to be
+freed. Hence an additional global mutex is needed.
+The issue is as old as the driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Reported-by: syzbot+422188bce66e76020e55@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=422188bce66e76020e55
+Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)")
+Rule: add
+Link: https://lore.kernel.org/stable/20241002132201.552578-1-oneukum%40suse.com
+Link: https://lore.kernel.org/r/20241002132201.552578-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/misc/chaoskey.c | 35 ++++++++++++++++++++++++-----------
+ 1 file changed, 24 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 87067c3d6109b..32fa7fd50c380 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -27,6 +27,8 @@ static struct usb_class_driver chaoskey_class;
+ static int chaoskey_rng_read(struct hwrng *rng, void *data,
+                            size_t max, bool wait);
++static DEFINE_MUTEX(chaoskey_list_lock);
++
+ #define usb_dbg(usb_if, format, arg...) \
+       dev_dbg(&(usb_if)->dev, format, ## arg)
+@@ -231,6 +233,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+       if (dev->hwrng_registered)
+               hwrng_unregister(&dev->hwrng);
++      mutex_lock(&chaoskey_list_lock);
+       usb_deregister_dev(interface, &chaoskey_class);
+       usb_set_intfdata(interface, NULL);
+@@ -245,6 +248,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+       } else
+               mutex_unlock(&dev->lock);
++      mutex_unlock(&chaoskey_list_lock);
+       usb_dbg(interface, "disconnect done");
+ }
+@@ -252,6 +256,7 @@ static int chaoskey_open(struct inode *inode, struct file *file)
+ {
+       struct chaoskey *dev;
+       struct usb_interface *interface;
++      int rv = 0;
+       /* get the interface from minor number and driver information */
+       interface = usb_find_interface(&chaoskey_driver, iminor(inode));
+@@ -267,18 +272,23 @@ static int chaoskey_open(struct inode *inode, struct file *file)
+       }
+       file->private_data = dev;
++      mutex_lock(&chaoskey_list_lock);
+       mutex_lock(&dev->lock);
+-      ++dev->open;
++      if (dev->present)
++              ++dev->open;
++      else
++              rv = -ENODEV;
+       mutex_unlock(&dev->lock);
++      mutex_unlock(&chaoskey_list_lock);
+-      usb_dbg(interface, "open success");
+-      return 0;
++      return rv;
+ }
+ static int chaoskey_release(struct inode *inode, struct file *file)
+ {
+       struct chaoskey *dev = file->private_data;
+       struct usb_interface *interface;
++      int rv = 0;
+       if (dev == NULL)
+               return -ENODEV;
+@@ -287,14 +297,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+       usb_dbg(interface, "release");
++      mutex_lock(&chaoskey_list_lock);
+       mutex_lock(&dev->lock);
+       usb_dbg(interface, "open count at release is %d", dev->open);
+       if (dev->open <= 0) {
+               usb_dbg(interface, "invalid open count (%d)", dev->open);
+-              mutex_unlock(&dev->lock);
+-              return -ENODEV;
++              rv = -ENODEV;
++              goto bail;
+       }
+       --dev->open;
+@@ -303,13 +314,15 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+               if (dev->open == 0) {
+                       mutex_unlock(&dev->lock);
+                       chaoskey_free(dev);
+-              } else
+-                      mutex_unlock(&dev->lock);
+-      } else
+-              mutex_unlock(&dev->lock);
+-
++                      goto destruction;
++              }
++      }
++bail:
++      mutex_unlock(&dev->lock);
++destruction:
++      mutex_lock(&chaoskey_list_lock);
+       usb_dbg(interface, "release success");
+-      return 0;
++      return rv;
+ }
+ static void chaos_read_callback(struct urb *urb)
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch b/queue-5.10/usb-chaoskey-fix-possible-deadlock-chaoskey_list_loc.patch
new file mode 100644 (file)
index 0000000..a8af459
--- /dev/null
@@ -0,0 +1,154 @@
+From a9777dd9f357252360e83c5418a92955cd7e8c3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 22:52:07 +0800
+Subject: USB: chaoskey: Fix possible deadlock chaoskey_list_lock
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit d73dc7b182be4238b75278bfae16afb4c5564a58 ]
+
+[Syzbot reported two possible deadlocks]
+The first possible deadlock is:
+WARNING: possible recursive locking detected
+6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted
+--------------------------------------------
+syz-executor363/2651 is trying to acquire lock:
+ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x15d/0x2c0 drivers/usb/misc/chaoskey.c:322
+
+but task is already holding lock:
+ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_release+0x7f/0x2c0 drivers/usb/misc/chaoskey.c:299
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+       CPU0
+       ----
+  lock(chaoskey_list_lock);
+  lock(chaoskey_list_lock);
+
+ *** DEADLOCK ***
+
+The second possible deadlock is:
+WARNING: possible circular locking dependency detected
+6.12.0-rc1-syzkaller-00027-g4a9fe2a8ac53 #0 Not tainted
+------------------------------------------------------
+kworker/0:2/804 is trying to acquire lock:
+ffffffff899dadb0 (minor_rwsem){++++}-{3:3}, at: usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186
+
+but task is already holding lock:
+ffffffff89b120e8 (chaoskey_list_lock){+.+.}-{3:3}, at: chaoskey_disconnect+0xa8/0x2a0 drivers/usb/misc/chaoskey.c:235
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #1 (chaoskey_list_lock){+.+.}-{3:3}:
+       __mutex_lock_common kernel/locking/mutex.c:608 [inline]
+       __mutex_lock+0x175/0x9c0 kernel/locking/mutex.c:752
+       chaoskey_open+0xdd/0x220 drivers/usb/misc/chaoskey.c:274
+       usb_open+0x186/0x220 drivers/usb/core/file.c:47
+       chrdev_open+0x237/0x6a0 fs/char_dev.c:414
+       do_dentry_open+0x6cb/0x1390 fs/open.c:958
+       vfs_open+0x82/0x3f0 fs/open.c:1088
+       do_open fs/namei.c:3774 [inline]
+       path_openat+0x1e6a/0x2d60 fs/namei.c:3933
+       do_filp_open+0x1dc/0x430 fs/namei.c:3960
+       do_sys_openat2+0x17a/0x1e0 fs/open.c:1415
+       do_sys_open fs/open.c:1430 [inline]
+       __do_sys_openat fs/open.c:1446 [inline]
+       __se_sys_openat fs/open.c:1441 [inline]
+       __x64_sys_openat+0x175/0x210 fs/open.c:1441
+       do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+       do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
+       entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+-> #0 (minor_rwsem){++++}-{3:3}:
+       check_prev_add kernel/locking/lockdep.c:3161 [inline]
+       check_prevs_add kernel/locking/lockdep.c:3280 [inline]
+       validate_chain kernel/locking/lockdep.c:3904 [inline]
+       __lock_acquire+0x250b/0x3ce0 kernel/locking/lockdep.c:5202
+       lock_acquire.part.0+0x11b/0x380 kernel/locking/lockdep.c:5825
+       down_write+0x93/0x200 kernel/locking/rwsem.c:1577
+       usb_deregister_dev+0x7c/0x1e0 drivers/usb/core/file.c:186
+       chaoskey_disconnect+0xb7/0x2a0 drivers/usb/misc/chaoskey.c:236
+       usb_unbind_interface+0x1e8/0x970 drivers/usb/core/driver.c:461
+       device_remove drivers/base/dd.c:569 [inline]
+       device_remove+0x122/0x170 drivers/base/dd.c:561
+       __device_release_driver drivers/base/dd.c:1273 [inline]
+       device_release_driver_internal+0x44a/0x610 drivers/base/dd.c:1296
+       bus_remove_device+0x22f/0x420 drivers/base/bus.c:576
+       device_del+0x396/0x9f0 drivers/base/core.c:3864
+       usb_disable_device+0x36c/0x7f0 drivers/usb/core/message.c:1418
+       usb_disconnect+0x2e1/0x920 drivers/usb/core/hub.c:2304
+       hub_port_connect drivers/usb/core/hub.c:5361 [inline]
+       hub_port_connect_change drivers/usb/core/hub.c:5661 [inline]
+       port_event drivers/usb/core/hub.c:5821 [inline]
+       hub_event+0x1bed/0x4f40 drivers/usb/core/hub.c:5903
+       process_one_work+0x9c5/0x1ba0 kernel/workqueue.c:3229
+       process_scheduled_works kernel/workqueue.c:3310 [inline]
+       worker_thread+0x6c8/0xf00 kernel/workqueue.c:3391
+       kthread+0x2c1/0x3a0 kernel/kthread.c:389
+       ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
+       ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+
+other info that might help us debug this:
+
+ Possible unsafe locking scenario:
+
+       CPU0                    CPU1
+       ----                    ----
+  lock(chaoskey_list_lock);
+                               lock(minor_rwsem);
+                               lock(chaoskey_list_lock);
+  lock(minor_rwsem);
+
+ *** DEADLOCK ***
+[Analysis]
+The first is AA lock, it because wrong logic, it need a unlock.
+The second is AB lock, it needs to rearrange the order of lock usage.
+
+Fixes: 422dc0a4d12d ("USB: chaoskey: fail open after removal")
+Reported-by: syzbot+685e14d04fe35692d3bc@syzkaller.appspotmail.com
+Reported-by: syzbot+1f8ca5ee82576ec01f12@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=685e14d04fe35692d3bc
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Tested-by: syzbot+685e14d04fe35692d3bc@syzkaller.appspotmail.com
+Reported-by: syzbot+5f1ce62e956b7b19610e@syzkaller.appspotmail.com
+Tested-by: syzbot+5f1ce62e956b7b19610e@syzkaller.appspotmail.com
+Tested-by: syzbot+1f8ca5ee82576ec01f12@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/tencent_84EB865C89862EC22EE94CB3A7C706C59206@qq.com
+Cc: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/misc/chaoskey.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 32fa7fd50c380..d99d424c05a7a 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -233,10 +233,10 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+       if (dev->hwrng_registered)
+               hwrng_unregister(&dev->hwrng);
+-      mutex_lock(&chaoskey_list_lock);
+       usb_deregister_dev(interface, &chaoskey_class);
+       usb_set_intfdata(interface, NULL);
++      mutex_lock(&chaoskey_list_lock);
+       mutex_lock(&dev->lock);
+       dev->present = false;
+@@ -320,7 +320,7 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+ bail:
+       mutex_unlock(&dev->lock);
+ destruction:
+-      mutex_lock(&chaoskey_list_lock);
++      mutex_unlock(&chaoskey_list_lock);
+       usb_dbg(interface, "release success");
+       return rv;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch b/queue-5.10/usb-using-mutex-lock-and-supporting-o_nonblock-flag-.patch
new file mode 100644 (file)
index 0000000..7f1ada2
--- /dev/null
@@ -0,0 +1,130 @@
+From bd9d187e33d3a1ea250d8f9f9aaf0b45711fb5dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Sep 2024 19:34:03 +0900
+Subject: usb: using mutex lock and supporting O_NONBLOCK flag in
+ iowarrior_read()
+
+From: Jeongjun Park <aha310510@gmail.com>
+
+[ Upstream commit 44feafbaa66ec86232b123bb8437a6a262442025 ]
+
+iowarrior_read() uses the iowarrior dev structure, but does not use any
+lock on the structure. This can cause various bugs including data-races,
+so it is more appropriate to use a mutex lock to safely protect the
+iowarrior dev structure. When using a mutex lock, you should split the
+branch to prevent blocking when the O_NONBLOCK flag is set.
+
+In addition, it is unnecessary to check for NULL on the iowarrior dev
+structure obtained by reading file->private_data. Therefore, it is
+better to remove the check.
+
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Link: https://lore.kernel.org/r/20240919103403.3986-1-aha310510@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/misc/iowarrior.c | 46 ++++++++++++++++++++++++++++--------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
+index 51a5d626134c3..c06238ce70eaa 100644
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -277,28 +277,45 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+       struct iowarrior *dev;
+       int read_idx;
+       int offset;
++      int retval;
+       dev = file->private_data;
++      if (file->f_flags & O_NONBLOCK) {
++              retval = mutex_trylock(&dev->mutex);
++              if (!retval)
++                      return -EAGAIN;
++      } else {
++              retval = mutex_lock_interruptible(&dev->mutex);
++              if (retval)
++                      return -ERESTARTSYS;
++      }
++
+       /* verify that the device wasn't unplugged */
+-      if (!dev || !dev->present)
+-              return -ENODEV;
++      if (!dev->present) {
++              retval = -ENODEV;
++              goto exit;
++      }
+       dev_dbg(&dev->interface->dev, "minor %d, count = %zd\n",
+               dev->minor, count);
+       /* read count must be packet size (+ time stamp) */
+       if ((count != dev->report_size)
+-          && (count != (dev->report_size + 1)))
+-              return -EINVAL;
++          && (count != (dev->report_size + 1))) {
++              retval = -EINVAL;
++              goto exit;
++      }
+       /* repeat until no buffer overrun in callback handler occur */
+       do {
+               atomic_set(&dev->overflow_flag, 0);
+               if ((read_idx = read_index(dev)) == -1) {
+                       /* queue empty */
+-                      if (file->f_flags & O_NONBLOCK)
+-                              return -EAGAIN;
++                      if (file->f_flags & O_NONBLOCK) {
++                              retval = -EAGAIN;
++                              goto exit;
++                      }
+                       else {
+                               //next line will return when there is either new data, or the device is unplugged
+                               int r = wait_event_interruptible(dev->read_wait,
+@@ -309,28 +326,37 @@ static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+                                                                 -1));
+                               if (r) {
+                                       //we were interrupted by a signal
+-                                      return -ERESTART;
++                                      retval = -ERESTART;
++                                      goto exit;
+                               }
+                               if (!dev->present) {
+                                       //The device was unplugged
+-                                      return -ENODEV;
++                                      retval = -ENODEV;
++                                      goto exit;
+                               }
+                               if (read_idx == -1) {
+                                       // Can this happen ???
+-                                      return 0;
++                                      retval = 0;
++                                      goto exit;
+                               }
+                       }
+               }
+               offset = read_idx * (dev->report_size + 1);
+               if (copy_to_user(buffer, dev->read_queue + offset, count)) {
+-                      return -EFAULT;
++                      retval = -EFAULT;
++                      goto exit;
+               }
+       } while (atomic_read(&dev->overflow_flag));
+       read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+       atomic_set(&dev->read_idx, read_idx);
++      mutex_unlock(&dev->mutex);
+       return count;
++
++exit:
++      mutex_unlock(&dev->mutex);
++      return retval;
+ }
+ /*
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch b/queue-5.10/usb-yurex-make-waiting-on-yurex_write-interruptible.patch
new file mode 100644 (file)
index 0000000..d08d7c6
--- /dev/null
@@ -0,0 +1,68 @@
+From 606105af8fc6671a35ecaef9702880400957289e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Sep 2024 10:43:45 +0200
+Subject: usb: yurex: make waiting on yurex_write interruptible
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit e0aa9614ab0fd35b404e4b16ebe879f9fc152591 ]
+
+The IO yurex_write() needs to wait for in order to have a device
+ready for writing again can take a long time time.
+Consequently the sleep is done in an interruptible state.
+Therefore others waiting for yurex_write() itself to finish should
+use mutex_lock_interruptible.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Fixes: 6bc235a2e24a5 ("USB: add driver for Meywa-Denki & Kayac YUREX")
+Rule: add
+Link: https://lore.kernel.org/stable/20240924084415.300557-1-oneukum%40suse.com
+Link: https://lore.kernel.org/r/20240924084415.300557-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/misc/iowarrior.c | 4 ----
+ drivers/usb/misc/yurex.c     | 5 ++++-
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
+index c06238ce70eaa..2a0036d8fc292 100644
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -915,7 +915,6 @@ static int iowarrior_probe(struct usb_interface *interface,
+ static void iowarrior_disconnect(struct usb_interface *interface)
+ {
+       struct iowarrior *dev = usb_get_intfdata(interface);
+-      int minor = dev->minor;
+       usb_deregister_dev(interface, &iowarrior_class);
+@@ -939,9 +938,6 @@ static void iowarrior_disconnect(struct usb_interface *interface)
+               mutex_unlock(&dev->mutex);
+               iowarrior_delete(dev);
+       }
+-
+-      dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
+-               minor - IOWARRIOR_MINOR_BASE);
+ }
+ /* usb specific object needed to register this driver with the usb subsystem */
+diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
+index 8bc7c683bf836..36192fbf915a6 100644
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -440,7 +440,10 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
+       if (count == 0)
+               goto error;
+-      mutex_lock(&dev->io_mutex);
++      retval = mutex_lock_interruptible(&dev->io_mutex);
++      if (retval < 0)
++              return -EINTR;
++
+       if (dev->disconnected) {                /* already disconnected */
+               mutex_unlock(&dev->io_mutex);
+               retval = -ENODEV;
+-- 
+2.43.0
+
diff --git a/queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch b/queue-5.10/vdpa-mlx5-fix-suboptimal-range-on-iotlb-iteration.patch
new file mode 100644 (file)
index 0000000..c9ea25d
--- /dev/null
@@ -0,0 +1,53 @@
+From 238fd661ec829672734ebe68c1abe2711154702b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Oct 2024 16:40:40 +0300
+Subject: vdpa/mlx5: Fix suboptimal range on iotlb iteration
+
+From: Si-Wei Liu <si-wei.liu@oracle.com>
+
+[ Upstream commit 35025963326e44d8bced3eecd42d2f040f4f0024 ]
+
+The starting iova address to iterate iotlb map entry within a range
+was set to an irrelevant value when passing to the itree_next()
+iterator, although luckily it doesn't affect the outcome of finding
+out the granule of the smallest iotlb map size. Fix the code to make
+it consistent with the following for-loop.
+
+Fixes: 94abbccdf291 ("vdpa/mlx5: Add shared memory registration code")
+Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
+Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
+Message-Id: <20241021134040.975221-3-dtatulea@nvidia.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/mlx5/core/mr.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
+index 48489beb6e0a7..4615f827cd0cb 100644
+--- a/drivers/vdpa/mlx5/core/mr.c
++++ b/drivers/vdpa/mlx5/core/mr.c
+@@ -226,7 +226,6 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+       unsigned long lgcd = 0;
+       int log_entity_size;
+       unsigned long size;
+-      u64 start = 0;
+       int err;
+       struct page *pg;
+       unsigned int nsg;
+@@ -237,10 +236,9 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mr
+       struct device *dma = mvdev->mdev->device;
+       for (map = vhost_iotlb_itree_first(iotlb, mr->start, mr->end - 1);
+-           map; map = vhost_iotlb_itree_next(map, start, mr->end - 1)) {
++           map; map = vhost_iotlb_itree_next(map, mr->start, mr->end - 1)) {
+               size = maplen(map, mr);
+               lgcd = gcd(lgcd, size);
+-              start += size;
+       }
+       log_entity_size = ilog2(lgcd);
+-- 
+2.43.0
+
diff --git a/queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch b/queue-5.10/vfio-pci-properly-hide-first-in-list-pcie-extended-c.patch
new file mode 100644 (file)
index 0000000..4cab782
--- /dev/null
@@ -0,0 +1,115 @@
+From 854687013d12fc0733e08c640a55eeea9316476b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Nov 2024 16:27:39 +0200
+Subject: vfio/pci: Properly hide first-in-list PCIe extended capability
+
+From: Avihai Horon <avihaih@nvidia.com>
+
+[ Upstream commit fe4bf8d0b6716a423b16495d55b35d3fe515905d ]
+
+There are cases where a PCIe extended capability should be hidden from
+the user. For example, an unknown capability (i.e., capability with ID
+greater than PCI_EXT_CAP_ID_MAX) or a capability that is intentionally
+chosen to be hidden from the user.
+
+Hiding a capability is done by virtualizing and modifying the 'Next
+Capability Offset' field of the previous capability so it points to the
+capability after the one that should be hidden.
+
+The special case where the first capability in the list should be hidden
+is handled differently because there is no previous capability that can
+be modified. In this case, the capability ID and version are zeroed
+while leaving the next pointer intact. This hides the capability and
+leaves an anchor for the rest of the capability list.
+
+However, today, hiding the first capability in the list is not done
+properly if the capability is unknown, as struct
+vfio_pci_core_device->pci_config_map is set to the capability ID during
+initialization but the capability ID is not properly checked later when
+used in vfio_config_do_rw(). This leads to the following warning [1] and
+to an out-of-bounds access to ecap_perms array.
+
+Fix it by checking cap_id in vfio_config_do_rw(), and if it is greater
+than PCI_EXT_CAP_ID_MAX, use an alternative struct perm_bits for direct
+read only access instead of the ecap_perms array.
+
+Note that this is safe since the above is the only case where cap_id can
+exceed PCI_EXT_CAP_ID_MAX (except for the special capabilities, which
+are already checked before).
+
+[1]
+
+WARNING: CPU: 118 PID: 5329 at drivers/vfio/pci/vfio_pci_config.c:1900 vfio_pci_config_rw+0x395/0x430 [vfio_pci_core]
+CPU: 118 UID: 0 PID: 5329 Comm: simx-qemu-syste Not tainted 6.12.0+ #1
+(snip)
+Call Trace:
+ <TASK>
+ ? show_regs+0x69/0x80
+ ? __warn+0x8d/0x140
+ ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core]
+ ? report_bug+0x18f/0x1a0
+ ? handle_bug+0x63/0xa0
+ ? exc_invalid_op+0x19/0x70
+ ? asm_exc_invalid_op+0x1b/0x20
+ ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core]
+ ? vfio_pci_config_rw+0x244/0x430 [vfio_pci_core]
+ vfio_pci_rw+0x101/0x1b0 [vfio_pci_core]
+ vfio_pci_core_read+0x1d/0x30 [vfio_pci_core]
+ vfio_device_fops_read+0x27/0x40 [vfio]
+ vfs_read+0xbd/0x340
+ ? vfio_device_fops_unl_ioctl+0xbb/0x740 [vfio]
+ ? __rseq_handle_notify_resume+0xa4/0x4b0
+ __x64_sys_pread64+0x96/0xc0
+ x64_sys_call+0x1c3d/0x20d0
+ do_syscall_64+0x4d/0x120
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 89e1f7d4c66d ("vfio: Add PCI device driver")
+Signed-off-by: Avihai Horon <avihaih@nvidia.com>
+Reviewed-by: Yi Liu <yi.l.liu@intel.com>
+Tested-by: Yi Liu <yi.l.liu@intel.com>
+Link: https://lore.kernel.org/r/20241124142739.21698-1-avihaih@nvidia.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/vfio_pci_config.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
+index 47f21a6ca7fe9..401c3c776c6b5 100644
+--- a/drivers/vfio/pci/vfio_pci_config.c
++++ b/drivers/vfio/pci/vfio_pci_config.c
+@@ -312,6 +312,10 @@ static int vfio_virt_config_read(struct vfio_pci_device *vdev, int pos,
+       return count;
+ }
++static struct perm_bits direct_ro_perms = {
++      .readfn = vfio_direct_config_read,
++};
++
+ /* Default capability regions to read-only, no-virtualization */
+ static struct perm_bits cap_perms[PCI_CAP_ID_MAX + 1] = {
+       [0 ... PCI_CAP_ID_MAX] = { .readfn = vfio_direct_config_read }
+@@ -1840,9 +1844,17 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf,
+               cap_start = *ppos;
+       } else {
+               if (*ppos >= PCI_CFG_SPACE_SIZE) {
+-                      WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX);
++                      /*
++                       * We can get a cap_id that exceeds PCI_EXT_CAP_ID_MAX
++                       * if we're hiding an unknown capability at the start
++                       * of the extended capability list.  Use default, ro
++                       * access, which will virtualize the id and next values.
++                       */
++                      if (cap_id > PCI_EXT_CAP_ID_MAX)
++                              perm = &direct_ro_perms;
++                      else
++                              perm = &ecap_perms[cap_id];
+-                      perm = &ecap_perms[cap_id];
+                       cap_start = vfio_find_cap_start(vdev, *ppos);
+               } else {
+                       WARN_ON(cap_id > PCI_CAP_ID_MAX);
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch
new file mode 100644 (file)
index 0000000..a67fb90
--- /dev/null
@@ -0,0 +1,52 @@
+From ab9a1c5fbe3ee180b2f164108ca2477fb0ea4e21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jul 2024 10:03:43 +0800
+Subject: wifi: ath10k: fix invalid VHT parameters in
+ supported_vht_mcs_rate_nss1
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit d50886b27850447d90c0cd40c725238097909d1e ]
+
+In supported_vht_mcs_rate_nss1, the rate for MCS9 & VHT20 is defined as
+{780,  867}, this does not align with firmware's definition and therefore
+fails the verification in ath10k_mac_get_rate_flags_vht():
+
+       invalid vht params rate 960 100kbps nss 1 mcs 9
+
+Change it to {865,  960} to align with firmware, so this issue could be
+fixed.
+
+Since ath10k_hw_params::supports_peer_stats_info is enabled only for
+QCA6174, this change does not affect other chips.
+
+Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1
+
+Fixes: 3344b99d69ab ("ath10k: add bitrate parse for peer stats info")
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Closes: https://lore.kernel.org/lkml/fba24cd3-4a1e-4072-8585-8402272788ff@molgen.mpg.de/
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240711020344.98040-2-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 15f02bf23e9bd..2bf3e66c83f63 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -8955,7 +8955,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss1[
+       {6,  {2633, 2925}, {1215, 1350}, {585,  650} },
+       {7,  {2925, 3250}, {1350, 1500}, {650,  722} },
+       {8,  {3510, 3900}, {1620, 1800}, {780,  867} },
+-      {9,  {3900, 4333}, {1800, 2000}, {780,  867} }
++      {9,  {3900, 4333}, {1800, 2000}, {865,  960} }
+ };
+ /*MCS parameters with Nss = 2 */
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150 b/queue-5.10/wifi-ath10k-fix-invalid-vht-parameters-in-supported_.patch-19150
new file mode 100644 (file)
index 0000000..edb17ef
--- /dev/null
@@ -0,0 +1,56 @@
+From dc84a9a07f72440dbeb5e3f65b4b2d9a764fdadc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jul 2024 10:03:44 +0800
+Subject: wifi: ath10k: fix invalid VHT parameters in
+ supported_vht_mcs_rate_nss2
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 52db16ec5bae7bd027804265b968259d1a6c3970 ]
+
+In supported_vht_mcs_rate_nss2, the rate for MCS9 & VHT20 is defined as
+{1560, 1733}, this does not align with firmware's definition and therefore
+fails the verification in ath10k_mac_get_rate_flags_vht():
+
+       invalid vht params rate 1730 100kbps nss 2 mcs 9
+
+and:
+
+       invalid vht params rate 1920 100kbps nss 2 mcs 9
+
+Change it to {1730,  1920} to align with firmware to fix the issue.
+
+Since ath10k_hw_params::supports_peer_stats_info is enabled only for
+QCA6174, this change does not affect other chips.
+
+Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1
+
+Fixes: 3344b99d69ab ("ath10k: add bitrate parse for peer stats info")
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Closes: https://lore.kernel.org/lkml/fba24cd3-4a1e-4072-8585-8402272788ff@molgen.mpg.de/
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Tested-by: Paul Menzel <pmenzel@molgen.mpg.de> # Dell XPS 13 9360
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240711020344.98040-3-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/mac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 2bf3e66c83f63..323b6763cb0f5 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -8970,7 +8970,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss2[
+       {6,  {5265, 5850}, {2430, 2700}, {1170, 1300} },
+       {7,  {5850, 6500}, {2700, 3000}, {1300, 1444} },
+       {8,  {7020, 7800}, {3240, 3600}, {1560, 1733} },
+-      {9,  {7800, 8667}, {3600, 4000}, {1560, 1733} }
++      {9,  {7800, 8667}, {3600, 4000}, {1730, 1920} }
+ };
+ static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch b/queue-5.10/wifi-ath9k-add-range-check-for-conn_rsp_epid-in-htc_.patch
new file mode 100644 (file)
index 0000000..9fb1826
--- /dev/null
@@ -0,0 +1,61 @@
+From 2c123c9fce25c23cceb98fd94491c9add6681678 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Sep 2024 12:06:03 +0300
+Subject: wifi: ath9k: add range check for conn_rsp_epid in
+ htc_connect_service()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeongjun Park <aha310510@gmail.com>
+
+[ Upstream commit 8619593634cbdf5abf43f5714df49b04e4ef09ab ]
+
+I found the following bug in my fuzzer:
+
+  UBSAN: array-index-out-of-bounds in drivers/net/wireless/ath/ath9k/htc_hst.c:26:51
+  index 255 is out of range for type 'htc_endpoint [22]'
+  CPU: 0 UID: 0 PID: 8 Comm: kworker/0:0 Not tainted 6.11.0-rc6-dirty #14
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+  Workqueue: events request_firmware_work_func
+  Call Trace:
+   <TASK>
+   dump_stack_lvl+0x180/0x1b0
+   __ubsan_handle_out_of_bounds+0xd4/0x130
+   htc_issue_send.constprop.0+0x20c/0x230
+   ? _raw_spin_unlock_irqrestore+0x3c/0x70
+   ath9k_wmi_cmd+0x41d/0x610
+   ? mark_held_locks+0x9f/0xe0
+   ...
+
+Since this bug has been confirmed to be caused by insufficient verification
+of conn_rsp_epid, I think it would be appropriate to add a range check for
+conn_rsp_epid to htc_connect_service() to prevent the bug from occurring.
+
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240909103855.68006-1-aha310510@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc_hst.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index 99667aba289df..00dc97ac53b9d 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -294,6 +294,9 @@ int htc_connect_service(struct htc_target *target,
+               return -ETIMEDOUT;
+       }
++      if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX)
++              return -EINVAL;
++
+       *conn_rsp_epid = target->conn_rsp_epid;
+       return 0;
+ err:
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch b/queue-5.10/wifi-mwifiex-fix-memcpy-field-spanning-write-warning.patch
new file mode 100644 (file)
index 0000000..f0d9e0e
--- /dev/null
@@ -0,0 +1,56 @@
+From 9eb632efd38bd02c4dcf88a747a9ce399a226cf3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 01:20:54 +0300
+Subject: wifi: mwifiex: Fix memcpy() field-spanning write warning in
+ mwifiex_config_scan()
+
+From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
+
+[ Upstream commit d241a139c2e9f8a479f25c75ebd5391e6a448500 ]
+
+Replace one-element array with a flexible-array member in `struct
+mwifiex_ie_types_wildcard_ssid_params` to fix the following warning
+on a MT8173 Chromebook (mt8173-elm-hana):
+
+[  356.775250] ------------[ cut here ]------------
+[  356.784543] memcpy: detected field-spanning write (size 6) of single field "wildcard_ssid_tlv->ssid" at drivers/net/wireless/marvell/mwifiex/scan.c:904 (size 1)
+[  356.813403] WARNING: CPU: 3 PID: 742 at drivers/net/wireless/marvell/mwifiex/scan.c:904 mwifiex_scan_networks+0x4fc/0xf28 [mwifiex]
+
+The "(size 6)" above is exactly the length of the SSID of the network
+this device was connected to. The source of the warning looks like:
+
+    ssid_len = user_scan_in->ssid_list[i].ssid_len;
+    [...]
+    memcpy(wildcard_ssid_tlv->ssid,
+           user_scan_in->ssid_list[i].ssid, ssid_len);
+
+There is a #define WILDCARD_SSID_TLV_MAX_SIZE that uses sizeof() on this
+struct, but it already didn't account for the size of the one-element
+array, so it doesn't need to be changed.
+
+Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
+Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/20241007222301.24154-1-alpernebiyasak@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/fw.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
+index 284671618e9ce..50205b6ae4ca2 100644
+--- a/drivers/net/wireless/marvell/mwifiex/fw.h
++++ b/drivers/net/wireless/marvell/mwifiex/fw.h
+@@ -854,7 +854,7 @@ struct mwifiex_ietypes_chanstats {
+ struct mwifiex_ie_types_wildcard_ssid_params {
+       struct mwifiex_ie_types_header header;
+       u8 max_ssid_length;
+-      u8 ssid[1];
++      u8 ssid[];
+ } __packed;
+ #define TSF_DATA_SIZE            8
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/wifi-mwifiex-use-irqf_no_autoen-flag-in-request_irq.patch
new file mode 100644 (file)
index 0000000..de3a992
--- /dev/null
@@ -0,0 +1,48 @@
+From 8bf08be35238d0ab611908cbf76dcb9e9e4b3cf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 20:43:13 +0800
+Subject: wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 9a98dd48b6d834d7a3fe5e8e7b8c3a1d006f9685 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 853402a00823 ("mwifiex: Enable WoWLAN for both sdio and pcie")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/20240910124314.698896-3-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
+index b8b79fe50dbc2..6991bb0e8e9b6 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1600,7 +1600,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
+       }
+       ret = devm_request_irq(dev, adapter->irq_wakeup,
+-                             mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
++                             mwifiex_irq_wakeup_handler,
++                             IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
+                              "wifi_wake", adapter);
+       if (ret) {
+               dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
+@@ -1608,7 +1609,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
+               goto err_exit;
+       }
+-      disable_irq(adapter->irq_wakeup);
+       if (device_init_wakeup(dev, true)) {
+               dev_err(dev, "fail to init wakeup for mwifiex\n");
+               goto err_exit;
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch b/queue-5.10/wifi-p54-use-irqf_no_autoen-flag-in-request_irq.patch
new file mode 100644 (file)
index 0000000..828f450
--- /dev/null
@@ -0,0 +1,47 @@
+From e8b1d014971afd3c39c804119597221f28531275 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 20:43:12 +0800
+Subject: wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit bcd1371bd85e560ccc9159b7747f94bfe43b77a6 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: cd8d3d321285 ("p54spi: p54spi driver")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/20240910124314.698896-2-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/p54spi.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
+index cdb57819684ae..8a9168aac7281 100644
+--- a/drivers/net/wireless/intersil/p54/p54spi.c
++++ b/drivers/net/wireless/intersil/p54/p54spi.c
+@@ -623,7 +623,7 @@ static int p54spi_probe(struct spi_device *spi)
+       gpio_direction_input(p54spi_gpio_irq);
+       ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
+-                        p54spi_interrupt, 0, "p54spi",
++                        p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
+                         priv->spi);
+       if (ret < 0) {
+               dev_err(&priv->spi->dev, "request_irq() failed");
+@@ -632,8 +632,6 @@ static int p54spi_probe(struct spi_device *spi)
+       irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
+-      disable_irq(gpio_to_irq(p54spi_gpio_irq));
+-
+       INIT_WORK(&priv->work, p54spi_work);
+       init_completion(&priv->fw_comp);
+       INIT_LIST_HEAD(&priv->tx_pending);
+-- 
+2.43.0
+
diff --git a/queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch b/queue-5.10/wifi-wfx-fix-error-handling-in-wfx_core_init.patch
new file mode 100644 (file)
index 0000000..f08a50f
--- /dev/null
@@ -0,0 +1,60 @@
+From 9d1bff97c7febbfaf94093c47f849c0c0597aac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Oct 2024 17:04:53 +0800
+Subject: wifi: wfx: Fix error handling in wfx_core_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 3b88a9876779b55478a4dde867e73f7a100ffa23 ]
+
+The wfx_core_init() returns without checking the retval from
+sdio_register_driver().
+If the sdio_register_driver() failed, the module failed to install,
+leaving the wfx_spi_driver not unregistered.
+
+Fixes: a7a91ca5a23d ("staging: wfx: add infrastructure for new driver")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Reviewed-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/20241022090453.84679-1-yuancan@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/wfx/main.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
+index d5dacd5583c6e..5a54dd22fad53 100644
+--- a/drivers/staging/wfx/main.c
++++ b/drivers/staging/wfx/main.c
+@@ -477,10 +477,23 @@ static int __init wfx_core_init(void)
+ {
+       int ret = 0;
+-      if (IS_ENABLED(CONFIG_SPI))
++      if (IS_ENABLED(CONFIG_SPI)) {
+               ret = spi_register_driver(&wfx_spi_driver);
+-      if (IS_ENABLED(CONFIG_MMC) && !ret)
++              if (ret)
++                      goto out;
++      }
++      if (IS_ENABLED(CONFIG_MMC)) {
+               ret = sdio_register_driver(&wfx_sdio_driver);
++              if (ret)
++                      goto unregister_spi;
++      }
++
++      return 0;
++
++unregister_spi:
++      if (IS_ENABLED(CONFIG_SPI))
++              spi_unregister_driver(&wfx_spi_driver);
++out:
+       return ret;
+ }
+ module_init(wfx_core_init);
+-- 
+2.43.0
+
diff --git a/queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch b/queue-5.10/wireguard-selftests-load-nf_conntrack-if-not-present.patch
new file mode 100644 (file)
index 0000000..bb9c9e2
--- /dev/null
@@ -0,0 +1,40 @@
+From cbfb55799f480df5cb8092fa4cfaa5dcc2944493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Nov 2024 22:20:29 +0100
+Subject: wireguard: selftests: load nf_conntrack if not present
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 0290abc9860917f1ee8b58309c2bbd740a39ee8e ]
+
+Some distros may not load nf_conntrack by default, which will cause
+subsequent nf_conntrack sets to fail. Load this module if it is not
+already loaded.
+
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+[ Jason: add [[ -e ... ]] check so this works in the qemu harness. ]
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Link: https://patch.msgid.link/20241117212030.629159-4-Jason@zx2c4.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/wireguard/netns.sh | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh
+index 93e44410f170e..4732c23e35ee5 100755
+--- a/tools/testing/selftests/wireguard/netns.sh
++++ b/tools/testing/selftests/wireguard/netns.sh
+@@ -320,6 +320,7 @@ waitiface $netns1 vethc
+ waitiface $netns2 veths
+ n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
++[[ -e /proc/sys/net/netfilter/nf_conntrack_udp_timeout ]] || modprobe nf_conntrack
+ n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
+ n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
+ n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1
+-- 
+2.43.0
+
diff --git a/queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch b/queue-5.10/x86-barrier-do-not-serialize-msr-accesses-on-amd.patch
new file mode 100644 (file)
index 0000000..5eb90bf
--- /dev/null
@@ -0,0 +1,211 @@
+From 21268e7087ec47c8606767bec63dbe13d7e4fbbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 14:24:16 +0200
+Subject: x86/barrier: Do not serialize MSR accesses on AMD
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+commit 04c3024560d3a14acd18d0a51a1d0a89d29b7eb5 upstream.
+
+AMD does not have the requirement for a synchronization barrier when
+acccessing a certain group of MSRs. Do not incur that unnecessary
+penalty there.
+
+There will be a CPUID bit which explicitly states that a MFENCE is not
+needed. Once that bit is added to the APM, this will be extended with
+it.
+
+While at it, move to processor.h to avoid include hell. Untangling that
+file properly is a matter for another day.
+
+Some notes on the performance aspect of why this is relevant, courtesy
+of Kishon VijayAbraham <Kishon.VijayAbraham@amd.com>:
+
+On a AMD Zen4 system with 96 cores, a modified ipi-bench[1] on a VM
+shows x2AVIC IPI rate is 3% to 4% lower than AVIC IPI rate. The
+ipi-bench is modified so that the IPIs are sent between two vCPUs in the
+same CCX. This also requires to pin the vCPU to a physical core to
+prevent any latencies. This simulates the use case of pinning vCPUs to
+the thread of a single CCX to avoid interrupt IPI latency.
+
+In order to avoid run-to-run variance (for both x2AVIC and AVIC), the
+below configurations are done:
+
+  1) Disable Power States in BIOS (to prevent the system from going to
+     lower power state)
+
+  2) Run the system at fixed frequency 2500MHz (to prevent the system
+     from increasing the frequency when the load is more)
+
+With the above configuration:
+
+*) Performance measured using ipi-bench for AVIC:
+  Average Latency:  1124.98ns [Time to send IPI from one vCPU to another vCPU]
+
+  Cumulative throughput: 42.6759M/s [Total number of IPIs sent in a second from
+                                    48 vCPUs simultaneously]
+
+*) Performance measured using ipi-bench for x2AVIC:
+  Average Latency:  1172.42ns [Time to send IPI from one vCPU to another vCPU]
+
+  Cumulative throughput: 40.9432M/s [Total number of IPIs sent in a second from
+                                    48 vCPUs simultaneously]
+
+From above, x2AVIC latency is ~4% more than AVIC. However, the expectation is
+x2AVIC performance to be better or equivalent to AVIC. Upon analyzing
+the perf captures, it is observed significant time is spent in
+weak_wrmsr_fence() invoked by x2apic_send_IPI().
+
+With the fix to skip weak_wrmsr_fence()
+
+*) Performance measured using ipi-bench for x2AVIC:
+  Average Latency:  1117.44ns [Time to send IPI from one vCPU to another vCPU]
+
+  Cumulative throughput: 42.9608M/s [Total number of IPIs sent in a second from
+                                    48 vCPUs simultaneously]
+
+Comparing the performance of x2AVIC with and without the fix, it can be seen
+the performance improves by ~4%.
+
+Performance captured using an unmodified ipi-bench using the 'mesh-ipi' option
+with and without weak_wrmsr_fence() on a Zen4 system also showed significant
+performance improvement without weak_wrmsr_fence(). The 'mesh-ipi' option ignores
+CCX or CCD and just picks random vCPU.
+
+  Average throughput (10 iterations) with weak_wrmsr_fence(),
+        Cumulative throughput: 4933374 IPI/s
+
+  Average throughput (10 iterations) without weak_wrmsr_fence(),
+        Cumulative throughput: 6355156 IPI/s
+
+[1] https://github.com/bytedance/kvm-utils/tree/master/microbenchmark/ipi-bench
+
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20230622095212.20940-1-bp@alien8.de
+Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/barrier.h     | 18 ------------------
+ arch/x86/include/asm/cpufeatures.h |  1 +
+ arch/x86/include/asm/processor.h   | 18 ++++++++++++++++++
+ arch/x86/kernel/cpu/amd.c          |  3 +++
+ arch/x86/kernel/cpu/common.c       |  7 +++++++
+ arch/x86/kernel/cpu/hygon.c        |  3 +++
+ 6 files changed, 32 insertions(+), 18 deletions(-)
+
+diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
+index 4819d5e5a3353..7f828fe497978 100644
+--- a/arch/x86/include/asm/barrier.h
++++ b/arch/x86/include/asm/barrier.h
+@@ -84,22 +84,4 @@ do {                                                                        \
+ #include <asm-generic/barrier.h>
+-/*
+- * Make previous memory operations globally visible before
+- * a WRMSR.
+- *
+- * MFENCE makes writes visible, but only affects load/store
+- * instructions.  WRMSR is unfortunately not a load/store
+- * instruction and is unaffected by MFENCE.  The LFENCE ensures
+- * that the WRMSR is not reordered.
+- *
+- * Most WRMSRs are full serializing instructions themselves and
+- * do not require this barrier.  This is only required for the
+- * IA32_TSC_DEADLINE and X2APIC MSRs.
+- */
+-static inline void weak_wrmsr_fence(void)
+-{
+-      asm volatile("mfence; lfence" : : : "memory");
+-}
+-
+ #endif /* _ASM_X86_BARRIER_H */
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index 23f563493e810..f3365ec973763 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -305,6 +305,7 @@
+ #define X86_FEATURE_SRSO              (11*32+24) /* "" AMD BTB untrain RETs */
+ #define X86_FEATURE_SRSO_ALIAS                (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
+ #define X86_FEATURE_IBPB_ON_VMEXIT    (11*32+26) /* "" Issue an IBPB only on VMEXIT */
++#define X86_FEATURE_APIC_MSRS_FENCE   (11*32+27) /* "" IA32_TSC_DEADLINE and X2APIC MSRs need fencing */
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX512_BF16               (12*32+ 5) /* AVX512 BFLOAT16 instructions */
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index c682a14299e0e..5defef9f286e1 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -858,4 +858,22 @@ enum mds_mitigations {
+ extern bool gds_ucode_mitigated(void);
++/*
++ * Make previous memory operations globally visible before
++ * a WRMSR.
++ *
++ * MFENCE makes writes visible, but only affects load/store
++ * instructions.  WRMSR is unfortunately not a load/store
++ * instruction and is unaffected by MFENCE.  The LFENCE ensures
++ * that the WRMSR is not reordered.
++ *
++ * Most WRMSRs are full serializing instructions themselves and
++ * do not require this barrier.  This is only required for the
++ * IA32_TSC_DEADLINE and X2APIC MSRs.
++ */
++static inline void weak_wrmsr_fence(void)
++{
++      alternative("mfence; lfence", "", ALT_NOT(X86_FEATURE_APIC_MSRS_FENCE));
++}
++
+ #endif /* _ASM_X86_PROCESSOR_H */
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 3b02cb8b05338..c10f7dcaa7b7c 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -1186,6 +1186,9 @@ static void init_amd(struct cpuinfo_x86 *c)
+       if (!cpu_has(c, X86_FEATURE_HYPERVISOR) &&
+            cpu_has_amd_erratum(c, amd_erratum_1485))
+               msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT);
++
++      /* AMD CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */
++      clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE);
+ }
+ #ifdef CONFIG_X86_32
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index f8e5598408bfd..97da1dcf5a399 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1716,6 +1716,13 @@ static void identify_cpu(struct cpuinfo_x86 *c)
+       c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
+ #endif
++
++      /*
++       * Set default APIC and TSC_DEADLINE MSR fencing flag. AMD and
++       * Hygon will clear it in ->c_init() below.
++       */
++      set_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE);
++
+       /*
+        * Vendor-specific initialization.  In this section we
+        * canonicalize the feature flags, meaning if there are
+diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
+index 3f5c00b15e2c1..b49f662f68718 100644
+--- a/arch/x86/kernel/cpu/hygon.c
++++ b/arch/x86/kernel/cpu/hygon.c
+@@ -363,6 +363,9 @@ static void init_hygon(struct cpuinfo_x86 *c)
+               set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
+       check_null_seg_clears_base(c);
++
++      /* Hygon CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */
++      clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE);
+ }
+ static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
+-- 
+2.43.0
+
diff --git a/queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch b/queue-5.10/x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch
new file mode 100644 (file)
index 0000000..1f9aed3
--- /dev/null
@@ -0,0 +1,54 @@
+From 981a05a2e3d15cf30f556fa08c217a6c8f0eda22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 18:04:40 +0200
+Subject: x86/pvh: Call C code via the kernel virtual mapping
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit e8fbc0d9cab6c1ee6403f42c0991b0c1d5dbc092 ]
+
+Calling C code via a different mapping than it was linked at is
+problematic, because the compiler assumes that RIP-relative and absolute
+symbol references are interchangeable. GCC in particular may use
+RIP-relative per-CPU variable references even when not using -fpic.
+
+So call xen_prepare_pvh() via its kernel virtual mapping on x86_64, so
+that those RIP-relative references produce the correct values. This
+matches the pre-existing behavior for i386, which also invokes
+xen_prepare_pvh() via the kernel virtual mapping before invoking
+startup_32 with paging disabled again.
+
+Fixes: 7243b93345f7 ("xen/pvh: Bootstrap PVH guest")
+Tested-by: Jason Andryuk <jason.andryuk@amd.com>
+Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Message-ID: <20241009160438.3884381-8-ardb+git@google.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/platform/pvh/head.S | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
+index cfabc3340362b..eadadd2ecd847 100644
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -106,7 +106,14 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+       movq %rbp, %rbx
+       subq $_pa(pvh_start_xen), %rbx
+       movq %rbx, phys_base(%rip)
+-      call xen_prepare_pvh
++
++      /* Call xen_prepare_pvh() via the kernel virtual mapping */
++      leaq xen_prepare_pvh(%rip), %rax
++      subq phys_base(%rip), %rax
++      addq $__START_KERNEL_map, %rax
++      ANNOTATE_RETPOLINE_SAFE
++      call *%rax
++
+       /*
+        * Clear phys_base.  __startup_64 will *add* to its value,
+        * so reset to 0.
+-- 
+2.43.0
+
diff --git a/queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch b/queue-5.10/x86-pvh-set-phys_base-when-calling-xen_prepare_pvh.patch
new file mode 100644 (file)
index 0000000..e15049b
--- /dev/null
@@ -0,0 +1,52 @@
+From f250731baac8e75ace3cec56e22c979aadb1f1ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Aug 2024 15:36:28 -0400
+Subject: x86/pvh: Set phys_base when calling xen_prepare_pvh()
+
+From: Jason Andryuk <jason.andryuk@amd.com>
+
+[ Upstream commit b464b461d27d564125db760938643374864c1b1f ]
+
+phys_base needs to be set for __pa() to work in xen_pvh_init() when
+finding the hypercall page.  Set it before calling into
+xen_prepare_pvh(), which calls xen_pvh_init().  Clear it afterward to
+avoid __startup_64() adding to it and creating an incorrect value.
+
+Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Message-ID: <20240823193630.2583107-4-jason.andryuk@amd.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: e8fbc0d9cab6 ("x86/pvh: Call C code via the kernel virtual mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/platform/pvh/head.S | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
+index b0490701da2ab..cfabc3340362b 100644
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -99,7 +99,20 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+       xor %edx, %edx
+       wrmsr
++      /*
++       * Calculate load offset and store in phys_base.  __pa() needs
++       * phys_base set to calculate the hypercall page in xen_pvh_init().
++       */
++      movq %rbp, %rbx
++      subq $_pa(pvh_start_xen), %rbx
++      movq %rbx, phys_base(%rip)
+       call xen_prepare_pvh
++      /*
++       * Clear phys_base.  __startup_64 will *add* to its value,
++       * so reset to 0.
++       */
++      xor  %rbx, %rbx
++      movq %rbx, phys_base(%rip)
+       /* startup_64 expects boot_params in %rsi. */
+       mov $_pa(pvh_bootparams), %rsi
+-- 
+2.43.0
+
diff --git a/queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch b/queue-5.10/x86-xen-pvh-annotate-indirect-branch-as-safe.patch
new file mode 100644 (file)
index 0000000..478e12e
--- /dev/null
@@ -0,0 +1,46 @@
+From d216a9dab1baf7ef71df9b038a4ee12234f421b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jan 2021 15:29:30 -0600
+Subject: x86/xen/pvh: Annotate indirect branch as safe
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+[ Upstream commit 82694854caa8badab7c5d3a19c0139e8b471b1d3 ]
+
+This indirect jump is harmless; annotate it to keep objtool's retpoline
+validation happy.
+
+Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: Juergen Gross <jgross@suse.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/4797c72a258b26e06741c58ccd4a75c42db39c1d.1611263462.git.jpoimboe@redhat.com
+Stable-dep-of: e8fbc0d9cab6 ("x86/pvh: Call C code via the kernel virtual mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/platform/pvh/head.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
+index afbf0bb252da5..b0490701da2ab 100644
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -16,6 +16,7 @@
+ #include <asm/boot.h>
+ #include <asm/processor-flags.h>
+ #include <asm/msr.h>
++#include <asm/nospec-branch.h>
+ #include <xen/interface/elfnote.h>
+       __HEAD
+@@ -103,6 +104,7 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+       /* startup_64 expects boot_params in %rsi. */
+       mov $_pa(pvh_bootparams), %rsi
+       mov $_pa(startup_64), %rax
++      ANNOTATE_RETPOLINE_SAFE
+       jmp *%rax
+ #else /* CONFIG_X86_64 */
+-- 
+2.43.0
+
diff --git a/queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch b/queue-5.10/xfrm-rename-xfrm_state_offload-struct-to-allow-reuse.patch
new file mode 100644 (file)
index 0000000..39a9d2c
--- /dev/null
@@ -0,0 +1,126 @@
+From 73603a61b5c78794e4c8e5c73735940c42d191b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 13:06:40 +0300
+Subject: xfrm: rename xfrm_state_offload struct to allow reuse
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 87e0a94e60ea2e29be9dec6bc146fbc9861a4055 ]
+
+The struct xfrm_state_offload has all fields needed to hold information
+for offloaded policies too. In order to do not create new struct with
+same fields, let's rename existing one and reuse it later.
+
+Reviewed-by: Raed Salem <raeds@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h     | 10 +++++-----
+ net/xfrm/xfrm_device.c |  2 +-
+ net/xfrm/xfrm_state.c  |  4 ++--
+ net/xfrm/xfrm_user.c   |  2 +-
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 798df30c2d253..987c603806aee 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -126,7 +126,7 @@ struct xfrm_state_walk {
+       struct xfrm_address_filter *filter;
+ };
+-struct xfrm_state_offload {
++struct xfrm_dev_offload {
+       struct net_device       *dev;
+       struct net_device       *real_dev;
+       unsigned long           offload_handle;
+@@ -240,7 +240,7 @@ struct xfrm_state {
+       struct xfrm_lifetime_cur curlft;
+       struct hrtimer          mtimer;
+-      struct xfrm_state_offload xso;
++      struct xfrm_dev_offload xso;
+       /* used to fix curlft->add_time when changing date */
+       long            saved_tmo;
+@@ -1892,7 +1892,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
+ static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
+ {
+-      struct xfrm_state_offload *xso = &x->xso;
++      struct xfrm_dev_offload *xso = &x->xso;
+       if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
+               xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
+@@ -1918,7 +1918,7 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
+ static inline void xfrm_dev_state_delete(struct xfrm_state *x)
+ {
+-      struct xfrm_state_offload *xso = &x->xso;
++      struct xfrm_dev_offload *xso = &x->xso;
+       if (xso->dev)
+               xso->dev->xfrmdev_ops->xdo_dev_state_delete(x);
+@@ -1926,7 +1926,7 @@ static inline void xfrm_dev_state_delete(struct xfrm_state *x)
+ static inline void xfrm_dev_state_free(struct xfrm_state *x)
+ {
+-      struct xfrm_state_offload *xso = &x->xso;
++      struct xfrm_dev_offload *xso = &x->xso;
+       struct net_device *dev = xso->dev;
+       if (dev && dev->xfrmdev_ops) {
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 4d13f7a372ab6..61aa0fd9d2a0c 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -225,7 +225,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+       int err;
+       struct dst_entry *dst;
+       struct net_device *dev;
+-      struct xfrm_state_offload *xso = &x->xso;
++      struct xfrm_dev_offload *xso = &x->xso;
+       xfrm_address_t *saddr;
+       xfrm_address_t *daddr;
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index ba73014805a4f..94179ff475f2f 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -726,7 +726,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool
+       for (i = 0; i <= net->xfrm.state_hmask; i++) {
+               struct xfrm_state *x;
+-              struct xfrm_state_offload *xso;
++              struct xfrm_dev_offload *xso;
+               hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
+                       xso = &x->xso;
+@@ -810,7 +810,7 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali
+       err = -ESRCH;
+       for (i = 0; i <= net->xfrm.state_hmask; i++) {
+               struct xfrm_state *x;
+-              struct xfrm_state_offload *xso;
++              struct xfrm_dev_offload *xso;
+ restart:
+               hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) {
+                       xso = &x->xso;
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index e28e49499713f..b12a305a2d7a4 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -843,7 +843,7 @@ static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
+       return 0;
+ }
+-static int copy_user_offload(struct xfrm_state_offload *xso, struct sk_buff *skb)
++static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb)
+ {
+       struct xfrm_user_offload *xuo;
+       struct nlattr *attr;
+-- 
+2.43.0
+
diff --git a/queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch b/queue-5.10/xfrm-store-and-rely-on-direction-to-construct-offloa.patch
new file mode 100644 (file)
index 0000000..12a4dd3
--- /dev/null
@@ -0,0 +1,96 @@
+From 2fc8606ea6ecd9997ccc3d43c0de145de5c0876a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 13:06:41 +0300
+Subject: xfrm: store and rely on direction to construct offload flags
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 482db2f1dd211f73ad9d71e33ae15c1df6379982 ]
+
+XFRM state doesn't need anything from flags except to understand
+direction, so store it separately. For future patches, such change
+will allow us to reuse xfrm_dev_offload for policy offload too, which
+has three possible directions instead of two.
+
+Reviewed-by: Raed Salem <raeds@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Stable-dep-of: 2cf567f421db ("netdevsim: copy addresses for both in and out paths")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h     | 6 ++++++
+ net/xfrm/xfrm_device.c | 8 +++++++-
+ net/xfrm/xfrm_user.c   | 3 ++-
+ 3 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 987c603806aee..2c1feca282036 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -126,12 +126,18 @@ struct xfrm_state_walk {
+       struct xfrm_address_filter *filter;
+ };
++enum {
++      XFRM_DEV_OFFLOAD_IN = 1,
++      XFRM_DEV_OFFLOAD_OUT,
++};
++
+ struct xfrm_dev_offload {
+       struct net_device       *dev;
+       struct net_device       *real_dev;
+       unsigned long           offload_handle;
+       unsigned int            num_exthdrs;
+       u8                      flags;
++      u8                      dir : 2;
+ };
+ struct xfrm_mode {
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 61aa0fd9d2a0c..7690d23bcf8bb 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -129,7 +129,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+       sp = skb_sec_path(skb);
+       x = sp->xvec[sp->len - 1];
+-      if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
++      if (xo->flags & XFRM_GRO || x->xso.dir == XFRM_DEV_OFFLOAD_IN)
+               return skb;
+       /* This skb was already validated on the upper/virtual dev */
+@@ -285,11 +285,17 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
+       /* Don't forward bit that is not implemented */
+       xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6;
++      if (xuo->flags & XFRM_OFFLOAD_INBOUND)
++              xso->dir = XFRM_DEV_OFFLOAD_IN;
++      else
++              xso->dir = XFRM_DEV_OFFLOAD_OUT;
++
+       err = dev->xfrmdev_ops->xdo_dev_state_add(x);
+       if (err) {
+               xso->num_exthdrs = 0;
+               xso->flags = 0;
+               xso->dev = NULL;
++              xso->dir = 0;
+               xso->real_dev = NULL;
+               dev_put(dev);
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index b12a305a2d7a4..aa509857b6660 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -855,7 +855,8 @@ static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb)
+       xuo = nla_data(attr);
+       memset(xuo, 0, sizeof(*xuo));
+       xuo->ifindex = xso->dev->ifindex;
+-      xuo->flags = xso->flags;
++      if (xso->dir == XFRM_DEV_OFFLOAD_IN)
++              xuo->flags = XFRM_OFFLOAD_INBOUND;
+       return 0;
+ }
+-- 
+2.43.0
+