]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Fri, 10 Nov 2023 17:35:01 +0000 (12:35 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 10 Nov 2023 17:35:01 +0000 (12:35 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
232 files changed:
queue-5.15/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch [new file with mode: 0644]
queue-5.15/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch [new file with mode: 0644]
queue-5.15/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch [new file with mode: 0644]
queue-5.15/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch [new file with mode: 0644]
queue-5.15/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch [new file with mode: 0644]
queue-5.15/arm64-arm-xen-enlighten-fix-kpti-checks.patch [new file with mode: 0644]
queue-5.15/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch [new file with mode: 0644]
queue-5.15/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch [new file with mode: 0644]
queue-5.15/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch [new file with mode: 0644]
queue-5.15/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch [new file with mode: 0644]
queue-5.15/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch [new file with mode: 0644]
queue-5.15/asoc-ams-delta.c-use-component-after-check.patch [new file with mode: 0644]
queue-5.15/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch [new file with mode: 0644]
queue-5.15/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch [new file with mode: 0644]
queue-5.15/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch [new file with mode: 0644]
queue-5.15/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch [new file with mode: 0644]
queue-5.15/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch [new file with mode: 0644]
queue-5.15/can-dev-can_restart-fix-race-condition-between-contr.patch [new file with mode: 0644]
queue-5.15/chtls-fix-tp-rcv_tstamp-initialization.patch [new file with mode: 0644]
queue-5.15/clk-imx-imx8mq-correct-error-handling-path.patch [new file with mode: 0644]
queue-5.15/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch [new file with mode: 0644]
queue-5.15/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch [new file with mode: 0644]
queue-5.15/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch [new file with mode: 0644]
queue-5.15/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch [new file with mode: 0644]
queue-5.15/clk-npcm7xx-fix-incorrect-kfree.patch [new file with mode: 0644]
queue-5.15/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch [new file with mode: 0644]
queue-5.15/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8996-drop-unsupported-clock-sources.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8996-move-clock-parent-tables-down.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8996-use-array_size-instead-of-speci.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-msm8996-use-parent_hws-_data-instead-of.patch [new file with mode: 0644]
queue-5.15/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch [new file with mode: 0644]
queue-5.15/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch [new file with mode: 0644]
queue-5.15/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch [new file with mode: 0644]
queue-5.15/clk-renesas-rzg2l-fix-computation-formula.patch [new file with mode: 0644]
queue-5.15/clk-renesas-rzg2l-simplify-multiplication-shift-logi.patch [new file with mode: 0644]
queue-5.15/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch [new file with mode: 0644]
queue-5.15/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch [new file with mode: 0644]
queue-5.15/clk-ti-add-ti_dt_clk_name-helper-to-use-clock-output.patch [new file with mode: 0644]
queue-5.15/clk-ti-change-ti_clk_register-_omap_hw-api.patch [new file with mode: 0644]
queue-5.15/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch [new file with mode: 0644]
queue-5.15/clk-ti-update-component-clocks-to-use-ti_dt_clk_name.patch [new file with mode: 0644]
queue-5.15/clk-ti-update-pll-and-clockdomain-clocks-to-use-ti_d.patch [new file with mode: 0644]
queue-5.15/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch [new file with mode: 0644]
queue-5.15/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch [new file with mode: 0644]
queue-5.15/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch [new file with mode: 0644]
queue-5.15/crypto-qat-fix-deadlock-in-backlog-processing.patch [new file with mode: 0644]
queue-5.15/crypto-qat-increase-size-of-buffers.patch [new file with mode: 0644]
queue-5.15/cxl-mbox-introduce-the-mbox_send-operation.patch [new file with mode: 0644]
queue-5.15/cxl-mbox-move-mailbox-and-other-non-pci-specific-inf.patch [new file with mode: 0644]
queue-5.15/cxl-mem-fix-shutdown-order.patch [new file with mode: 0644]
queue-5.15/cxl-pci-clean-up-cxl_mem_get_partition_info.patch [new file with mode: 0644]
queue-5.15/cxl-pci-drop-idr.h.patch [new file with mode: 0644]
queue-5.15/cxl-pci-make-struct-cxl_mem-device-type-generic.patch [new file with mode: 0644]
queue-5.15/dmaengine-idxd-register-dsa_bus_type-before-register.patch [new file with mode: 0644]
queue-5.15/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch [new file with mode: 0644]
queue-5.15/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch [new file with mode: 0644]
queue-5.15/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-add-hot-plug-detection.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-fix-bridge_detach.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-register-and-attach-our-dsi-devic.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt8912b-switch-to-devm-mipi-dsi-helpers.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt9611uxc-register-and-attach-our-dsi-dev.patch [new file with mode: 0644]
queue-5.15/drm-bridge-lt9611uxc-switch-to-devm-mipi-dsi-helpers.patch [new file with mode: 0644]
queue-5.15/drm-bridge-tc358768-disable-non-continuous-clock-mod.patch [new file with mode: 0644]
queue-5.15/drm-bridge-tc358768-fix-bit-updates.patch [new file with mode: 0644]
queue-5.15/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch [new file with mode: 0644]
queue-5.15/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch [new file with mode: 0644]
queue-5.15/drm-mipi-dsi-create-devm-device-attachment.patch [new file with mode: 0644]
queue-5.15/drm-mipi-dsi-create-devm-device-registration.patch [new file with mode: 0644]
queue-5.15/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch [new file with mode: 0644]
queue-5.15/drm-radeon-possible-buffer-overflow.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch [new file with mode: 0644]
queue-5.15/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch [new file with mode: 0644]
queue-5.15/ext4-move-ix-sanity-check-to-corrent-position.patch [new file with mode: 0644]
queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch [new file with mode: 0644]
queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch [new file with mode: 0644]
queue-5.15/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch [new file with mode: 0644]
queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch [new file with mode: 0644]
queue-5.15/f2fs-introduce-memory-mode.patch [new file with mode: 0644]
queue-5.15/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch [new file with mode: 0644]
queue-5.15/firmware-ti_sci-mark-driver-as-non-removable.patch [new file with mode: 0644]
queue-5.15/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch [new file with mode: 0644]
queue-5.15/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch [new file with mode: 0644]
queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch [new file with mode: 0644]
queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch [new file with mode: 0644]
queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch [new file with mode: 0644]
queue-5.15/gve-use-size_add-in-call-to-struct_size.patch [new file with mode: 0644]
queue-5.15/hid-cp2112-fix-duplicate-workqueue-initialization.patch [new file with mode: 0644]
queue-5.15/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch [new file with mode: 0644]
queue-5.15/hid-cp2112-make-irq_chip-immutable.patch [new file with mode: 0644]
queue-5.15/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch [new file with mode: 0644]
queue-5.15/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch [new file with mode: 0644]
queue-5.15/hid-logitech-hidpp-remove-hidpp_quirk_no_hidinput-qu.patch [new file with mode: 0644]
queue-5.15/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch [new file with mode: 0644]
queue-5.15/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch [new file with mode: 0644]
queue-5.15/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch [new file with mode: 0644]
queue-5.15/hwrng-geode-fix-accessing-registers.patch [new file with mode: 0644]
queue-5.15/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch [new file with mode: 0644]
queue-5.15/i40e-fix-potential-memory-leaks-in-i40e_remove.patch [new file with mode: 0644]
queue-5.15/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch [new file with mode: 0644]
queue-5.15/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch [new file with mode: 0644]
queue-5.15/ipv6-avoid-atomic-fragment-on-gso-packets.patch [new file with mode: 0644]
queue-5.15/ipvlan-properly-track-tx_errors.patch [new file with mode: 0644]
queue-5.15/iwlwifi-pcie-adjust-to-bz-completion-descriptor.patch [new file with mode: 0644]
queue-5.15/iwlwifi-remove-contact-information.patch [new file with mode: 0644]
queue-5.15/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch [new file with mode: 0644]
queue-5.15/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch [new file with mode: 0644]
queue-5.15/leds-turris-omnia-do-not-use-smbus-calls.patch [new file with mode: 0644]
queue-5.15/leds-turris-omnia-drop-unnecessary-mutex-locking.patch [new file with mode: 0644]
queue-5.15/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch [new file with mode: 0644]
queue-5.15/livepatch-fix-missing-newline-character-in-klp_resol.patch [new file with mode: 0644]
queue-5.15/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch [new file with mode: 0644]
queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch [new file with mode: 0644]
queue-5.15/media-cedrus-fix-clock-reset-sequence.patch [new file with mode: 0644]
queue-5.15/media-dvb-usb-v2-af9035-fix-missing-unlock.patch [new file with mode: 0644]
queue-5.15/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch [new file with mode: 0644]
queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch [new file with mode: 0644]
queue-5.15/media-rcar-vin-move-group-async-notifier.patch [new file with mode: 0644]
queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch [new file with mode: 0644]
queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch [new file with mode: 0644]
queue-5.15/media-s3c-camif-avoid-inappropriate-kfree.patch [new file with mode: 0644]
queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch [new file with mode: 0644]
queue-5.15/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch [new file with mode: 0644]
queue-5.15/media-vidtv-psi-add-check-for-kstrdup.patch [new file with mode: 0644]
queue-5.15/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch [new file with mode: 0644]
queue-5.15/mfd-core-ensure-disabled-devices-are-skipped-without.patch [new file with mode: 0644]
queue-5.15/mfd-core-un-constify-mfd_cell.of_reg.patch [new file with mode: 0644]
queue-5.15/mfd-dln2-fix-double-put-in-dln2_probe.patch [new file with mode: 0644]
queue-5.15/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch [new file with mode: 0644]
queue-5.15/mlxsw-use-size_mul-in-call-to-struct_size.patch [new file with mode: 0644]
queue-5.15/modpost-fix-tee-module_device_table-built-on-big-end.patch [new file with mode: 0644]
queue-5.15/mt76-add-support-for-overriding-the-device-used-for-.patch [new file with mode: 0644]
queue-5.15/mt76-dma-use-kzalloc-instead-of-devm_kzalloc-for-txw.patch [new file with mode: 0644]
queue-5.15/mt76-pass-original-queue-id-from-__mt76_tx_queue_skb.patch [new file with mode: 0644]
queue-5.15/nd_btt-make-btt-lanes-preemptible.patch [new file with mode: 0644]
queue-5.15/net-add-dev_stats_read-helper.patch [new file with mode: 0644]
queue-5.15/net-spider_net-use-size_add-in-call-to-struct_size.patch [new file with mode: 0644]
queue-5.15/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch [new file with mode: 0644]
queue-5.15/padata-fix-refcnt-handling-in-padata_free_shell.patch [new file with mode: 0644]
queue-5.15/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch [new file with mode: 0644]
queue-5.15/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch [new file with mode: 0644]
queue-5.15/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch [new file with mode: 0644]
queue-5.15/perf-evlist-add-evlist__add_dummy_on_all_cpus.patch [new file with mode: 0644]
queue-5.15/perf-evlist-avoid-frequency-mode-for-the-dummy-event.patch [new file with mode: 0644]
queue-5.15/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch [new file with mode: 0644]
queue-5.15/perf-hist-add-missing-puts-to-hist__account_cycles.patch [new file with mode: 0644]
queue-5.15/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch [new file with mode: 0644]
queue-5.15/perf-tools-get-rid-of-evlist__add_on_all_cpus.patch [new file with mode: 0644]
queue-5.15/platform-x86-wmi-fix-opening-of-char-device.patch [new file with mode: 0644]
queue-5.15/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch [new file with mode: 0644]
queue-5.15/platform-x86-wmi-remove-unnecessary-initializations.patch [new file with mode: 0644]
queue-5.15/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch [new file with mode: 0644]
queue-5.15/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch [new file with mode: 0644]
queue-5.15/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch [new file with mode: 0644]
queue-5.15/powerpc-only-define-__parse_fpscr-when-required.patch [new file with mode: 0644]
queue-5.15/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch [new file with mode: 0644]
queue-5.15/powerpc-xive-fix-endian-conversion-size.patch [new file with mode: 0644]
queue-5.15/pstore-platform-add-check-for-kstrdup.patch [new file with mode: 0644]
queue-5.15/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch [new file with mode: 0644]
queue-5.15/r8169-use-tp_to_dev-instead-of-open-code.patch [new file with mode: 0644]
queue-5.15/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch [new file with mode: 0644]
queue-5.15/rdma-hfi1-workaround-truncation-compilation-error.patch [new file with mode: 0644]
queue-5.15/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch [new file with mode: 0644]
queue-5.15/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch [new file with mode: 0644]
queue-5.15/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch [new file with mode: 0644]
queue-5.15/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch [new file with mode: 0644]
queue-5.15/regmap-prevent-noinc-writes-from-clobbering-cache.patch [new file with mode: 0644]
queue-5.15/revert-hid-logitech-hidpp-add-a-module-parameter-to-.patch [new file with mode: 0644]
queue-5.15/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch [new file with mode: 0644]
queue-5.15/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch [new file with mode: 0644]
queue-5.15/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch [new file with mode: 0644]
queue-5.15/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch [new file with mode: 0644]
queue-5.15/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch [new file with mode: 0644]
queue-5.15/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch [new file with mode: 0644]
queue-5.15/selftests-bpf-test-tail-call-counting-with-bpf2bpf-a.patch [new file with mode: 0644]
queue-5.15/selftests-pidfd-fix-ksft-print-formats.patch [new file with mode: 0644]
queue-5.15/selftests-resctrl-ensure-the-benchmark-commands-fits.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/sh-bios-revive-earlyprintk-support.patch [new file with mode: 0644]
queue-5.15/soc-qcom-llcc-handle-a-second-device-without-data-co.patch [new file with mode: 0644]
queue-5.15/spi-nxp-fspi-use-the-correct-ioremap-function.patch [new file with mode: 0644]
queue-5.15/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch [new file with mode: 0644]
queue-5.15/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch [new file with mode: 0644]
queue-5.15/tcp-fix-cookie_init_timestamp-overflows.patch [new file with mode: 0644]
queue-5.15/tcp_metrics-add-missing-barriers-on-delete.patch [new file with mode: 0644]
queue-5.15/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch [new file with mode: 0644]
queue-5.15/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch [new file with mode: 0644]
queue-5.15/thermal-core-prevent-potential-string-overflow.patch [new file with mode: 0644]
queue-5.15/tipc-use-size_add-in-calls-to-struct_size.patch [new file with mode: 0644]
queue-5.15/tools-iio-iio_generic_buffer-ensure-alignment.patch [new file with mode: 0644]
queue-5.15/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch [new file with mode: 0644]
queue-5.15/udp-add-missing-write_once-around-up-encap_rcv.patch [new file with mode: 0644]
queue-5.15/usb-chipidea-fix-dma-overwrite-for-tegra.patch [new file with mode: 0644]
queue-5.15/usb-chipidea-simplify-tegra-dma-alignment-code.patch [new file with mode: 0644]
queue-5.15/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch [new file with mode: 0644]
queue-5.15/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch [new file with mode: 0644]
queue-5.15/usb-usbip-fix-stub_dev-hub-disconnect.patch [new file with mode: 0644]
queue-5.15/vfs-fix-readahead-2-on-block-devices.patch [new file with mode: 0644]
queue-5.15/wifi-iwlwifi-call-napi_synchronize-before-freeing-rx.patch [new file with mode: 0644]
queue-5.15/wifi-iwlwifi-empty-overflow-queue-during-flush.patch [new file with mode: 0644]
queue-5.15/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch [new file with mode: 0644]
queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch [new file with mode: 0644]
queue-5.15/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch [new file with mode: 0644]
queue-5.15/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch [new file with mode: 0644]
queue-5.15/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch [new file with mode: 0644]
queue-5.15/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch [new file with mode: 0644]
queue-5.15/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch [new file with mode: 0644]
queue-5.15/x86-boot-fix-incorrect-startup_gdt_descr.size.patch [new file with mode: 0644]
queue-5.15/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch [new file with mode: 0644]
queue-5.15/x86-share-definition-of-__is_canonical_address.patch [new file with mode: 0644]
queue-5.15/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch [new file with mode: 0644]
queue-5.15/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch [new file with mode: 0644]
queue-5.15/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch [new file with mode: 0644]

diff --git a/queue-5.15/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch b/queue-5.15/9p-net-fix-possible-memory-leak-in-p9_check_errors.patch
new file mode 100644 (file)
index 0000000..6b698d9
--- /dev/null
@@ -0,0 +1,47 @@
+From 77446d67560d46864a1986e48ef9b9633f232f1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 11:03:02 +0800
+Subject: 9p/net: fix possible memory leak in p9_check_errors()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit ce07087964208eee2ca2f9ee4a98f8b5d9027fe6 ]
+
+When p9pdu_readf() is called with "s?d" attribute, it allocates a pointer
+that will store a string. But when p9pdu_readf() fails while handling "d"
+then this pointer will not be freed in p9_check_errors().
+
+Fixes: 51a87c552dfd ("9p: rework client code to use new protocol support functions")
+Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Message-ID: <20231027030302.11927-1-hbh25y@gmail.com>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/client.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/9p/client.c b/net/9p/client.c
+index c4c1e44cd7ca3..9fdcaa956c008 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -520,12 +520,14 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
+               return 0;
+       if (!p9_is_proto_dotl(c)) {
+-              char *ename;
++              char *ename = NULL;
+               err = p9pdu_readf(&req->rc, c->proto_version, "s?d",
+                                 &ename, &ecode);
+-              if (err)
++              if (err) {
++                      kfree(ename);
+                       goto out_err;
++              }
+               if (p9_is_proto_dotu(c) && ecode < 512)
+                       err = -ecode;
+-- 
+2.42.0
+
diff --git a/queue-5.15/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch b/queue-5.15/acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch
new file mode 100644 (file)
index 0000000..8bfbe9f
--- /dev/null
@@ -0,0 +1,62 @@
+From 6480654ad6e5e47192c9ec7a883c6cbdbdcc9dd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Oct 2023 20:32:54 +0200
+Subject: ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 48cf49d31994ff97b33c4044e618560ec84d35fb ]
+
+snprintf() does not return negative values on error.
+
+To know if the buffer was too small, the returned value needs to be
+compared with the length of the passed buffer. If it is greater or
+equal, the output has been truncated, so add checks for the truncation
+to create_pnp_modalias() and create_of_modalias(). Also make them
+return -ENOMEM in that case, as they already do that elsewhere.
+
+Moreover, the remaining size of the buffer used by snprintf() needs to
+be updated after the first write to avoid out-of-bounds access as
+already done correctly in create_pnp_modalias(), but not in
+create_of_modalias(), so change the latter accordingly.
+
+Fixes: 8765c5ba1949 ("ACPI / scan: Rework modalias creation when "compatible" is present")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+[ rjw: Merge two patches into one, combine changelogs, add subject ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/device_sysfs.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
+index 61271e61c3073..da9cd11adfb56 100644
+--- a/drivers/acpi/device_sysfs.c
++++ b/drivers/acpi/device_sysfs.c
+@@ -157,8 +157,8 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
+               return 0;
+       len = snprintf(modalias, size, "acpi:");
+-      if (len <= 0)
+-              return len;
++      if (len >= size)
++              return -ENOMEM;
+       size -= len;
+@@ -211,8 +211,10 @@ static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
+       len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
+       ACPI_FREE(buf.pointer);
+-      if (len <= 0)
+-              return len;
++      if (len >= size)
++              return -ENOMEM;
++
++      size -= len;
+       of_compatible = acpi_dev->data.of_compatible;
+       if (of_compatible->type == ACPI_TYPE_PACKAGE) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch b/queue-5.15/arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch
new file mode 100644 (file)
index 0000000..1bcdc8e
--- /dev/null
@@ -0,0 +1,63 @@
+From f71e01feff5b06f29dea7be9408bbe282c83427a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 15:06:06 +0100
+Subject: ARM: 9321/1: memset: cast the constant byte to unsigned char
+
+From: Kursad Oney <kursad.oney@broadcom.com>
+
+[ Upstream commit c0e824661f443b8cab3897006c1bbc69fd0e7bc4 ]
+
+memset() description in ISO/IEC 9899:1999 (and elsewhere) says:
+
+       The memset function copies the value of c (converted to an
+       unsigned char) into each of the first n characters of the
+       object pointed to by s.
+
+The kernel's arm32 memset does not cast c to unsigned char. This results
+in the following code to produce erroneous output:
+
+       char a[128];
+       memset(a, -128, sizeof(a));
+
+This is because gcc will generally emit the following code before
+it calls memset() :
+
+       mov   r0, r7
+       mvn   r1, #127        ; 0x7f
+       bl    00000000 <memset>
+
+r1 ends up with 0xffffff80 before being used by memset() and the
+'a' array will have -128 once in every four bytes while the other
+bytes will be set incorrectly to -1 like this (printing the first
+8 bytes) :
+
+       test_module: -128 -1 -1 -1
+       test_module: -1 -1 -1 -128
+
+The change here is to 'and' r1 with 255 before it is used.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Kursad Oney <kursad.oney@broadcom.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/lib/memset.S | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
+index 9817cb258c1a5..0481b9bbbd004 100644
+--- a/arch/arm/lib/memset.S
++++ b/arch/arm/lib/memset.S
+@@ -17,6 +17,7 @@ ENTRY(__memset)
+ ENTRY(mmioset)
+ WEAK(memset)
+ UNWIND( .fnstart         )
++      and     r1, r1, #255            @ cast to unsigned char
+       ands    r3, r0, #3              @ 1 unaligned?
+       mov     ip, r0                  @ preserve r0 as return value
+       bne     6f                      @ 1
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch b/queue-5.15/arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch
new file mode 100644 (file)
index 0000000..d74c875
--- /dev/null
@@ -0,0 +1,51 @@
+From 2411013ead0e25a4e5c8c391b302dcdfcadaa9ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 20:39:13 +0200
+Subject: ARM: dts: qcom: mdm9615: populate vsdcc fixed regulator
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 09f8ee81b6da5f76de8b83c8bfc4475b54e101e0 ]
+
+Fixed regulator put under "regulators" node will not be populated,
+unless simple-bus or something similar is used.  Drop the "regulators"
+wrapper node to fix this.
+
+Fixes: 2c5e596524e7 ("ARM: dts: Add MDM9615 dtsi")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230924183914.51414-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-mdm9615.dtsi | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+index ad9b52d53ef9b..982f3c3921965 100644
+--- a/arch/arm/boot/dts/qcom-mdm9615.dtsi
++++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+@@ -82,14 +82,12 @@ cxo_board {
+               };
+       };
+-      regulators {
+-              vsdcc_fixed: vsdcc-regulator {
+-                      compatible = "regulator-fixed";
+-                      regulator-name = "SDCC Power";
+-                      regulator-min-microvolt = <2700000>;
+-                      regulator-max-microvolt = <2700000>;
+-                      regulator-always-on;
+-              };
++      vsdcc_fixed: vsdcc-regulator {
++              compatible = "regulator-fixed";
++              regulator-name = "SDCC Power";
++              regulator-min-microvolt = <2700000>;
++              regulator-max-microvolt = <2700000>;
++              regulator-always-on;
+       };
+       soc: soc {
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch b/queue-5.15/arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch
new file mode 100644 (file)
index 0000000..808ffa6
--- /dev/null
@@ -0,0 +1,39 @@
+From 7a182f164433cc2a8a6f6952bea4850c8d9ae35d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Aug 2023 17:21:38 +0200
+Subject: ARM: dts: renesas: blanche: Fix typo in GP_11_2 pin name
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit edc6ef026fe69154bb6b70dd6e7f278cfd7d6919 ]
+
+On blanche, the GPIO keyboard fails to probe with:
+
+    sh-pfc e6060000.pinctrl: could not map pin config for "GP_11_02"
+
+Fix this by correcting the name for this pin to "GP_11_2".
+
+Fixes: 1f27fedead91eb60 ("ARM: dts: blanche: Configure pull-up for SOFT_SW and SW25 GPIO keys")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/203128eca2261ffc33b83637818dd39c488f42b0.1693408326.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/r8a7792-blanche.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/r8a7792-blanche.dts b/arch/arm/boot/dts/r8a7792-blanche.dts
+index 62aa9f61321be..089fef40c4c49 100644
+--- a/arch/arm/boot/dts/r8a7792-blanche.dts
++++ b/arch/arm/boot/dts/r8a7792-blanche.dts
+@@ -239,7 +239,7 @@ du1_pins: du1 {
+       };
+       keyboard_pins: keyboard {
+-              pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_02";
++              pins = "GP_3_10", "GP_3_11", "GP_3_12", "GP_3_15", "GP_11_2";
+               bias-pull-up;
+       };
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-arm-xen-enlighten-fix-kpti-checks.patch b/queue-5.15/arm64-arm-xen-enlighten-fix-kpti-checks.patch
new file mode 100644 (file)
index 0000000..bb9d4dd
--- /dev/null
@@ -0,0 +1,128 @@
+From b41800afaa64ab8b9b88c7c8d60b3c38d3fda01f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Oct 2023 11:24:25 +0100
+Subject: arm64/arm: xen: enlighten: Fix KPTI checks
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 20f3b8eafe0ba5d3c69d5011a9b07739e9645132 ]
+
+When KPTI is in use, we cannot register a runstate region as XEN
+requires that this is always a valid VA, which we cannot guarantee. Due
+to this, xen_starting_cpu() must avoid registering each CPU's runstate
+region, and xen_guest_init() must avoid setting up features that depend
+upon it.
+
+We tried to ensure that in commit:
+
+  f88af7229f6f22ce (" xen/arm: do not setup the runstate info page if kpti is enabled")
+
+... where we added checks for xen_kernel_unmapped_at_usr(), which wraps
+arm64_kernel_unmapped_at_el0() on arm64 and is always false on 32-bit
+arm.
+
+Unfortunately, as xen_guest_init() is an early_initcall, this happens
+before secondary CPUs are booted and arm64 has finalized the
+ARM64_UNMAP_KERNEL_AT_EL0 cpucap which backs
+arm64_kernel_unmapped_at_el0(), and so this can subsequently be set as
+secondary CPUs are onlined. On a big.LITTLE system where the boot CPU
+does not require KPTI but some secondary CPUs do, this will result in
+xen_guest_init() intializing features that depend on the runstate
+region, and xen_starting_cpu() registering the runstate region on some
+CPUs before KPTI is subsequent enabled, resulting the the problems the
+aforementioned commit tried to avoid.
+
+Handle this more robsutly by deferring the initialization of the
+runstate region until secondary CPUs have been initialized and the
+ARM64_UNMAP_KERNEL_AT_EL0 cpucap has been finalized. The per-cpu work is
+moved into a new hotplug starting function which is registered later
+when we're certain that KPTI will not be used.
+
+Fixes: f88af7229f6f ("xen/arm: do not setup the runstate info page if kpti is enabled")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Bertrand Marquis <bertrand.marquis@arm.com>
+Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Stefano Stabellini <sstabellini@kernel.org>
+Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/xen/enlighten.c   | 25 ++++++++++++++++---------
+ include/linux/cpuhotplug.h |  1 +
+ 2 files changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
+index 7f1c106b746f8..27277d6bbfa5a 100644
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -159,9 +159,6 @@ static int xen_starting_cpu(unsigned int cpu)
+       BUG_ON(err);
+       per_cpu(xen_vcpu, cpu) = vcpup;
+-      if (!xen_kernel_unmapped_at_usr())
+-              xen_setup_runstate_info(cpu);
+-
+ after_register_vcpu_info:
+       enable_percpu_irq(xen_events_irq, 0);
+       return 0;
+@@ -394,9 +391,6 @@ static int __init xen_guest_init(void)
+               return -EINVAL;
+       }
+-      if (!xen_kernel_unmapped_at_usr())
+-              xen_time_setup_guest();
+-
+       if (xen_initial_domain())
+               pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
+@@ -406,7 +400,13 @@ static int __init xen_guest_init(void)
+ }
+ early_initcall(xen_guest_init);
+-static int __init xen_pm_init(void)
++static int xen_starting_runstate_cpu(unsigned int cpu)
++{
++      xen_setup_runstate_info(cpu);
++      return 0;
++}
++
++static int __init xen_late_init(void)
+ {
+       if (!xen_domain())
+               return -ENODEV;
+@@ -419,9 +419,16 @@ static int __init xen_pm_init(void)
+               do_settimeofday64(&ts);
+       }
+-      return 0;
++      if (xen_kernel_unmapped_at_usr())
++              return 0;
++
++      xen_time_setup_guest();
++
++      return cpuhp_setup_state(CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
++                               "arm/xen_runstate:starting",
++                               xen_starting_runstate_cpu, NULL);
+ }
+-late_initcall(xen_pm_init);
++late_initcall(xen_late_init);
+ /* empty stubs */
+diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
+index dbca858ffa6da..c7156bb56e831 100644
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -188,6 +188,7 @@ enum cpuhp_state {
+       /* Must be the last timer callback */
+       CPUHP_AP_DUMMY_TIMER_STARTING,
+       CPUHP_AP_ARM_XEN_STARTING,
++      CPUHP_AP_ARM_XEN_RUNSTATE_STARTING,
+       CPUHP_AP_ARM_CORESIGHT_STARTING,
+       CPUHP_AP_ARM_CORESIGHT_CTI_STARTING,
+       CPUHP_AP_ARM64_ISNDEP_STARTING,
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch b/queue-5.15/arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch
new file mode 100644 (file)
index 0000000..a6782a8
--- /dev/null
@@ -0,0 +1,36 @@
+From d5c8ff6cc9cc9d3474c42000f82c3122e7cf636a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 18:01:58 -0500
+Subject: arm64: dts: imx8mm: Add sound-dai-cells to micfil node
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 0e6cc2b8bb7d67733f4a47720787eff1ce2666f2 ]
+
+Per the DT bindings, the micfil node should have a sound-dai-cells
+entry.
+
+Fixes: 3bd0788c43d9 ("arm64: dts: imx8mm: Add support for micfil")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index 2a67122c5624c..86731850a6bd6 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -366,6 +366,7 @@ micfil: audio-controller@30080000 {
+                                                     "pll8k", "pll11k", "clkext3";
+                                       dmas = <&sdma2 24 25 0x80000000>;
+                                       dma-names = "rx";
++                                      #sound-dai-cells = <0>;
+                                       status = "disabled";
+                               };
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch b/queue-5.15/arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch
new file mode 100644 (file)
index 0000000..86a1db7
--- /dev/null
@@ -0,0 +1,36 @@
+From adf10134d080fcb3d98adea7dbd18f4b0838f192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 18:01:59 -0500
+Subject: arm64: dts: imx8mn: Add sound-dai-cells to micfil node
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit db1925454a2e7cadcac8756442ca7c3198332336 ]
+
+Per the DT bindings, the micfil node should have a sound-dai-cells
+entry.
+
+Fixes: cca69ef6eba5 ("arm64: dts: imx8mn: Add support for micfil")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mn.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+index 16a5efba17f39..8f01848b7c6a9 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+@@ -340,6 +340,7 @@ micfil: audio-controller@30080000 {
+                                                     "pll8k", "pll11k", "clkext3";
+                                       dmas = <&sdma2 24 25 0x80000000>;
+                                       dma-names = "rx";
++                                      #sound-dai-cells = <0>;
+                                       status = "disabled";
+                               };
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch b/queue-5.15/arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch
new file mode 100644 (file)
index 0000000..e78e7c9
--- /dev/null
@@ -0,0 +1,42 @@
+From ca067a45f64a175c8def5f99b855687b1180e821 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 11:27:36 -0300
+Subject: arm64: dts: imx8qm-ss-img: Fix jpegenc compatible entry
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit 1d33cd614d89b0ec024d25ec45acf4632211b5a7 ]
+
+The first compatible entry for the jpegenc should be 'nxp,imx8qm-jpgenc'.
+
+Change it accordingly to fix the following schema warning:
+
+imx8qm-apalis-eval.dtb: jpegenc@58450000: compatible: 'oneOf' conditional failed, one must be fixed:
+       'nxp,imx8qm-jpgdec' is not one of ['nxp,imx8qxp-jpgdec', 'nxp,imx8qxp-jpgenc']
+       'nxp,imx8qm-jpgenc' was expected
+       'nxp,imx8qxp-jpgdec' was expected
+
+Fixes: 5bb279171afc ("arm64: dts: imx8: Add jpeg encoder/decoder nodes")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
+index 7764b4146e0ab..2bbdacb1313f9 100644
+--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
+@@ -8,5 +8,5 @@ &jpegdec {
+ };
+ &jpegenc {
+-      compatible = "nxp,imx8qm-jpgdec", "nxp,imx8qxp-jpgenc";
++      compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc";
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch b/queue-5.15/arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch
new file mode 100644 (file)
index 0000000..78b7e71
--- /dev/null
@@ -0,0 +1,72 @@
+From 1fae08c62af0928245ef3a5dc36df4520e9e4af5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 10:51:25 +1200
+Subject: ARM64: dts: marvell: cn9310: Use appropriate label for spi1 pins
+
+From: Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+[ Upstream commit 0878fd86f554ab98aa493996c7e0c72dff58437f ]
+
+Both the CN9130-CRB and CN9130-DB use the SPI1 interface but had the
+pinctrl node labelled as "cp0_spi0_pins". Use the label "cp0_spi1_pins"
+and update the node name to "cp0-spi-pins-1" to avoid confusion with the
+pinctrl options for SPI0.
+
+Fixes: 4c43a41e5b8c ("arm64: dts: cn913x: add device trees for topology B boards")
+Fixes: 5c0ee54723f3 ("arm64: dts: add support for Marvell cn9130-crb platform")
+Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/marvell/cn9130-crb.dtsi | 4 ++--
+ arch/arm64/boot/dts/marvell/cn9130-db.dtsi  | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
+index 505ae69289f6d..ce49702dc4936 100644
+--- a/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
++++ b/arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
+@@ -107,7 +107,7 @@ cp0_sdhci_pins: cp0-sdhi-pins-0 {
+                                      "mpp59", "mpp60", "mpp61";
+                       marvell,function = "sdio";
+               };
+-              cp0_spi0_pins: cp0-spi-pins-0 {
++              cp0_spi1_pins: cp0-spi-pins-1 {
+                       marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+                       marvell,function = "spi1";
+               };
+@@ -149,7 +149,7 @@ &cp0_sdhci0 {
+ &cp0_spi1 {
+       pinctrl-names = "default";
+-      pinctrl-0 = <&cp0_spi0_pins>;
++      pinctrl-0 = <&cp0_spi1_pins>;
+       reg = <0x700680 0x50>,          /* control */
+             <0x2000000 0x1000000>;    /* CS0 */
+       status = "okay";
+diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
+index c00b69b88bd2f..c53253f668403 100644
+--- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
++++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
+@@ -307,7 +307,7 @@ &cp0_sdhci0 {
+ &cp0_spi1 {
+       status = "disabled";
+       pinctrl-names = "default";
+-      pinctrl-0 = <&cp0_spi0_pins>;
++      pinctrl-0 = <&cp0_spi1_pins>;
+       reg = <0x700680 0x50>;
+       spi-flash@0 {
+@@ -371,7 +371,7 @@ cp0_sdhci_pins: cp0-sdhi-pins-0 {
+                                      "mpp59", "mpp60", "mpp61";
+                       marvell,function = "sdio";
+               };
+-              cp0_spi0_pins: cp0-spi-pins-0 {
++              cp0_spi1_pins: cp0-spi-pins-1 {
+                       marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
+                       marvell,function = "spi1";
+               };
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch b/queue-5.15/arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch
new file mode 100644 (file)
index 0000000..cbf0606
--- /dev/null
@@ -0,0 +1,45 @@
+From 65a05cd16e035e672bb57b27bb1eb0333cef14a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 12:49:55 +0200
+Subject: arm64: dts: qcom: apq8016-sbc: Add missing ADV7533 regulators
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit 33e9032a1875bb1aee3c68a4540f5a577ff44130 ]
+
+Add the missing regulator supplies to the ADV7533 HDMI bridge to fix
+the following dtbs_check warnings. They are all also supplied by
+pm8916_l6 so there is no functional difference.
+
+apq8016-sbc.dtb: bridge@39: 'dvdd-supply' is a required property
+apq8016-sbc.dtb: bridge@39: 'pvdd-supply' is a required property
+apq8016-sbc.dtb: bridge@39: 'a2vdd-supply' is a required property
+        from schema display/bridge/adi,adv7533.yaml
+
+Fixes: 28546b095511 ("arm64: dts: apq8016-sbc: Add HDMI display support")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230922-db410c-adv7533-regulators-v1-1-68aba71e529b@gerhold.net
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/apq8016-sbc.dts | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+index ad4c2ccec63ee..0153be6d2a2b1 100644
+--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
++++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dts
+@@ -190,6 +190,9 @@ adv_bridge: bridge@39 {
+               pd-gpios = <&msmgpio 32 GPIO_ACTIVE_HIGH>;
+               avdd-supply = <&pm8916_l6>;
++              a2vdd-supply = <&pm8916_l6>;
++              dvdd-supply = <&pm8916_l6>;
++              pvdd-supply = <&pm8916_l6>;
+               v1p2-supply = <&pm8916_l6>;
+               v3p3-supply = <&pm8916_l17>;
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch b/queue-5.15/arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch
new file mode 100644 (file)
index 0000000..2f68871
--- /dev/null
@@ -0,0 +1,40 @@
+From ff76ee86e94d159c87e0ec611d3973ae18f5c01b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 20:03:04 +0530
+Subject: arm64: dts: qcom: msm8916: Fix iommu local address range
+
+From: Gaurav Kohli <quic_gkohli@quicinc.com>
+
+[ Upstream commit 2de8ee9f58fa51f707c71f8fbcd8470ab0078102 ]
+
+Fix the apps iommu local address space range as per data sheet.
+
+Fixes: 6a6729f38436 ("arm64: dts: qcom: msm8916: Add IOMMU support")
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Gaurav Kohli <quic_gkohli@quicinc.com>
+Reviewed-by: Stephan Gerhold <stephan@gerhold.net>
+Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230915143304.477-1-quic_gkohli@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index fcc9f757c9e14..668674059d485 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1233,7 +1233,7 @@ apps_iommu: iommu@1ef0000 {
+                       #size-cells = <1>;
+                       #iommu-cells = <1>;
+                       compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1";
+-                      ranges = <0 0x01e20000 0x40000>;
++                      ranges = <0 0x01e20000 0x20000>;
+                       reg = <0x01ef0000 0x3000>;
+                       clocks = <&gcc GCC_SMMU_CFG_CLK>,
+                                <&gcc GCC_APSS_TCU_CLK>;
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch b/queue-5.15/arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch
new file mode 100644 (file)
index 0000000..e16da1b
--- /dev/null
@@ -0,0 +1,42 @@
+From cb43a19df3ed3620f0645c93b3f69a1b7d998e29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 09:20:48 +0200
+Subject: arm64: dts: qcom: msm8992-libra: drop duplicated reserved memory
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit f32096602c19e68fb9bf04b494d13f1190602554 ]
+
+There are two entries for similar reserved memory: qseecom@cb400000 and
+audio@cb400000.  Keep the qseecom as it is longer.
+
+  Warning (unique_unit_address_if_enabled): /reserved-memory/audio@cb400000: duplicate unit-address (also used in node /reserved-memory/qseecom@cb400000)
+
+Fixes: 69876bc6fd4d ("arm64: dts: qcom: msm8992-libra: Fix the memory map")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230720072048.10093-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+index d08659c606b9a..5433ae0c45907 100644
+--- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
++++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts
+@@ -99,11 +99,6 @@ rmtfs_mem: rmtfs@ca100000 {
+                       qcom,client-id = <1>;
+               };
+-              audio_mem: audio@cb400000 {
+-                      reg = <0 0xcb000000 0 0x400000>;
+-                      no-mem;
+-              };
+-
+               qseecom_mem: qseecom@cb400000 {
+                       reg = <0 0xcb400000 0 0x1c00000>;
+                       no-mem;
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch b/queue-5.15/arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch
new file mode 100644 (file)
index 0000000..a45d27a
--- /dev/null
@@ -0,0 +1,43 @@
+From cda075d471bc310e17c682d4866112465202e40e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 22:58:22 +0200
+Subject: arm64: dts: qcom: sc7280: Add missing LMH interrupts
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 3f93d119c9d6e1744d55cd48af764160a1a3aca3 ]
+
+Hook up the interrupts that signal the Limits Management Hardware has
+started some sort of throttling action.
+
+Fixes: 7dbd121a2c58 ("arm64: dts: qcom: sc7280: Add cpufreq hw node")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230811-topic-7280_lmhirq-v1-1-c262b6a25c8f@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7280.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index fb6473a0aa4b3..dc4aab258ff6f 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -1851,6 +1851,14 @@ cpufreq_hw: cpufreq@18591000 {
+                       reg = <0 0x18591000 0 0x1000>,
+                             <0 0x18592000 0 0x1000>,
+                             <0 0x18593000 0 0x1000>;
++
++                      interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "dcvsh-irq-0",
++                                        "dcvsh-irq-1",
++                                        "dcvsh-irq-2";
++
+                       clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+                       clock-names = "xo", "alternate";
+                       #freq-domain-cells = <1>;
+-- 
+2.42.0
+
diff --git a/queue-5.15/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch b/queue-5.15/arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch
new file mode 100644 (file)
index 0000000..1bd962d
--- /dev/null
@@ -0,0 +1,37 @@
+From 2a4076b88121ad10d1d8b2ac66e06c384dc561a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Aug 2023 01:19:11 +0300
+Subject: arm64: dts: qcom: sdm845-mtp: fix WiFi configuration
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b33868a52f342d9b1f20aa5bffe40cbd69bd0a4b ]
+
+Enable the host-cap-8bit quirk on this device. It is required for the
+WiFi to function properly.
+
+Fixes: 022bccb840b7 ("arm64: dts: sdm845: Add WCN3990 WLAN module device node")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230826221915.846937-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+index 52dd7a858231e..cf2fad5bcac1b 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+@@ -572,6 +572,8 @@ &wifi {
+       vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+       vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+       vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
++
++      qcom,snoc-host-cap-8bit-quirk;
+ };
+ /* PINCTRL - additions to nodes defined in sdm845.dtsi */
+-- 
+2.42.0
+
diff --git a/queue-5.15/asoc-ams-delta.c-use-component-after-check.patch b/queue-5.15/asoc-ams-delta.c-use-component-after-check.patch
new file mode 100644 (file)
index 0000000..b9cf0c4
--- /dev/null
@@ -0,0 +1,56 @@
+From 52958aa8fd7da647dbf672f70621ae6a14b5fcf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 00:09:56 +0000
+Subject: ASoC: ams-delta.c: use component after check
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit bd0f7498bc9084d8cccc5484cd004b40f314b763 ]
+
+       static void cx81801_close()
+       {
+               ...
+(A)            struct snd_soc_dapm_context *dapm = &component->card->dapm;
+               ...
+(B)            if (!component)
+                       return;
+       }
+
+(A) uses component before NULL check (B). This patch moves it after (B).
+
+Fixes: d0fdfe34080c ("ASoC: cx20442: replace codec to component")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/3e608474-e99a-4866-ae98-3054a4221f09@moroto.mountain
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/r/87ttqdq623.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/ti/ams-delta.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c
+index ecd24d412a9b0..4537ef1b676f5 100644
+--- a/sound/soc/ti/ams-delta.c
++++ b/sound/soc/ti/ams-delta.c
+@@ -303,7 +303,7 @@ static int cx81801_open(struct tty_struct *tty)
+ static void cx81801_close(struct tty_struct *tty)
+ {
+       struct snd_soc_component *component = tty->disc_data;
+-      struct snd_soc_dapm_context *dapm = &component->card->dapm;
++      struct snd_soc_dapm_context *dapm;
+       del_timer_sync(&cx81801_timer);
+@@ -315,6 +315,8 @@ static void cx81801_close(struct tty_struct *tty)
+       v253_ops.close(tty);
++      dapm = &component->card->dapm;
++
+       /* Revert back to default audio input/output constellation */
+       snd_soc_dapm_mutex_lock(dapm);
+-- 
+2.42.0
+
diff --git a/queue-5.15/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch b/queue-5.15/asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch
new file mode 100644 (file)
index 0000000..483dfdb
--- /dev/null
@@ -0,0 +1,54 @@
+From 4c56916f378b9946593628dc57d9dc5075a70720 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 21:03:15 +0800
+Subject: ASoC: fsl: Fix PM disable depth imbalance in fsl_easrc_probe
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 9e630efb5a4af56fdb15aa10405f5cfd3f5f5b83 ]
+
+The pm_runtime_enable will increase power disable depth. Thus
+a pairing decrement is needed on the error handling path to
+keep it balanced according to context. We fix it by calling
+pm_runtime_disable when error returns.
+
+Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Link: https://lore.kernel.org/r/tencent_C0D62E6D89818179A02A04A0C248F0DDC40A@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_easrc.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
+index cf0e10d17dbe3..c7ff48208d005 100644
+--- a/sound/soc/fsl/fsl_easrc.c
++++ b/sound/soc/fsl/fsl_easrc.c
+@@ -1965,17 +1965,21 @@ static int fsl_easrc_probe(struct platform_device *pdev)
+                                             &fsl_easrc_dai, 1);
+       if (ret) {
+               dev_err(dev, "failed to register ASoC DAI\n");
+-              return ret;
++              goto err_pm_disable;
+       }
+       ret = devm_snd_soc_register_component(dev, &fsl_asrc_component,
+                                             NULL, 0);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register ASoC platform\n");
+-              return ret;
++              goto err_pm_disable;
+       }
+       return 0;
++
++err_pm_disable:
++      pm_runtime_disable(&pdev->dev);
++      return ret;
+ }
+ static int fsl_easrc_remove(struct platform_device *pdev)
+-- 
+2.42.0
+
diff --git a/queue-5.15/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch b/queue-5.15/asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch
new file mode 100644 (file)
index 0000000..738442b
--- /dev/null
@@ -0,0 +1,45 @@
+From e119dc31cda92cf17e6d5dd7624d77a7dbdfa1ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 23:39:43 +0000
+Subject: ASoC: fsl: mpc5200_dma.c: Fix warning of Function parameter or member
+ not described
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit 4a221b2e3340f4a3c2b414c46c846a26c6caf820 ]
+
+This patch fixes the warnings of "Function parameter or member 'xxx'
+not described".
+
+>> sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'component' not described in 'psc_dma_trigger'
+   sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'substream' not described in 'psc_dma_trigger'
+   sound/soc/fsl/mpc5200_dma.c:116: warning: Function parameter or member 'cmd' not described in 'psc_dma_trigger'
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202310061914.jJuekdHs-lkp@intel.com/
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Fixes: 6d1048bc1152 ("ASoC: fsl: mpc5200_dma: remove snd_pcm_ops")
+Link: https://lore.kernel.org/r/87il7fcqm8.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/mpc5200_dma.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
+index 9014978100207..3f7ccae3f6b1a 100644
+--- a/sound/soc/fsl/mpc5200_dma.c
++++ b/sound/soc/fsl/mpc5200_dma.c
+@@ -100,6 +100,9 @@ static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
+ /**
+  * psc_dma_trigger: start and stop the DMA transfer.
++ * @component: triggered component
++ * @substream: triggered substream
++ * @cmd: triggered command
+  *
+  * This function is called by ALSA to start, stop, pause, and resume the DMA
+  * transfer of data.
+-- 
+2.42.0
+
diff --git a/queue-5.15/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch b/queue-5.15/asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch
new file mode 100644 (file)
index 0000000..3f5e897
--- /dev/null
@@ -0,0 +1,40 @@
+From 609ec476cdb15c434068cb193a0696c7d62ea978 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 10:25:58 +0200
+Subject: ASoC: Intel: Skylake: Fix mem leak when parsing UUIDs fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cezary Rojewski <cezary.rojewski@intel.com>
+
+[ Upstream commit 168d97844a61db302dec76d44406e9d4d7106b8e ]
+
+Error path in snd_skl_parse_uuids() shall free last allocated module if
+its instance_id allocation fails.
+
+Fixes: f8e066521192 ("ASoC: Intel: Skylake: Fix uuid_module memory leak in failure case")
+Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
+Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
+Link: https://lore.kernel.org/r/20231026082558.1864910-1-amadeuszx.slawinski@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/skylake/skl-sst-utils.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
+index 57ea815d3f041..b776c58dcf47a 100644
+--- a/sound/soc/intel/skylake/skl-sst-utils.c
++++ b/sound/soc/intel/skylake/skl-sst-utils.c
+@@ -299,6 +299,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
+               module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
+               if (!module->instance_id) {
+                       ret = -ENOMEM;
++                      kfree(module);
+                       goto free_uuid_list;
+               }
+-- 
+2.42.0
+
diff --git a/queue-5.15/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch b/queue-5.15/can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch
new file mode 100644 (file)
index 0000000..ed377ea
--- /dev/null
@@ -0,0 +1,43 @@
+From fe1be58f7710425d08a491ee2649d44668c0a5eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Sep 2023 10:23:47 +0200
+Subject: can: dev: can_put_echo_skb(): don't crash kernel if
+ can_priv::echo_skb is accessed out of bounds
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6411959c10fe917288cbb1038886999148560057 ]
+
+If the "struct can_priv::echoo_skb" is accessed out of bounds, this
+would cause a kernel crash. Instead, issue a meaningful warning
+message and return with an error.
+
+Fixes: a6e4bc530403 ("can: make the number of echo skb's configurable")
+Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-5-91b5c1fd922c@pengutronix.de
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/skb.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
+index 61660248c69ef..e59d5cbb644a1 100644
+--- a/drivers/net/can/dev/skb.c
++++ b/drivers/net/can/dev/skb.c
+@@ -42,7 +42,11 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+ {
+       struct can_priv *priv = netdev_priv(dev);
+-      BUG_ON(idx >= priv->echo_skb_max);
++      if (idx >= priv->echo_skb_max) {
++              netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
++                         __func__, idx, priv->echo_skb_max);
++              return -EINVAL;
++      }
+       /* check flag whether this packet has to be looped back */
+       if (!(dev->flags & IFF_ECHO) ||
+-- 
+2.42.0
+
diff --git a/queue-5.15/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch b/queue-5.15/can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch
new file mode 100644 (file)
index 0000000..fe09a8a
--- /dev/null
@@ -0,0 +1,46 @@
+From 0fd33d1593eab375917f8b559caea53bac5d0be1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 21:58:23 +0200
+Subject: can: dev: can_restart(): don't crash kernel if carrier is OK
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit fe5c9940dfd8ba0c73672dddb30acd1b7a11d4c7 ]
+
+During testing, I triggered a can_restart() with the netif carrier
+being OK [1]. The BUG_ON, which checks if the carrier is OK, results
+in a fatal kernel crash. This is neither helpful for debugging nor for
+a production system.
+
+[1] The root cause is a race condition in can_restart() which will be
+fixed in the next patch.
+
+Do not crash the kernel, issue an error message instead, and continue
+restarting the CAN device anyway.
+
+Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
+Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-1-91b5c1fd922c@pengutronix.de
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/dev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
+index e3d840b81357d..ed2841a681d72 100644
+--- a/drivers/net/can/dev/dev.c
++++ b/drivers/net/can/dev/dev.c
+@@ -141,7 +141,8 @@ static void can_restart(struct net_device *dev)
+       struct can_frame *cf;
+       int err;
+-      BUG_ON(netif_carrier_ok(dev));
++      if (netif_carrier_ok(dev))
++              netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n");
+       /* No synchronization needed because the device is bus-off and
+        * no messages can come in or go out.
+-- 
+2.42.0
+
diff --git a/queue-5.15/can-dev-can_restart-fix-race-condition-between-contr.patch b/queue-5.15/can-dev-can_restart-fix-race-condition-between-contr.patch
new file mode 100644 (file)
index 0000000..da54965
--- /dev/null
@@ -0,0 +1,102 @@
+From 892d069ad88acb25a3552266ae5beca25ab8fcc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Sep 2023 10:25:11 +0200
+Subject: can: dev: can_restart(): fix race condition between controller
+ restart and netif_carrier_on()
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 6841cab8c4504835e4011689cbdb3351dec693fd ]
+
+This race condition was discovered while updating the at91_can driver
+to use can_bus_off(). The following scenario describes how the
+converted at91_can driver would behave.
+
+When a CAN device goes into BUS-OFF state, the driver usually
+stops/resets the CAN device and calls can_bus_off().
+
+This function sets the netif carrier to off, and (if configured by
+user space) schedules a delayed work that calls can_restart() to
+restart the CAN device.
+
+The can_restart() function first checks if the carrier is off and
+triggers an error message if the carrier is OK.
+
+Then it calls the driver's do_set_mode() function to restart the
+device, then it sets the netif carrier to on. There is a race window
+between these two calls.
+
+The at91 CAN controller (observed on the sama5d3, a single core 32 bit
+ARM CPU) has a hardware limitation. If the device goes into bus-off
+while sending a CAN frame, there is no way to abort the sending of
+this frame. After the controller is enabled again, another attempt is
+made to send it.
+
+If the bus is still faulty, the device immediately goes back to the
+bus-off state. The driver calls can_bus_off(), the netif carrier is
+switched off and another can_restart is scheduled. This occurs within
+the race window before the original can_restart() handler marks the
+netif carrier as OK. This would cause the 2nd can_restart() to be
+called with an OK netif carrier, resulting in an error message.
+
+The flow of the 1st can_restart() looks like this:
+
+can_restart()
+    // bail out if netif_carrier is OK
+
+    netif_carrier_ok(dev)
+    priv->do_set_mode(dev, CAN_MODE_START)
+        // enable CAN controller
+        // sama5d3 restarts sending old message
+
+        // CAN devices goes into BUS_OFF, triggers IRQ
+
+// IRQ handler start
+    at91_irq()
+        at91_irq_err_line()
+            can_bus_off()
+                netif_carrier_off()
+                schedule_delayed_work()
+// IRQ handler end
+
+    netif_carrier_on()
+
+The 2nd can_restart() will be called with an OK netif carrier and the
+error message will be printed.
+
+To close the race window, first set the netif carrier to on, then
+restart the controller. In case the restart fails with an error code,
+roll back the netif carrier to off.
+
+Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
+Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-2-91b5c1fd922c@pengutronix.de
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/dev.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
+index ed2841a681d72..94916f2d24d41 100644
+--- a/drivers/net/can/dev/dev.c
++++ b/drivers/net/can/dev/dev.c
+@@ -166,11 +166,12 @@ static void can_restart(struct net_device *dev)
+       priv->can_stats.restarts++;
+       /* Now restart the device */
+-      err = priv->do_set_mode(dev, CAN_MODE_START);
+-
+       netif_carrier_on(dev);
+-      if (err)
++      err = priv->do_set_mode(dev, CAN_MODE_START);
++      if (err) {
+               netdev_err(dev, "Error %d during restart", err);
++              netif_carrier_off(dev);
++      }
+ }
+ static void can_restart_work(struct work_struct *work)
+-- 
+2.42.0
+
diff --git a/queue-5.15/chtls-fix-tp-rcv_tstamp-initialization.patch b/queue-5.15/chtls-fix-tp-rcv_tstamp-initialization.patch
new file mode 100644 (file)
index 0000000..db80849
--- /dev/null
@@ -0,0 +1,36 @@
+From 593c13d625955550aa7ffa47759e797846efc6df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 12:57:36 +0000
+Subject: chtls: fix tp->rcv_tstamp initialization
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 225d9ddbacb102621af6d28ff7bf5a0b4ce249d8 ]
+
+tp->rcv_tstamp should be set to tcp_jiffies, not tcp_time_stamp().
+
+Fixes: cc35c88ae4db ("crypto : chtls - CPL handler definition")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Ayush Sawal <ayush.sawal@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+index ddfe9208529a5..65d4a39634be4 100644
+--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+@@ -2260,7 +2260,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb)
+               if (tp->snd_una != snd_una) {
+                       tp->snd_una = snd_una;
+-                      tp->rcv_tstamp = tcp_time_stamp(tp);
++                      tp->rcv_tstamp = tcp_jiffies32;
+                       if (tp->snd_una == tp->snd_nxt &&
+                           !csk_flag_nochk(csk, CSK_TX_FAILOVER))
+                               csk_reset_flag(csk, CSK_TX_WAIT_IDLE);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-imx-imx8mq-correct-error-handling-path.patch b/queue-5.15/clk-imx-imx8mq-correct-error-handling-path.patch
new file mode 100644 (file)
index 0000000..1f25d30
--- /dev/null
@@ -0,0 +1,71 @@
+From 9683bf7a8a50c0400d177b859a7c6e822941246f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 20:26:18 +0800
+Subject: clk: imx: imx8mq: correct error handling path
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 577ad169966e6e75b10e004389a3f79813e84b5d ]
+
+Avoid memory leak in error handling path. It does not make
+much sense for the SoC without clk driver, to make program behavior
+correct, let's fix it.
+
+Fixes: b80522040cd3 ("clk: imx: Add clock driver for i.MX8MQ CCM")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202309240551.e46NllPa-lkp@intel.com/
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20231001122618.194498-1-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mq.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
+index 83cc2b1c32947..791f6bdd88b8a 100644
+--- a/drivers/clk/imx/clk-imx8mq.c
++++ b/drivers/clk/imx/clk-imx8mq.c
+@@ -288,8 +288,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
+       void __iomem *base;
+       int err;
+-      clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+-                                        IMX8MQ_CLK_END), GFP_KERNEL);
++      clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MQ_CLK_END), GFP_KERNEL);
+       if (WARN_ON(!clk_hw_data))
+               return -ENOMEM;
+@@ -306,10 +305,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
+       hws[IMX8MQ_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
+-      base = of_iomap(np, 0);
++      base = devm_of_iomap(dev, np, 0, NULL);
+       of_node_put(np);
+-      if (WARN_ON(!base))
+-              return -ENOMEM;
++      if (WARN_ON(IS_ERR(base))) {
++              err = PTR_ERR(base);
++              goto unregister_hws;
++      }
+       hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+@@ -395,8 +396,10 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
+       np = dev->of_node;
+       base = devm_platform_ioremap_resource(pdev, 0);
+-      if (WARN_ON(IS_ERR(base)))
+-              return PTR_ERR(base);
++      if (WARN_ON(IS_ERR(base))) {
++              err = PTR_ERR(base);
++              goto unregister_hws;
++      }
+       /* CORE */
+       hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch b/queue-5.15/clk-imx-imx8qxp-fix-elcdif_pll-clock.patch
new file mode 100644 (file)
index 0000000..aabc640
--- /dev/null
@@ -0,0 +1,45 @@
+From d6a6ca157dab879ff2dc40df4966263d55969531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:19:00 +0800
+Subject: clk: imx: imx8qxp: Fix elcdif_pll clock
+
+From: Robert Chiras <robert.chiras@nxp.com>
+
+[ Upstream commit 15cee75dacb82ade710d61bfd536011933ef9bf2 ]
+
+Move the elcdif_pll clock initialization before the lcd_clk, since the
+elcdif_clk needs to be initialized ahead of lcd_clk, being its parent.
+This change fixes issues with the LCD clocks during suspend/resume.
+
+Fixes: babfaa9556d7 ("clk: imx: scu: add more scu clocks")
+Suggested-by: Ranjani Vaidyanathan <ranjani.vaidyanathan@nxp.com>
+Acked-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
+Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20230912-imx8-clk-v1-v1-2-69a34bcfcae1@nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8qxp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
+index 40a2efb1329be..32df47c56621a 100644
+--- a/drivers/clk/imx/clk-imx8qxp.c
++++ b/drivers/clk/imx/clk-imx8qxp.c
+@@ -148,10 +148,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
+       imx_clk_scu("adc0_clk",  IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER);
+       imx_clk_scu("adc1_clk",  IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER);
+       imx_clk_scu("pwm_clk",   IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
++      imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
+       imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
+       imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
+       imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
+-      imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
+       /* Audio SS */
+       imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch b/queue-5.15/clk-imx-select-mxc_clk-for-clk_imx8qxp.patch
new file mode 100644 (file)
index 0000000..b057d44
--- /dev/null
@@ -0,0 +1,43 @@
+From 65b10dc863f9858c9b7ac79af5cc6e849a269591 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 12:23:54 +0300
+Subject: clk: imx: Select MXC_CLK for CLK_IMX8QXP
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit 317e69c49b4ceef8aebb47d771498ccb3571bdf9 ]
+
+If the i.MX8QXP clock provider is built-in but the MXC_CLK is
+built as module, build fails:
+
+aarch64-linux-ld: drivers/clk/imx/clk-imx8-acm.o: in function `imx8_acm_clk_probe':
+clk-imx8-acm.c:(.text+0x3d0): undefined reference to `imx_check_clk_hws'
+
+Fix that by selecting MXC_CLK in case of CLK_IMX8QXP.
+
+Fixes: c2cccb6d0b33 ("clk: imx: add imx8qxp clk driver")
+Closes: https://lore.kernel.org/all/8b77219e-b59e-40f1-96f1-980a0b2debcf@infradead.org/
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Acked-by: Randy Dunlap <rdunlap@infradead.org>
+Tested-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
+index 47d9ec3abd2f7..d3d730610cb4f 100644
+--- a/drivers/clk/imx/Kconfig
++++ b/drivers/clk/imx/Kconfig
+@@ -96,5 +96,6 @@ config CLK_IMX8QXP
+       depends on (ARCH_MXC && ARM64) || COMPILE_TEST
+       depends on IMX_SCU && HAVE_ARM_SMCCC
+       select MXC_CLK_SCU
++      select MXC_CLK
+       help
+         Build the driver for IMX8QXP SCU based clocks.
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch b/queue-5.15/clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch
new file mode 100644 (file)
index 0000000..3744d47
--- /dev/null
@@ -0,0 +1,61 @@
+From 5cf3428205b12862d4919d13000062d26026a298 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Oct 2023 17:01:57 +0300
+Subject: clk: keystone: pll: fix a couple NULL vs IS_ERR() checks
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit a5d14f8b551eb1551c10053653ee8e27f19672fa ]
+
+The clk_register_divider() and clk_register_mux() functions returns
+error pointers on error but this code checks for NULL.  Fix that.
+
+Fixes: b9e0d40c0d83 ("clk: keystone: add Keystone PLL clock driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/d9da4c97-0da9-499f-9a21-1f8e3f148dc1@moroto.mountain
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/keystone/pll.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
+index ee5c72369334f..6bbdd4705d71f 100644
+--- a/drivers/clk/keystone/pll.c
++++ b/drivers/clk/keystone/pll.c
+@@ -281,12 +281,13 @@ static void __init of_pll_div_clk_init(struct device_node *node)
+       clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift,
+                                mask, 0, NULL);
+-      if (clk) {
+-              of_clk_add_provider(node, of_clk_src_simple_get, clk);
+-      } else {
++      if (IS_ERR(clk)) {
+               pr_err("%s: error registering divider %s\n", __func__, clk_name);
+               iounmap(reg);
++              return;
+       }
++
++      of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ }
+ CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init);
+@@ -328,10 +329,12 @@ static void __init of_pll_mux_clk_init(struct device_node *node)
+       clk = clk_register_mux(NULL, clk_name, (const char **)&parents,
+                               ARRAY_SIZE(parents) , 0, reg, shift, mask,
+                               0, NULL);
+-      if (clk)
+-              of_clk_add_provider(node, of_clk_src_simple_get, clk);
+-      else
++      if (IS_ERR(clk)) {
+               pr_err("%s: error registering mux %s\n", __func__, clk_name);
++              return;
++      }
++
++      of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ }
+ CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch b/queue-5.15/clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch
new file mode 100644 (file)
index 0000000..3f41437
--- /dev/null
@@ -0,0 +1,66 @@
+From f05e4cb17055005277c77564a9513ee8b9d18d19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Sep 2023 10:46:58 +0800
+Subject: clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 0d6e24b422a2166a9297a8286ff2e6ab9a5e8cd3 ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: e9862118272a ("clk: mediatek: Add MT2701 clock support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230901024658.23405-1-jiasheng@iscas.ac.cn
+Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt2701.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+index 695be0f774270..c67cd73aca171 100644
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -675,6 +675,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                                               clk_data);
+@@ -742,6 +744,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node)
+       if (!infra_clk_data) {
+               infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
++              if (!infra_clk_data)
++                      return;
+               for (i = 0; i < CLK_INFRA_NR; i++)
+                       infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+@@ -768,6 +772,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
+       if (!infra_clk_data) {
+               infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
++              if (!infra_clk_data)
++                      return -ENOMEM;
+       } else {
+               for (i = 0; i < CLK_INFRA_NR; i++) {
+                       if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
+@@ -896,6 +902,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                                               clk_data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch b/queue-5.15/clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch
new file mode 100644 (file)
index 0000000..2694358
--- /dev/null
@@ -0,0 +1,56 @@
+From 07f6013877e72deff29b426f11ba2d8188126ce5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:34:03 +0800
+Subject: clk: mediatek: clk-mt6765: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit b82681042724924ae3ba0f2f2eeec217fa31e830 ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: 1aca9939bf72 ("clk: mediatek: Add MT6765 clock support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230912093407.21505-1-jiasheng@iscas.ac.cn
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt6765.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
+index d77ea5aff2920..17352342b6989 100644
+--- a/drivers/clk/mediatek/clk-mt6765.c
++++ b/drivers/clk/mediatek/clk-mt6765.c
+@@ -785,6 +785,8 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
+       }
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+@@ -820,6 +822,8 @@ static int clk_mt6765_top_probe(struct platform_device *pdev)
+       }
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
+                                   clk_data);
+@@ -860,6 +864,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev)
+       }
+       clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
+                              clk_data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch b/queue-5.15/clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch
new file mode 100644 (file)
index 0000000..d2ccb34
--- /dev/null
@@ -0,0 +1,47 @@
+From bd70ccf02e0ec0559e977bc1bd2ddb67ecd80737 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:34:04 +0800
+Subject: clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 1f57f78fbacf630430bf954e5a84caafdfea30c0 ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: 710774e04861 ("clk: mediatek: Add MT6779 clock support")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230912093407.21505-2-jiasheng@iscas.ac.cn
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt6779.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
+index 6e0d3a1667291..cf720651fc536 100644
+--- a/drivers/clk/mediatek/clk-mt6779.c
++++ b/drivers/clk/mediatek/clk-mt6779.c
+@@ -1216,6 +1216,8 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev)
+       struct device_node *node = pdev->dev.of_node;
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+@@ -1236,6 +1238,8 @@ static int clk_mt6779_top_probe(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch b/queue-5.15/clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch
new file mode 100644 (file)
index 0000000..2f61009
--- /dev/null
@@ -0,0 +1,56 @@
+From 8cb7e491e03e9d409ba1d3f8d53ca54b1d3c48cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:34:05 +0800
+Subject: clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 606f6366a35a3329545e38129804d65ef26ed7d2 ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: 96596aa06628 ("clk: mediatek: add clk support for MT6797")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230912093407.21505-3-jiasheng@iscas.ac.cn
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt6797.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
+index 428eb24ffec55..98d456023f4e4 100644
+--- a/drivers/clk/mediatek/clk-mt6797.c
++++ b/drivers/clk/mediatek/clk-mt6797.c
+@@ -391,6 +391,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
+                                clk_data);
+@@ -563,6 +565,8 @@ static void mtk_infrasys_init_early(struct device_node *node)
+       if (!infra_clk_data) {
+               infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
++              if (!infra_clk_data)
++                      return;
+               for (i = 0; i < CLK_INFRA_NR; i++)
+                       infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+@@ -587,6 +591,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
+       if (!infra_clk_data) {
+               infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
++              if (!infra_clk_data)
++                      return -ENOMEM;
+       } else {
+               for (i = 0; i < CLK_INFRA_NR; i++) {
+                       if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch b/queue-5.15/clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch
new file mode 100644 (file)
index 0000000..1e6cdae
--- /dev/null
@@ -0,0 +1,56 @@
+From f8d533ac0c023bfea138a1bc41fb12d3e80882a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:34:07 +0800
+Subject: clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 2befa515c1bb6cdd33c262b909d93d1973a219aa ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: 3b5e748615e7 ("clk: mediatek: add clock support for MT7629 SoC")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230912093407.21505-5-jiasheng@iscas.ac.cn
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt7629.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
+index a0ee079670c7e..f791e53b812ab 100644
+--- a/drivers/clk/mediatek/clk-mt7629.c
++++ b/drivers/clk/mediatek/clk-mt7629.c
+@@ -580,6 +580,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+@@ -603,6 +605,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
+       struct clk_onecell_data *clk_data;
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+                              clk_data);
+@@ -626,6 +630,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)
+               return PTR_ERR(base);
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+                              clk_data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch b/queue-5.15/clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch
new file mode 100644 (file)
index 0000000..05217f7
--- /dev/null
@@ -0,0 +1,47 @@
+From 8bfe49196be6c6f670d0b13a82621495aa7bb10f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 17:34:06 +0800
+Subject: clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 0884393c63cc9a1772f7121a6645ba7bd76feeb9 ]
+
+Add the check for the return value of mtk_alloc_clk_data() in order to
+avoid NULL pointer dereference.
+
+Fixes: 3b5e748615e7 ("clk: mediatek: add clock support for MT7629 SoC")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230912093407.21505-4-jiasheng@iscas.ac.cn
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt7629-eth.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt7629-eth.c b/drivers/clk/mediatek/clk-mt7629-eth.c
+index 88279d0ea1a76..3ab7b672f8c70 100644
+--- a/drivers/clk/mediatek/clk-mt7629-eth.c
++++ b/drivers/clk/mediatek/clk-mt7629-eth.c
+@@ -83,6 +83,8 @@ static int clk_mt7629_ethsys_init(struct platform_device *pdev)
+       int r;
+       clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data);
+@@ -105,6 +107,8 @@ static int clk_mt7629_sgmiisys_init(struct platform_device *pdev)
+       int r;
+       clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
++      if (!clk_data)
++              return -ENOMEM;
+       mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK,
+                              clk_data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-npcm7xx-fix-incorrect-kfree.patch b/queue-5.15/clk-npcm7xx-fix-incorrect-kfree.patch
new file mode 100644 (file)
index 0000000..9729c0c
--- /dev/null
@@ -0,0 +1,45 @@
+From 5595f28a9c086eda9a4591e7066e87e4f8f99413 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Sep 2023 15:31:27 +0200
+Subject: clk: npcm7xx: Fix incorrect kfree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
+
+[ Upstream commit bbc5080bef4a245106aa8e8d424ba8847ca7c0ca ]
+
+The corresponding allocation is:
+
+> npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws,
+>                           NPCM7XX_NUM_CLOCKS), GFP_KERNEL);
+
+... so, kfree should be applied to npcm7xx_clk_data, not
+npcm7xx_clk_data->hws.
+
+Fixes: fcfd14369856 ("clk: npcm7xx: add clock controller")
+Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
+Link: https://lore.kernel.org/r/20230923133127.1815621-1-j.neuschaefer@gmx.net
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-npcm7xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
+index e677bb5a784b9..c10f04f9070a5 100644
+--- a/drivers/clk/clk-npcm7xx.c
++++ b/drivers/clk/clk-npcm7xx.c
+@@ -539,7 +539,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
+       return;
+ npcm7xx_init_fail:
+-      kfree(npcm7xx_clk_data->hws);
++      kfree(npcm7xx_clk_data);
+ npcm7xx_init_np_err:
+       iounmap(clk_base);
+ npcm7xx_init_error:
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch b/queue-5.15/clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch
new file mode 100644 (file)
index 0000000..929be5f
--- /dev/null
@@ -0,0 +1,57 @@
+From 20b4e82214a052df587655e66af5ec6b94b9a3ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Sep 2023 13:06:40 +0530
+Subject: clk: qcom: clk-rcg2: Fix clock rate overflow for high parent
+ frequencies
+
+From: Devi Priya <quic_devipriy@quicinc.com>
+
+[ Upstream commit f7b7d30158cff246667273bd2a62fc93ee0725d2 ]
+
+If the parent clock rate is greater than unsigned long max/2 then
+integer overflow happens when calculating the clock rate on 32-bit systems.
+As RCG2 uses half integer dividers, the clock rate is first being
+multiplied by 2 which will overflow the unsigned long max value.
+Hence, replace the common pattern of doing 64-bit multiplication
+and then a do_div() call with simpler mult_frac call.
+
+Fixes: bcd61c0f535a ("clk: qcom: Add support for root clock generators (RCGs)")
+Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Link: https://lore.kernel.org/r/20230901073640.4973-1-quic_devipriy@quicinc.com
+[bjorn: Also drop unnecessary {} around single statements]
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg2.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index c3823cc32edc6..f3c225ed57377 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -148,17 +148,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
+ static unsigned long
+ calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
+ {
+-      if (hid_div) {
+-              rate *= 2;
+-              rate /= hid_div + 1;
+-      }
++      if (hid_div)
++              rate = mult_frac(rate, 2, hid_div + 1);
+-      if (mode) {
+-              u64 tmp = rate;
+-              tmp *= m;
+-              do_div(tmp, n);
+-              rate = tmp;
+-      }
++      if (mode)
++              rate = mult_frac(rate, m, n);
+       return rate;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch b/queue-5.15/clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch
new file mode 100644 (file)
index 0000000..67f3e66
--- /dev/null
@@ -0,0 +1,41 @@
+From 0ee71b3a9b744bccc836be50094481e8f7c39c41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 11:49:31 +0530
+Subject: clk: qcom: config IPQ_APSS_6018 should depend on QCOM_SMEM
+
+From: Varadarajan Narayanan <quic_varada@quicinc.com>
+
+[ Upstream commit 6a15647d0adc686226045e8046369f34d6ab03ed ]
+
+The config IPQ_APSS_6018 should depend on QCOM_SMEM, to
+avoid the following error reported by 'kernel test robot'
+
+       loongarch64-linux-ld: drivers/clk/qcom/apss-ipq6018.o: in function `apss_ipq6018_probe':
+       >> apss-ipq6018.c:(.text+0xd0): undefined reference to `qcom_smem_get_soc_id'
+
+Fixes: 5e77b4ef1b19 ("clk: qcom: Add ipq6018 apss clock controller")
+Reported-by: kernel test robot <yujie.liu@intel.com>
+Closes: https://lore.kernel.org/r/202310181650.g8THtfsm-lkp@intel.com/
+Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
+Link: https://lore.kernel.org/r/f4c4d65a7cb71e807d6d472c63c7718408c8f5f0.1697781921.git.quic_varada@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
+index 6ba86cffc4135..4c8bb23ca7304 100644
+--- a/drivers/clk/qcom/Kconfig
++++ b/drivers/clk/qcom/Kconfig
+@@ -127,6 +127,7 @@ config IPQ_APSS_6018
+       tristate "IPQ APSS Clock Controller"
+       select IPQ_APSS_PLL
+       depends on QCOM_APCS_IPC || COMPILE_TEST
++      depends on QCOM_SMEM
+       help
+         Support for APSS clock controller on IPQ platforms. The
+         APSS clock controller manages the Mux and enable block that feeds the
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8996-drop-unsupported-clock-sources.patch b/queue-5.15/clk-qcom-gcc-msm8996-drop-unsupported-clock-sources.patch
new file mode 100644 (file)
index 0000000..9c05275
--- /dev/null
@@ -0,0 +1,123 @@
+From 6deb0edb736574297922aed9e13ccedb386f1b4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 07:54:12 +0300
+Subject: clk: qcom: gcc-msm8996: drop unsupported clock sources
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b554a687b4971ae137e92ee3feddc38e85a38d60 ]
+
+In preparation of updating the msm8996 gcc driver, drop all unsupported
+GPLL sources (gpll1/gpll1_early_div, gpll2/gpll2_early and gpll3).
+Downstream kernel also does not provide support for these GPLL sources,
+so it is safe to drop them.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20211228045415.20543-14-dmitry.baryshkov@linaro.org
+Stable-dep-of: 4afda5f6bcdf ("clk: qcom: gcc-msm8996: Remove RPM bus clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8996.c | 55 ++++------------------------------
+ 1 file changed, 6 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index d95814025c65e..4c85b3935a819 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -27,15 +27,10 @@
+ enum {
+       P_XO,
+       P_GPLL0,
+-      P_GPLL2,
+-      P_GPLL3,
+-      P_GPLL1,
+-      P_GPLL2_EARLY,
+       P_GPLL0_EARLY_DIV,
+       P_SLEEP_CLK,
+       P_GPLL4,
+       P_AUD_REF_CLK,
+-      P_GPLL1_EARLY_DIV
+ };
+ static const struct parent_map gcc_sleep_clk_map[] = {
+@@ -130,44 +125,6 @@ static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
+       "gpll0_early_div"
+ };
+-static const struct parent_map gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_GPLL1_EARLY_DIV, 3 },
+-      { P_GPLL1, 4 },
+-      { P_GPLL4, 5 },
+-      { P_GPLL0_EARLY_DIV, 6 }
+-};
+-
+-static const char * const gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll1_early_div",
+-      "gpll1",
+-      "gpll4",
+-      "gpll0_early_div"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_GPLL2, 2 },
+-      { P_GPLL3, 3 },
+-      { P_GPLL1, 4 },
+-      { P_GPLL2_EARLY, 5 },
+-      { P_GPLL0_EARLY_DIV, 6 }
+-};
+-
+-static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll2",
+-      "gpll3",
+-      "gpll1",
+-      "gpll2_early",
+-      "gpll0_early_div"
+-};
+-
+ static struct clk_fixed_factor xo = {
+       .mult = 1,
+       .div = 1,
+@@ -285,12 +242,12 @@ static const struct freq_tbl ftbl_system_noc_clk_src[] = {
+ static struct clk_rcg2 system_noc_clk_src = {
+       .cmd_rcgr = 0x0401c,
+       .hid_width = 5,
+-      .parent_map = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div_map,
++      .parent_map = gcc_xo_gpll0_gpll0_early_div_map,
+       .freq_tbl = ftbl_system_noc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "system_noc_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div,
+-              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div),
++              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1257,12 +1214,12 @@ static const struct freq_tbl ftbl_qspi_ser_clk_src[] = {
+ static struct clk_rcg2 qspi_ser_clk_src = {
+       .cmd_rcgr = 0x8b00c,
+       .hid_width = 5,
+-      .parent_map = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map,
++      .parent_map = gcc_xo_gpll0_gpll4_gpll0_early_div_map,
+       .freq_tbl = ftbl_qspi_ser_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qspi_ser_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div,
+-              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div),
++              .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8996-move-clock-parent-tables-down.patch b/queue-5.15/clk-qcom-gcc-msm8996-move-clock-parent-tables-down.patch
new file mode 100644 (file)
index 0000000..157f7d3
--- /dev/null
@@ -0,0 +1,228 @@
+From 2a8dabd8d0b8c34e0d9370ba081e1277d05f94e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 07:54:13 +0300
+Subject: clk: qcom: gcc-msm8996: move clock parent tables down
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1a2789cff03ccdeb70084157387f4a7bf4d2099f ]
+
+Move clock parent tables down, after the GPLL declrataions, so that we
+can use gpll hw clock fields in the next commit.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20211228045415.20543-15-dmitry.baryshkov@linaro.org
+Stable-dep-of: 4afda5f6bcdf ("clk: qcom: gcc-msm8996: Remove RPM bus clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8996.c | 184 ++++++++++++++++-----------------
+ 1 file changed, 92 insertions(+), 92 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index 4c85b3935a819..8531f2f3665fe 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -33,98 +33,6 @@ enum {
+       P_AUD_REF_CLK,
+ };
+-static const struct parent_map gcc_sleep_clk_map[] = {
+-      { P_SLEEP_CLK, 5 }
+-};
+-
+-static const char * const gcc_sleep_clk[] = {
+-      "sleep_clk"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 }
+-};
+-
+-static const char * const gcc_xo_gpll0[] = {
+-      "xo",
+-      "gpll0"
+-};
+-
+-static const struct parent_map gcc_xo_sleep_clk_map[] = {
+-      { P_XO, 0 },
+-      { P_SLEEP_CLK, 5 }
+-};
+-
+-static const char * const gcc_xo_sleep_clk[] = {
+-      "xo",
+-      "sleep_clk"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_gpll0_early_div_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_GPLL0_EARLY_DIV, 6 }
+-};
+-
+-static const char * const gcc_xo_gpll0_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll0_early_div"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_GPLL4, 5 }
+-};
+-
+-static const char * const gcc_xo_gpll0_gpll4[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll4"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_AUD_REF_CLK, 2 }
+-};
+-
+-static const char * const gcc_xo_gpll0_aud_ref_clk[] = {
+-      "xo",
+-      "gpll0",
+-      "aud_ref_clk"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_sleep_clk_gpll0_early_div_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_SLEEP_CLK, 5 },
+-      { P_GPLL0_EARLY_DIV, 6 }
+-};
+-
+-static const char * const gcc_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "sleep_clk",
+-      "gpll0_early_div"
+-};
+-
+-static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = {
+-      { P_XO, 0 },
+-      { P_GPLL0, 1 },
+-      { P_GPLL4, 5 },
+-      { P_GPLL0_EARLY_DIV, 6 }
+-};
+-
+-static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll4",
+-      "gpll0_early_div"
+-};
+-
+ static struct clk_fixed_factor xo = {
+       .mult = 1,
+       .div = 1,
+@@ -229,6 +137,98 @@ static struct clk_alpha_pll_postdiv gpll4 = {
+       },
+ };
++static const struct parent_map gcc_sleep_clk_map[] = {
++      { P_SLEEP_CLK, 5 }
++};
++
++static const char * const gcc_sleep_clk[] = {
++      "sleep_clk"
++};
++
++static const struct parent_map gcc_xo_gpll0_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 }
++};
++
++static const char * const gcc_xo_gpll0[] = {
++      "xo",
++      "gpll0"
++};
++
++static const struct parent_map gcc_xo_sleep_clk_map[] = {
++      { P_XO, 0 },
++      { P_SLEEP_CLK, 5 }
++};
++
++static const char * const gcc_xo_sleep_clk[] = {
++      "xo",
++      "sleep_clk"
++};
++
++static const struct parent_map gcc_xo_gpll0_gpll0_early_div_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 },
++      { P_GPLL0_EARLY_DIV, 6 }
++};
++
++static const char * const gcc_xo_gpll0_gpll0_early_div[] = {
++      "xo",
++      "gpll0",
++      "gpll0_early_div"
++};
++
++static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 },
++      { P_GPLL4, 5 }
++};
++
++static const char * const gcc_xo_gpll0_gpll4[] = {
++      "xo",
++      "gpll0",
++      "gpll4"
++};
++
++static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 },
++      { P_AUD_REF_CLK, 2 }
++};
++
++static const char * const gcc_xo_gpll0_aud_ref_clk[] = {
++      "xo",
++      "gpll0",
++      "aud_ref_clk"
++};
++
++static const struct parent_map gcc_xo_gpll0_sleep_clk_gpll0_early_div_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 },
++      { P_SLEEP_CLK, 5 },
++      { P_GPLL0_EARLY_DIV, 6 }
++};
++
++static const char * const gcc_xo_gpll0_sleep_clk_gpll0_early_div[] = {
++      "xo",
++      "gpll0",
++      "sleep_clk",
++      "gpll0_early_div"
++};
++
++static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = {
++      { P_XO, 0 },
++      { P_GPLL0, 1 },
++      { P_GPLL4, 5 },
++      { P_GPLL0_EARLY_DIV, 6 }
++};
++
++static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
++      "xo",
++      "gpll0",
++      "gpll4",
++      "gpll0_early_div"
++};
++
+ static const struct freq_tbl ftbl_system_noc_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch b/queue-5.15/clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch
new file mode 100644 (file)
index 0000000..f87c10c
--- /dev/null
@@ -0,0 +1,521 @@
+From 783e6719b00d27745f10d2aeb57ad31cbeeeb7c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 11:39:14 +0200
+Subject: clk: qcom: gcc-msm8996: Remove RPM bus clocks
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 4afda5f6bcdf673ef2556fcfa458daf3a5a648d8 ]
+
+The GCC driver contains clocks that are owned (meaning configured and
+scaled) by the RPM core.
+
+Remove them from Linux to stop interjecting the RPM's logic.
+
+Fixes: b1e010c0730a ("clk: qcom: Add MSM8996 Global Clock Control (GCC) driver")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230830-topic-rpmbusclocks8996gcc-v1-1-9e99bedcdc3b@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8996.c | 237 +--------------------------------
+ 1 file changed, 5 insertions(+), 232 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index 6b36024583b4a..2d79a73da1055 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -245,71 +245,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
+       { .hw = &gpll0_early_div.hw }
+ };
+-static const struct freq_tbl ftbl_system_noc_clk_src[] = {
+-      F(19200000, P_XO, 1, 0, 0),
+-      F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
+-      F(100000000, P_GPLL0, 6, 0, 0),
+-      F(150000000, P_GPLL0, 4, 0, 0),
+-      F(200000000, P_GPLL0, 3, 0, 0),
+-      F(240000000, P_GPLL0, 2.5, 0, 0),
+-      { }
+-};
+-
+-static struct clk_rcg2 system_noc_clk_src = {
+-      .cmd_rcgr = 0x0401c,
+-      .hid_width = 5,
+-      .parent_map = gcc_xo_gpll0_gpll0_early_div_map,
+-      .freq_tbl = ftbl_system_noc_clk_src,
+-      .clkr.hw.init = &(struct clk_init_data){
+-              .name = "system_noc_clk_src",
+-              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+-              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+-              .ops = &clk_rcg2_ops,
+-      },
+-};
+-
+-static const struct freq_tbl ftbl_config_noc_clk_src[] = {
+-      F(19200000, P_XO, 1, 0, 0),
+-      F(37500000, P_GPLL0, 16, 0, 0),
+-      F(75000000, P_GPLL0, 8, 0, 0),
+-      { }
+-};
+-
+-static struct clk_rcg2 config_noc_clk_src = {
+-      .cmd_rcgr = 0x0500c,
+-      .hid_width = 5,
+-      .parent_map = gcc_xo_gpll0_map,
+-      .freq_tbl = ftbl_config_noc_clk_src,
+-      .clkr.hw.init = &(struct clk_init_data){
+-              .name = "config_noc_clk_src",
+-              .parent_data = gcc_xo_gpll0,
+-              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+-              .ops = &clk_rcg2_ops,
+-      },
+-};
+-
+-static const struct freq_tbl ftbl_periph_noc_clk_src[] = {
+-      F(19200000, P_XO, 1, 0, 0),
+-      F(37500000, P_GPLL0, 16, 0, 0),
+-      F(50000000, P_GPLL0, 12, 0, 0),
+-      F(75000000, P_GPLL0, 8, 0, 0),
+-      F(100000000, P_GPLL0, 6, 0, 0),
+-      { }
+-};
+-
+-static struct clk_rcg2 periph_noc_clk_src = {
+-      .cmd_rcgr = 0x06014,
+-      .hid_width = 5,
+-      .parent_map = gcc_xo_gpll0_map,
+-      .freq_tbl = ftbl_periph_noc_clk_src,
+-      .clkr.hw.init = &(struct clk_init_data){
+-              .name = "periph_noc_clk_src",
+-              .parent_data = gcc_xo_gpll0,
+-              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+-              .ops = &clk_rcg2_ops,
+-      },
+-};
+-
+ static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(120000000, P_GPLL0, 5, 0, 0),
+@@ -1298,11 +1233,7 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_noc_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
++                      .flags = CLK_IGNORE_UNUSED,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1465,11 +1396,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_phy_cfg_ahb2phy_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1499,11 +1425,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1550,11 +1471,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1584,11 +1500,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc3_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1618,11 +1529,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1636,11 +1542,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -1978,11 +1879,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2319,11 +2215,6 @@ static struct clk_branch gcc_pdm_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2354,11 +2245,6 @@ static struct clk_branch gcc_prng_ahb_clk = {
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2371,11 +2257,6 @@ static struct clk_branch gcc_tsif_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2423,11 +2304,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2521,11 +2397,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_slv_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2538,11 +2409,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_mstr_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2555,11 +2421,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2607,11 +2468,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_slv_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2624,11 +2480,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_mstr_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2641,11 +2492,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2693,11 +2539,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_slv_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2710,11 +2551,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_mstr_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2727,11 +2563,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2779,11 +2610,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_phy_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -2830,11 +2656,6 @@ static struct clk_branch gcc_ufs_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3061,11 +2882,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_snoc_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
++                      .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3078,11 +2895,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_cnoc_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
++                      .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3095,11 +2908,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_aggre0_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
++                      .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3112,11 +2921,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_aggre0_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
++                      .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3163,10 +2968,6 @@ static struct clk_branch gcc_dcc_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3179,10 +2980,6 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3195,11 +2992,6 @@ static struct clk_branch gcc_qspi_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &periph_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+-                      .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3348,10 +3140,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_cfg_ahb_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &config_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3364,10 +3152,6 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_mnoc_bimc_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3380,10 +3164,6 @@ static struct clk_branch gcc_mss_snoc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_snoc_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3396,10 +3176,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+-                      .parent_hws = (const struct clk_hw*[]){
+-                              &system_noc_clk_src.clkr.hw,
+-                      },
+-                      .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+@@ -3495,9 +3271,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
+       [GPLL0] = &gpll0.clkr,
+       [GPLL4_EARLY] = &gpll4_early.clkr,
+       [GPLL4] = &gpll4.clkr,
+-      [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
+-      [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
+-      [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
+       [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+       [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+       [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8996-use-array_size-instead-of-speci.patch b/queue-5.15/clk-qcom-gcc-msm8996-use-array_size-instead-of-speci.patch
new file mode 100644 (file)
index 0000000..33cefd1
--- /dev/null
@@ -0,0 +1,579 @@
+From fb74a203f8a020b7db1e36bf34c90943cf3233b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 07:54:11 +0300
+Subject: clk: qcom: gcc-msm8996: use ARRAY_SIZE instead of specifying
+ num_parents
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit ed96df3d461eeb2c40cb06ca5fd51644d0f4a2c0 ]
+
+Use ARRAY_SIZE() instead of manually specifying num_parents. This makes
+adding/removing entries to/from parent_data easy and errorproof.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20211228045415.20543-13-dmitry.baryshkov@linaro.org
+Stable-dep-of: 4afda5f6bcdf ("clk: qcom: gcc-msm8996: Remove RPM bus clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8996.c | 122 ++++++++++++++++-----------------
+ 1 file changed, 61 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index 9b1674b28d45d..d95814025c65e 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -290,7 +290,7 @@ static struct clk_rcg2 system_noc_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "system_noc_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div,
+-              .num_parents = 7,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -310,7 +310,7 @@ static struct clk_rcg2 config_noc_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "config_noc_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -332,7 +332,7 @@ static struct clk_rcg2 periph_noc_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "periph_noc_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -353,7 +353,7 @@ static struct clk_rcg2 usb30_master_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_master_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_early_div,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -371,7 +371,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_mock_utmi_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_early_div,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -389,7 +389,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb3_phy_aux_clk_src",
+               .parent_names = gcc_xo_sleep_clk,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -408,7 +408,7 @@ static struct clk_rcg2 usb20_master_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_master_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_early_div,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -421,7 +421,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_mock_utmi_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_early_div,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -447,7 +447,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
+-              .num_parents = 4,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_floor_ops,
+       },
+ };
+@@ -467,7 +467,7 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
+-              .num_parents = 4,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -492,7 +492,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc2_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll4,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4),
+               .ops = &clk_rcg2_floor_ops,
+       },
+ };
+@@ -506,7 +506,7 @@ static struct clk_rcg2 sdcc3_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc3_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll4,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4),
+               .ops = &clk_rcg2_floor_ops,
+       },
+ };
+@@ -530,7 +530,7 @@ static struct clk_rcg2 sdcc4_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc4_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_floor_ops,
+       },
+ };
+@@ -555,7 +555,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -574,7 +574,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -607,7 +607,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -621,7 +621,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -634,7 +634,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -648,7 +648,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -662,7 +662,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -675,7 +675,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -689,7 +689,7 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart3_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -703,7 +703,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -716,7 +716,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -730,7 +730,7 @@ static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart4_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -744,7 +744,7 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -757,7 +757,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -771,7 +771,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart5_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -785,7 +785,7 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -798,7 +798,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -812,7 +812,7 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart6_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -826,7 +826,7 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -839,7 +839,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -853,7 +853,7 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart1_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -867,7 +867,7 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -880,7 +880,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -894,7 +894,7 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart2_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -908,7 +908,7 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -921,7 +921,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -935,7 +935,7 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart3_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -949,7 +949,7 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -962,7 +962,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -976,7 +976,7 @@ static struct clk_rcg2 blsp2_uart4_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart4_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -990,7 +990,7 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup5_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1003,7 +1003,7 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup5_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1017,7 +1017,7 @@ static struct clk_rcg2 blsp2_uart5_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart5_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1031,7 +1031,7 @@ static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup6_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1044,7 +1044,7 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup6_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1058,7 +1058,7 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart6_apps_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1076,7 +1076,7 @@ static struct clk_rcg2 pdm2_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pdm2_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1095,7 +1095,7 @@ static struct clk_rcg2 tsif_ref_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "tsif_ref_clk_src",
+               .parent_names = gcc_xo_gpll0_aud_ref_clk,
+-              .num_parents = 3,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_aud_ref_clk),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1107,7 +1107,7 @@ static struct clk_rcg2 gcc_sleep_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sleep_clk_src",
+               .parent_names = gcc_sleep_clk,
+-              .num_parents = 1,
++              .num_parents = ARRAY_SIZE(gcc_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1120,7 +1120,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_rbcpr_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1132,7 +1132,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_gpll0_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1153,7 +1153,7 @@ static struct clk_rcg2 gp1_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+               .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+-              .num_parents = 4,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1167,7 +1167,7 @@ static struct clk_rcg2 gp2_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+               .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+-              .num_parents = 4,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1181,7 +1181,7 @@ static struct clk_rcg2 gp3_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+               .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+-              .num_parents = 4,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1200,7 +1200,7 @@ static struct clk_rcg2 pcie_aux_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie_aux_clk_src",
+               .parent_names = gcc_xo_sleep_clk,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1221,7 +1221,7 @@ static struct clk_rcg2 ufs_axi_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_axi_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1241,7 +1241,7 @@ static struct clk_rcg2 ufs_ice_core_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_ice_core_clk_src",
+               .parent_names = gcc_xo_gpll0,
+-              .num_parents = 2,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+@@ -1262,7 +1262,7 @@ static struct clk_rcg2 qspi_ser_clk_src = {
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qspi_ser_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div,
+-              .num_parents = 6,
++              .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-msm8996-use-parent_hws-_data-instead-of.patch b/queue-5.15/clk-qcom-gcc-msm8996-use-parent_hws-_data-instead-of.patch
new file mode 100644 (file)
index 0000000..4c44803
--- /dev/null
@@ -0,0 +1,2060 @@
+From 2c539d7b261e3a9e80e634d0a8dbb891641c152b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Dec 2021 07:54:14 +0300
+Subject: clk: qcom: gcc-msm8996: use parent_hws/_data instead of parent_names
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b3867679d460d67aaef5aa76e4512197a5375514 ]
+
+Convert the clock driver to specify parent data rather than parent
+names, to actually bind using 'clock-names' specified in the DTS rather
+than global clock names. Use parent_hws where possible to refer parent
+clocks directly, skipping the lookup.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20211228045415.20543-16-dmitry.baryshkov@linaro.org
+Stable-dep-of: 4afda5f6bcdf ("clk: qcom: gcc-msm8996: Remove RPM bus clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8996.c | 678 ++++++++++++++++++++++-----------
+ 1 file changed, 463 insertions(+), 215 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index 8531f2f3665fe..6b36024583b4a 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -38,7 +38,9 @@ static struct clk_fixed_factor xo = {
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "xo",
+-              .parent_names = (const char *[]){ "xo_board" },
++              .parent_data = &(const struct clk_parent_data){
++                      .fw_name = "cxo", .name = "xo_board",
++              },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+@@ -52,7 +54,9 @@ static struct clk_alpha_pll gpll0_early = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_early",
+-                      .parent_names = (const char *[]){ "xo" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &xo.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+@@ -64,7 +68,9 @@ static struct clk_fixed_factor gpll0_early_div = {
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_early_div",
+-              .parent_names = (const char *[]){ "gpll0_early" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &gpll0_early.clkr.hw,
++              },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+@@ -75,7 +81,9 @@ static struct clk_alpha_pll_postdiv gpll0 = {
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+-              .parent_names = (const char *[]){ "gpll0_early" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &gpll0_early.clkr.hw,
++              },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+@@ -88,7 +96,9 @@ static struct clk_branch gcc_mmss_gpll0_div_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_gpll0_div_clk",
+-                      .parent_names = (const char *[]){ "gpll0" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gpll0.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -103,7 +113,9 @@ static struct clk_branch gcc_mss_gpll0_div_clk = {
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_gpll0_div_clk",
+-                      .parent_names = (const char *[]){ "gpll0" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gpll0.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops
+@@ -119,7 +131,9 @@ static struct clk_alpha_pll gpll4_early = {
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4_early",
+-                      .parent_names = (const char *[]){ "xo" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &xo.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+@@ -131,7 +145,9 @@ static struct clk_alpha_pll_postdiv gpll4 = {
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll4",
+-              .parent_names = (const char *[]){ "gpll4_early" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &gpll4_early.clkr.hw,
++              },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+@@ -141,8 +157,8 @@ static const struct parent_map gcc_sleep_clk_map[] = {
+       { P_SLEEP_CLK, 5 }
+ };
+-static const char * const gcc_sleep_clk[] = {
+-      "sleep_clk"
++static const struct clk_parent_data gcc_sleep_clk[] = {
++      { .fw_name = "sleep_clk", .name = "sleep_clk" }
+ };
+ static const struct parent_map gcc_xo_gpll0_map[] = {
+@@ -150,9 +166,9 @@ static const struct parent_map gcc_xo_gpll0_map[] = {
+       { P_GPLL0, 1 }
+ };
+-static const char * const gcc_xo_gpll0[] = {
+-      "xo",
+-      "gpll0"
++static const struct clk_parent_data gcc_xo_gpll0[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw }
+ };
+ static const struct parent_map gcc_xo_sleep_clk_map[] = {
+@@ -160,9 +176,9 @@ static const struct parent_map gcc_xo_sleep_clk_map[] = {
+       { P_SLEEP_CLK, 5 }
+ };
+-static const char * const gcc_xo_sleep_clk[] = {
+-      "xo",
+-      "sleep_clk"
++static const struct clk_parent_data gcc_xo_sleep_clk[] = {
++      { .hw = &xo.hw },
++      { .fw_name = "sleep_clk", .name = "sleep_clk" }
+ };
+ static const struct parent_map gcc_xo_gpll0_gpll0_early_div_map[] = {
+@@ -171,10 +187,10 @@ static const struct parent_map gcc_xo_gpll0_gpll0_early_div_map[] = {
+       { P_GPLL0_EARLY_DIV, 6 }
+ };
+-static const char * const gcc_xo_gpll0_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll0_early_div"
++static const struct clk_parent_data gcc_xo_gpll0_gpll0_early_div[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw },
++      { .hw = &gpll0_early_div.hw }
+ };
+ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
+@@ -183,10 +199,10 @@ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
+       { P_GPLL4, 5 }
+ };
+-static const char * const gcc_xo_gpll0_gpll4[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll4"
++static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw },
++      { .hw = &gpll4.clkr.hw }
+ };
+ static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = {
+@@ -195,10 +211,10 @@ static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = {
+       { P_AUD_REF_CLK, 2 }
+ };
+-static const char * const gcc_xo_gpll0_aud_ref_clk[] = {
+-      "xo",
+-      "gpll0",
+-      "aud_ref_clk"
++static const struct clk_parent_data gcc_xo_gpll0_aud_ref_clk[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw },
++      { .fw_name = "aud_ref_clk", .name = "aud_ref_clk" }
+ };
+ static const struct parent_map gcc_xo_gpll0_sleep_clk_gpll0_early_div_map[] = {
+@@ -208,11 +224,11 @@ static const struct parent_map gcc_xo_gpll0_sleep_clk_gpll0_early_div_map[] = {
+       { P_GPLL0_EARLY_DIV, 6 }
+ };
+-static const char * const gcc_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "sleep_clk",
+-      "gpll0_early_div"
++static const struct clk_parent_data gcc_xo_gpll0_sleep_clk_gpll0_early_div[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw },
++      { .fw_name = "sleep_clk", .name = "sleep_clk" },
++      { .hw = &gpll0_early_div.hw }
+ };
+ static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = {
+@@ -222,11 +238,11 @@ static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = {
+       { P_GPLL0_EARLY_DIV, 6 }
+ };
+-static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
+-      "xo",
+-      "gpll0",
+-      "gpll4",
+-      "gpll0_early_div"
++static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
++      { .hw = &xo.hw },
++      { .hw = &gpll0.clkr.hw },
++      { .hw = &gpll4.clkr.hw },
++      { .hw = &gpll0_early_div.hw }
+ };
+ static const struct freq_tbl ftbl_system_noc_clk_src[] = {
+@@ -246,7 +262,7 @@ static struct clk_rcg2 system_noc_clk_src = {
+       .freq_tbl = ftbl_system_noc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "system_noc_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -266,7 +282,7 @@ static struct clk_rcg2 config_noc_clk_src = {
+       .freq_tbl = ftbl_config_noc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "config_noc_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -288,7 +304,7 @@ static struct clk_rcg2 periph_noc_clk_src = {
+       .freq_tbl = ftbl_periph_noc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "periph_noc_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -309,7 +325,7 @@ static struct clk_rcg2 usb30_master_clk_src = {
+       .freq_tbl = ftbl_usb30_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_master_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -327,7 +343,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+       .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb30_mock_utmi_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -345,7 +361,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = {
+       .freq_tbl = ftbl_usb3_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb3_phy_aux_clk_src",
+-              .parent_names = gcc_xo_sleep_clk,
++              .parent_data = gcc_xo_sleep_clk,
+               .num_parents = ARRAY_SIZE(gcc_xo_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -364,7 +380,7 @@ static struct clk_rcg2 usb20_master_clk_src = {
+       .freq_tbl = ftbl_usb20_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_master_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -377,7 +393,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = {
+       .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb20_mock_utmi_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -403,7 +419,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .freq_tbl = ftbl_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll4_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_floor_ops,
+       },
+@@ -423,7 +439,7 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll4_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -448,7 +464,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .freq_tbl = ftbl_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc2_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll4,
++              .parent_data = gcc_xo_gpll0_gpll4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4),
+               .ops = &clk_rcg2_floor_ops,
+       },
+@@ -462,7 +478,7 @@ static struct clk_rcg2 sdcc3_apps_clk_src = {
+       .freq_tbl = ftbl_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc3_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll4,
++              .parent_data = gcc_xo_gpll0_gpll4,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4),
+               .ops = &clk_rcg2_floor_ops,
+       },
+@@ -486,7 +502,7 @@ static struct clk_rcg2 sdcc4_apps_clk_src = {
+       .freq_tbl = ftbl_sdcc4_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc4_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_floor_ops,
+       },
+@@ -511,7 +527,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -530,7 +546,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -563,7 +579,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -577,7 +593,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -590,7 +606,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -604,7 +620,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -618,7 +634,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -631,7 +647,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -645,7 +661,7 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart3_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -659,7 +675,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -672,7 +688,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -686,7 +702,7 @@ static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart4_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -700,7 +716,7 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -713,7 +729,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -727,7 +743,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart5_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -741,7 +757,7 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -754,7 +770,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -768,7 +784,7 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart6_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -782,7 +798,7 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -795,7 +811,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup1_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -809,7 +825,7 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart1_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -823,7 +839,7 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -836,7 +852,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup2_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -850,7 +866,7 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart2_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -864,7 +880,7 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -877,7 +893,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup3_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -891,7 +907,7 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart3_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -905,7 +921,7 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -918,7 +934,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup4_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -932,7 +948,7 @@ static struct clk_rcg2 blsp2_uart4_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart4_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -946,7 +962,7 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup5_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -959,7 +975,7 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup5_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -973,7 +989,7 @@ static struct clk_rcg2 blsp2_uart5_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart5_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -987,7 +1003,7 @@ static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup6_spi_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1000,7 +1016,7 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_qup6_i2c_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1014,7 +1030,7 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = {
+       .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp2_uart6_apps_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1032,7 +1048,7 @@ static struct clk_rcg2 pdm2_clk_src = {
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pdm2_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1051,7 +1067,7 @@ static struct clk_rcg2 tsif_ref_clk_src = {
+       .freq_tbl = ftbl_tsif_ref_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "tsif_ref_clk_src",
+-              .parent_names = gcc_xo_gpll0_aud_ref_clk,
++              .parent_data = gcc_xo_gpll0_aud_ref_clk,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_aud_ref_clk),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1063,7 +1079,7 @@ static struct clk_rcg2 gcc_sleep_clk_src = {
+       .parent_map = gcc_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sleep_clk_src",
+-              .parent_names = gcc_sleep_clk,
++              .parent_data = gcc_sleep_clk,
+               .num_parents = ARRAY_SIZE(gcc_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1076,7 +1092,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = {
+       .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_rbcpr_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1088,7 +1104,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = {
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hmss_gpll0_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1109,7 +1125,7 @@ static struct clk_rcg2 gp1_clk_src = {
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+-              .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1123,7 +1139,7 @@ static struct clk_rcg2 gp2_clk_src = {
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+-              .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1137,7 +1153,7 @@ static struct clk_rcg2 gp3_clk_src = {
+       .freq_tbl = ftbl_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+-              .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_sleep_clk_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1156,7 +1172,7 @@ static struct clk_rcg2 pcie_aux_clk_src = {
+       .freq_tbl = ftbl_pcie_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie_aux_clk_src",
+-              .parent_names = gcc_xo_sleep_clk,
++              .parent_data = gcc_xo_sleep_clk,
+               .num_parents = ARRAY_SIZE(gcc_xo_sleep_clk),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1177,7 +1193,7 @@ static struct clk_rcg2 ufs_axi_clk_src = {
+       .freq_tbl = ftbl_ufs_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_axi_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1197,7 +1213,7 @@ static struct clk_rcg2 ufs_ice_core_clk_src = {
+       .freq_tbl = ftbl_ufs_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ufs_ice_core_clk_src",
+-              .parent_names = gcc_xo_gpll0,
++              .parent_data = gcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1218,7 +1234,7 @@ static struct clk_rcg2 qspi_ser_clk_src = {
+       .freq_tbl = ftbl_qspi_ser_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qspi_ser_clk_src",
+-              .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
++              .parent_data = gcc_xo_gpll0_gpll4_gpll0_early_div,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4_gpll0_early_div),
+               .ops = &clk_rcg2_ops,
+       },
+@@ -1231,7 +1247,9 @@ static struct clk_branch gcc_sys_noc_usb3_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_usb3_axi_clk",
+-                      .parent_names = (const char *[]){ "usb30_master_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb30_master_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1246,7 +1264,9 @@ static struct clk_branch gcc_sys_noc_ufs_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_ufs_axi_clk",
+-                      .parent_names = (const char *[]){ "ufs_axi_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_axi_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1261,7 +1281,9 @@ static struct clk_branch gcc_periph_noc_usb20_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_periph_noc_usb20_ahb_clk",
+-                      .parent_names = (const char *[]){ "usb20_master_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb20_master_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1276,7 +1298,9 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mmss_noc_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+                       .ops = &clk_branch2_ops,
+@@ -1304,7 +1328,9 @@ static struct clk_branch gcc_usb30_master_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_master_clk",
+-                      .parent_names = (const char *[]){ "usb30_master_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb30_master_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1319,7 +1345,9 @@ static struct clk_branch gcc_usb30_sleep_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_sleep_clk",
+-                      .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gcc_sleep_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1334,7 +1362,9 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_mock_utmi_clk",
+-                      .parent_names = (const char *[]){ "usb30_mock_utmi_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb30_mock_utmi_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1349,7 +1379,9 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_aux_clk",
+-                      .parent_names = (const char *[]){ "usb3_phy_aux_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb3_phy_aux_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1365,7 +1397,9 @@ static struct clk_branch gcc_usb3_phy_pipe_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_phy_pipe_clk",
+-                      .parent_names = (const char *[]){ "usb3_phy_pipe_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "usb3_phy_pipe_clk_src", .name = "usb3_phy_pipe_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1380,7 +1414,9 @@ static struct clk_branch gcc_usb20_master_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_master_clk",
+-                      .parent_names = (const char *[]){ "usb20_master_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb20_master_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1395,7 +1431,9 @@ static struct clk_branch gcc_usb20_sleep_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_sleep_clk",
+-                      .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gcc_sleep_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1410,7 +1448,9 @@ static struct clk_branch gcc_usb20_mock_utmi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb20_mock_utmi_clk",
+-                      .parent_names = (const char *[]){ "usb20_mock_utmi_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb20_mock_utmi_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1425,7 +1465,9 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb_phy_cfg_ahb2phy_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1440,7 +1482,9 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+-                      .parent_names = (const char *[]){ "sdcc1_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &sdcc1_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1455,7 +1499,9 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1470,7 +1516,9 @@ static struct clk_branch gcc_sdcc1_ice_core_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+-                      .parent_names = (const char *[]){ "sdcc1_ice_core_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &sdcc1_ice_core_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1485,7 +1533,9 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+-                      .parent_names = (const char *[]){ "sdcc2_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &sdcc2_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1500,7 +1550,9 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1515,7 +1567,9 @@ static struct clk_branch gcc_sdcc3_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc3_apps_clk",
+-                      .parent_names = (const char *[]){ "sdcc3_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &sdcc3_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1530,7 +1584,9 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc3_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1545,7 +1601,9 @@ static struct clk_branch gcc_sdcc4_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_apps_clk",
+-                      .parent_names = (const char *[]){ "sdcc4_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &sdcc4_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1560,7 +1618,9 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc4_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1576,7 +1636,9 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1592,7 +1654,9 @@ static struct clk_branch gcc_blsp1_sleep_clk = {
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_sleep_clk",
+-                      .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gcc_sleep_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1607,7 +1671,9 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup1_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup1_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1622,7 +1688,9 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup1_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1637,7 +1705,9 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart1_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart1_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1652,7 +1722,9 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup2_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup2_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1667,7 +1739,9 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup2_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1682,7 +1756,9 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart2_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart2_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1697,7 +1773,9 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup3_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup3_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1712,7 +1790,9 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup3_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1727,7 +1807,9 @@ static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart3_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart3_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart3_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1742,7 +1824,9 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup4_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup4_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1757,7 +1841,9 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup4_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1772,7 +1858,9 @@ static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart4_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart4_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart4_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1787,7 +1875,9 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup5_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup5_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1802,7 +1892,9 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup5_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup5_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1817,7 +1909,9 @@ static struct clk_branch gcc_blsp1_uart5_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart5_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart5_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart5_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1832,7 +1926,9 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup6_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup6_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup6_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1847,7 +1943,9 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup6_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_qup6_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_qup6_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1862,7 +1960,9 @@ static struct clk_branch gcc_blsp1_uart6_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart6_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp1_uart6_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp1_uart6_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1878,7 +1978,9 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1894,7 +1996,9 @@ static struct clk_branch gcc_blsp2_sleep_clk = {
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_sleep_clk",
+-                      .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gcc_sleep_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1909,7 +2013,9 @@ static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup1_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup1_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup1_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1924,7 +2030,9 @@ static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup1_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup1_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup1_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1939,7 +2047,9 @@ static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart1_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart1_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart1_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1954,7 +2064,9 @@ static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup2_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup2_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup2_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1969,7 +2081,9 @@ static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup2_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup2_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup2_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1984,7 +2098,9 @@ static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart2_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart2_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart2_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -1999,7 +2115,9 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup3_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup3_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup3_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2014,7 +2132,9 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup3_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup3_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup3_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2029,7 +2149,9 @@ static struct clk_branch gcc_blsp2_uart3_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart3_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart3_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart3_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2044,7 +2166,9 @@ static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup4_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup4_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup4_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2059,7 +2183,9 @@ static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup4_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup4_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup4_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2074,7 +2200,9 @@ static struct clk_branch gcc_blsp2_uart4_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart4_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart4_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart4_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2089,7 +2217,9 @@ static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup5_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup5_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup5_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2104,7 +2234,9 @@ static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup5_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup5_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup5_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2119,7 +2251,9 @@ static struct clk_branch gcc_blsp2_uart5_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart5_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart5_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart5_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2134,7 +2268,9 @@ static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup6_spi_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup6_spi_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup6_spi_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2149,7 +2285,9 @@ static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_qup6_i2c_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_qup6_i2c_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_qup6_i2c_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2164,7 +2302,9 @@ static struct clk_branch gcc_blsp2_uart6_apps_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp2_uart6_apps_clk",
+-                      .parent_names = (const char *[]){ "blsp2_uart6_apps_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &blsp2_uart6_apps_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2179,7 +2319,9 @@ static struct clk_branch gcc_pdm_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2194,7 +2336,9 @@ static struct clk_branch gcc_pdm2_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+-                      .parent_names = (const char *[]){ "pdm2_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &pdm2_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2210,7 +2354,9 @@ static struct clk_branch gcc_prng_ahb_clk = {
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2225,7 +2371,9 @@ static struct clk_branch gcc_tsif_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2240,7 +2388,9 @@ static struct clk_branch gcc_tsif_ref_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_ref_clk",
+-                      .parent_names = (const char *[]){ "tsif_ref_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &tsif_ref_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2255,7 +2405,9 @@ static struct clk_branch gcc_tsif_inactivity_timers_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_tsif_inactivity_timers_clk",
+-                      .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gcc_sleep_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2271,7 +2423,9 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2299,7 +2453,9 @@ static struct clk_branch gcc_hmss_rbcpr_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_hmss_rbcpr_clk",
+-                      .parent_names = (const char *[]){ "hmss_rbcpr_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &hmss_rbcpr_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2314,7 +2470,9 @@ static struct clk_branch gcc_gp1_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+-                      .parent_names = (const char *[]){ "gp1_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gp1_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2329,7 +2487,9 @@ static struct clk_branch gcc_gp2_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+-                      .parent_names = (const char *[]){ "gp2_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gp2_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2344,7 +2504,9 @@ static struct clk_branch gcc_gp3_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+-                      .parent_names = (const char *[]){ "gp3_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &gp3_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2359,7 +2521,9 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_slv_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2374,7 +2538,9 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_mstr_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2389,7 +2555,9 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2404,7 +2572,9 @@ static struct clk_branch gcc_pcie_0_aux_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_aux_clk",
+-                      .parent_names = (const char *[]){ "pcie_aux_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &pcie_aux_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2420,7 +2590,9 @@ static struct clk_branch gcc_pcie_0_pipe_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_0_pipe_clk",
+-                      .parent_names = (const char *[]){ "pcie_0_pipe_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "pcie_0_pipe_clk_src", .name = "pcie_0_pipe_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2435,7 +2607,9 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_slv_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2450,7 +2624,9 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_mstr_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2465,7 +2641,9 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2480,7 +2658,9 @@ static struct clk_branch gcc_pcie_1_aux_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_aux_clk",
+-                      .parent_names = (const char *[]){ "pcie_aux_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &pcie_aux_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2496,7 +2676,9 @@ static struct clk_branch gcc_pcie_1_pipe_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_1_pipe_clk",
+-                      .parent_names = (const char *[]){ "pcie_1_pipe_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "pcie_1_pipe_clk_src", .name = "pcie_1_pipe_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2511,7 +2693,9 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_slv_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2526,7 +2710,9 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_mstr_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2541,7 +2727,9 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2556,7 +2744,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_aux_clk",
+-                      .parent_names = (const char *[]){ "pcie_aux_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &pcie_aux_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2572,7 +2762,9 @@ static struct clk_branch gcc_pcie_2_pipe_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_2_pipe_clk",
+-                      .parent_names = (const char *[]){ "pcie_2_pipe_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "pcie_2_pipe_clk_src", .name = "pcie_2_pipe_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2587,7 +2779,9 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_phy_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2602,7 +2796,9 @@ static struct clk_branch gcc_pcie_phy_aux_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie_phy_aux_clk",
+-                      .parent_names = (const char *[]){ "pcie_aux_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &pcie_aux_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2617,7 +2813,9 @@ static struct clk_branch gcc_ufs_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_axi_clk",
+-                      .parent_names = (const char *[]){ "ufs_axi_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_axi_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2632,7 +2830,9 @@ static struct clk_branch gcc_ufs_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2645,7 +2845,9 @@ static struct clk_fixed_factor ufs_tx_cfg_clk_src = {
+       .div = 16,
+       .hw.init = &(struct clk_init_data){
+               .name = "ufs_tx_cfg_clk_src",
+-              .parent_names = (const char *[]){ "ufs_axi_clk_src" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &ufs_axi_clk_src.clkr.hw,
++              },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_fixed_factor_ops,
+@@ -2659,7 +2861,9 @@ static struct clk_branch gcc_ufs_tx_cfg_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_tx_cfg_clk",
+-                      .parent_names = (const char *[]){ "ufs_tx_cfg_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_tx_cfg_clk_src.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2672,7 +2876,9 @@ static struct clk_fixed_factor ufs_rx_cfg_clk_src = {
+       .div = 16,
+       .hw.init = &(struct clk_init_data){
+               .name = "ufs_rx_cfg_clk_src",
+-              .parent_names = (const char *[]){ "ufs_axi_clk_src" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &ufs_axi_clk_src.clkr.hw,
++              },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_fixed_factor_ops,
+@@ -2712,7 +2918,9 @@ static struct clk_branch gcc_ufs_rx_cfg_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_rx_cfg_clk",
+-                      .parent_names = (const char *[]){ "ufs_rx_cfg_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_rx_cfg_clk_src.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2728,7 +2936,9 @@ static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_tx_symbol_0_clk",
+-                      .parent_names = (const char *[]){ "ufs_tx_symbol_0_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "ufs_tx_symbol_0_clk_src", .name = "ufs_tx_symbol_0_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2744,7 +2954,9 @@ static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_rx_symbol_0_clk",
+-                      .parent_names = (const char *[]){ "ufs_rx_symbol_0_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "ufs_rx_symbol_0_clk_src", .name = "ufs_rx_symbol_0_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2760,7 +2972,9 @@ static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_rx_symbol_1_clk",
+-                      .parent_names = (const char *[]){ "ufs_rx_symbol_1_clk_src" },
++                      .parent_data = &(const struct clk_parent_data){
++                              .fw_name = "ufs_rx_symbol_1_clk_src", .name = "ufs_rx_symbol_1_clk_src",
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2773,7 +2987,9 @@ static struct clk_fixed_factor ufs_ice_core_postdiv_clk_src = {
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "ufs_ice_core_postdiv_clk_src",
+-              .parent_names = (const char *[]){ "ufs_ice_core_clk_src" },
++              .parent_hws = (const struct clk_hw*[]){
++                      &ufs_ice_core_clk_src.clkr.hw,
++              },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_fixed_factor_ops,
+@@ -2787,7 +3003,9 @@ static struct clk_branch gcc_ufs_unipro_core_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_unipro_core_clk",
+-                      .parent_names = (const char *[]){ "ufs_ice_core_postdiv_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_ice_core_postdiv_clk_src.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2802,7 +3020,9 @@ static struct clk_branch gcc_ufs_ice_core_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_ice_core_clk",
+-                      .parent_names = (const char *[]){ "ufs_ice_core_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_ice_core_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2841,7 +3061,9 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_snoc_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+@@ -2856,7 +3078,9 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_cnoc_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+@@ -2871,7 +3095,9 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_aggre0_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+@@ -2886,7 +3112,9 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_smmu_aggre0_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+@@ -2901,7 +3129,9 @@ static struct clk_branch gcc_aggre2_ufs_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre2_ufs_axi_clk",
+-                      .parent_names = (const char *[]){ "ufs_axi_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &ufs_axi_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2916,7 +3146,9 @@ static struct clk_branch gcc_aggre2_usb3_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre2_usb3_axi_clk",
+-                      .parent_names = (const char *[]){ "usb30_master_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &usb30_master_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2931,7 +3163,9 @@ static struct clk_branch gcc_dcc_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+@@ -2945,7 +3179,9 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+@@ -2959,7 +3195,9 @@ static struct clk_branch gcc_qspi_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_ahb_clk",
+-                      .parent_names = (const char *[]){ "periph_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &periph_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -2974,7 +3212,9 @@ static struct clk_branch gcc_qspi_ser_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qspi_ser_clk",
+-                      .parent_names = (const char *[]){ "qspi_ser_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &qspi_ser_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+@@ -3108,7 +3348,9 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_cfg_ahb_clk",
+-                      .parent_names = (const char *[]){ "config_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &config_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+@@ -3122,7 +3364,9 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_mnoc_bimc_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+@@ -3136,7 +3380,9 @@ static struct clk_branch gcc_mss_snoc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_snoc_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+@@ -3150,7 +3396,9 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+-                      .parent_names = (const char *[]){ "system_noc_clk_src" },
++                      .parent_hws = (const struct clk_hw*[]){
++                              &system_noc_clk_src.clkr.hw,
++                      },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch b/queue-5.15/clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch
new file mode 100644 (file)
index 0000000..1175b37
--- /dev/null
@@ -0,0 +1,39 @@
+From fc166442fa13945f36174f30a9e9220d700cc11e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 20:56:11 +0300
+Subject: clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src
+
+From: Danila Tikhonov <danila@jiaxyga.com>
+
+[ Upstream commit 7138c244fb293f24ce8ab782961022eff00a10c4 ]
+
+Set .flags = CLK_OPS_PARENT_ENABLE to fix "gcc_sdcc2_apps_clk_src: rcg
+didn't update its configuration" error.
+
+Fixes: 2a1d7eb854bb ("clk: qcom: gcc: Add global clock controller driver for SM8150")
+Tested-by: Arseniy Velikanov <adomerlee@gmail.com>
+Signed-off-by: Danila Tikhonov <danila@jiaxyga.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230913175612.8685-1-danila@jiaxyga.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sm8150.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c
+index 2457944857197..e9ed963f129da 100644
+--- a/drivers/clk/qcom/gcc-sm8150.c
++++ b/drivers/clk/qcom/gcc-sm8150.c
+@@ -792,7 +792,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parents_6,
+               .num_parents = ARRAY_SIZE(gcc_parents_6),
+-              .flags = CLK_SET_RATE_PARENT,
++              .flags = CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_floor_ops,
+       },
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch b/queue-5.15/clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch
new file mode 100644 (file)
index 0000000..5671835
--- /dev/null
@@ -0,0 +1,55 @@
+From adfe05319d175bbf17fbb7bc8943fa6d72785993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 21:20:27 +0200
+Subject: clk: qcom: mmcc-msm8998: Don't check halt bit on some branch clks
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 9906c4140897bbdbff7bb71c6ae67903cb9954ce ]
+
+Some branch clocks are governed externally and we're only supposed to
+send a request concerning their shutdown, not actually ensure it happens.
+
+Use the BRANCH_HALT_SKIP define to skip checking the halt bit.
+
+Fixes: d14b15b5931c ("clk: qcom: Add MSM8998 Multimedia Clock Controller (MMCC) driver")
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-4-ba1b1fd9ee75@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-msm8998.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c
+index 467dadccde026..8768cdcf0aa3c 100644
+--- a/drivers/clk/qcom/mmcc-msm8998.c
++++ b/drivers/clk/qcom/mmcc-msm8998.c
+@@ -2487,6 +2487,7 @@ static struct clk_branch fd_ahb_clk = {
+ static struct clk_branch mnoc_ahb_clk = {
+       .halt_reg = 0x5024,
++      .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x5024,
+               .enable_mask = BIT(0),
+@@ -2502,6 +2503,7 @@ static struct clk_branch mnoc_ahb_clk = {
+ static struct clk_branch bimc_smmu_ahb_clk = {
+       .halt_reg = 0xe004,
++      .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0xe004,
+       .hwcg_bit = 1,
+       .clkr = {
+@@ -2519,6 +2521,7 @@ static struct clk_branch bimc_smmu_ahb_clk = {
+ static struct clk_branch bimc_smmu_axi_clk = {
+       .halt_reg = 0xe008,
++      .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0xe008,
+       .hwcg_bit = 1,
+       .clkr = {
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch b/queue-5.15/clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch
new file mode 100644 (file)
index 0000000..1d77141
--- /dev/null
@@ -0,0 +1,48 @@
+From 5b22ce30176315e1b2fc0a5f1005a442a463c81c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 21:20:28 +0200
+Subject: clk: qcom: mmcc-msm8998: Fix the SMMU GDSC
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 1fc62c8347397faf4e18249e88ecd4470c0a5357 ]
+
+The SMMU GDSC doesn't have to be ALWAYS-ON and shouldn't feature the
+HW_CTRL flag (it's separate from hw_ctrl_addr).  In addition to that,
+it should feature a cxc entry for bimc_smmu_axi_clk and be marked as
+votable.
+
+Fix all of these issues.
+
+Fixes: d14b15b5931c ("clk: qcom: Add MSM8998 Multimedia Clock Controller (MMCC) driver")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://lore.kernel.org/r/20230531-topic-8998_mmssclk-v3-5-ba1b1fd9ee75@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-msm8998.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c
+index 8768cdcf0aa3c..a68764cfb7930 100644
+--- a/drivers/clk/qcom/mmcc-msm8998.c
++++ b/drivers/clk/qcom/mmcc-msm8998.c
+@@ -2662,11 +2662,13 @@ static struct gdsc camss_cpp_gdsc = {
+ static struct gdsc bimc_smmu_gdsc = {
+       .gdscr = 0xe020,
+       .gds_hw_ctrl = 0xe024,
++      .cxcs = (unsigned int []){ 0xe008 },
++      .cxc_count = 1,
+       .pd = {
+               .name = "bimc_smmu",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+-      .flags = HW_CTRL | ALWAYS_ON,
++      .flags = VOTABLE,
+ };
+ static struct clk_regmap *mmcc_msm8998_clocks[] = {
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-renesas-rzg2l-fix-computation-formula.patch b/queue-5.15/clk-renesas-rzg2l-fix-computation-formula.patch
new file mode 100644 (file)
index 0000000..64d5dd6
--- /dev/null
@@ -0,0 +1,70 @@
+From c59e1960079eee8ff88445181ee8e3862002557a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Sep 2023 08:38:52 +0300
+Subject: clk: renesas: rzg2l: Fix computation formula
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit a2b23159499efd36b2d63b3c4534075d12ddc97a ]
+
+According to the hardware manual for RZ/G2L
+(r01uh0914ej0130-rzg2l-rzg2lc.pdf), the computation formula for PLL rate
+is as follows:
+
+    Fout = ((m + k/65536) * Fin) / (p * 2^s)
+
+and k has values in the range [-32768, 32767].  Dividing k by 65536 with
+integer arithmetic gives zero all the time, causing slight differences
+b/w what has been set vs. what is displayed.  Thus, get rid of this and
+decompose the formula before dividing k by 65536.
+
+Fixes: ef3c613ccd68a ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230929053915.1530607-6-claudiu.beznea@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/rzg2l-cpg.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index a2eee53e1406a..79e4e977b23b1 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -41,7 +41,7 @@
+ #define GET_SHIFT(val)                ((val >> 12) & 0xff)
+ #define GET_WIDTH(val)                ((val >> 8) & 0xf)
+-#define KDIV(val)             FIELD_GET(GENMASK(31, 16), val)
++#define KDIV(val)             ((s16)FIELD_GET(GENMASK(31, 16), val))
+ #define MDIV(val)             FIELD_GET(GENMASK(15, 6), val)
+ #define PDIV(val)             FIELD_GET(GENMASK(5, 0), val)
+ #define SDIV(val)             FIELD_GET(GENMASK(2, 0), val)
+@@ -146,18 +146,18 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+       struct pll_clk *pll_clk = to_pll(hw);
+       struct rzg2l_cpg_priv *priv = pll_clk->priv;
+       unsigned int val1, val2;
+-      unsigned int mult = 1;
+-      unsigned int div = 1;
++      u64 rate;
+       if (pll_clk->type != CLK_TYPE_SAM_PLL)
+               return parent_rate;
+       val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+       val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
+-      mult = MDIV(val1) + KDIV(val1) / 65536;
+-      div = PDIV(val1) << SDIV(val2);
+-      return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
++      rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1),
++                             16 + SDIV(val2));
++
++      return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1));
+ }
+ static const struct clk_ops rzg2l_cpg_pll_ops = {
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-renesas-rzg2l-simplify-multiplication-shift-logi.patch b/queue-5.15/clk-renesas-rzg2l-simplify-multiplication-shift-logi.patch
new file mode 100644 (file)
index 0000000..6e1d306
--- /dev/null
@@ -0,0 +1,37 @@
+From 470e9f76be081fe2f1e0d9231cc4e992cdc1988f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Feb 2022 17:25:20 +0100
+Subject: clk: renesas: rzg2l: Simplify multiplication/shift logic
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 29db30c45f07c929c86c40a5b85f18b69c89c638 ]
+
+"a * (1 << b)" == "a << b".
+
+No change in generated code.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/71e1cf2e30fb2d7966fc8ec6bab23eb7e24aa1c4.1645460687.git.geert+renesas@glider.be
+Stable-dep-of: a2b23159499e ("clk: renesas: rzg2l: Fix computation formula")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/rzg2l-cpg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index 1c92e73cd2b8c..e435d88d9da89 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -155,7 +155,7 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+       val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+       val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
+       mult = MDIV(val1) + KDIV(val1) / 65536;
+-      div = PDIV(val1) * (1 << SDIV(val2));
++      div = PDIV(val1) << SDIV(val2);
+       return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch b/queue-5.15/clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch
new file mode 100644 (file)
index 0000000..454f636
--- /dev/null
@@ -0,0 +1,55 @@
+From 35f907c3056a04fc7785faffab4742304c7096dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 07:51:33 +0300
+Subject: clk: renesas: rzg2l: Use FIELD_GET() for PLL register fields
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit 72977f07b035e488c3f1928832a1616c6cae7278 ]
+
+Use FIELD_GET() for PLL register fields.  This is its purpose.
+
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230912045157.177966-14-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: a2b23159499e ("clk: renesas: rzg2l: Fix computation formula")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/rzg2l-cpg.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index e435d88d9da89..a2eee53e1406a 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -11,6 +11,7 @@
+  * Copyright (C) 2015 Renesas Electronics Corp.
+  */
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/clk/renesas.h>
+@@ -37,14 +38,13 @@
+ #define WARN_DEBUG(x) do { } while (0)
+ #endif
+-#define DIV_RSMASK(v, s, m)   ((v >> s) & m)
+ #define GET_SHIFT(val)                ((val >> 12) & 0xff)
+ #define GET_WIDTH(val)                ((val >> 8) & 0xf)
+-#define KDIV(val)             DIV_RSMASK(val, 16, 0xffff)
+-#define MDIV(val)             DIV_RSMASK(val, 6, 0x3ff)
+-#define PDIV(val)             DIV_RSMASK(val, 0, 0x3f)
+-#define SDIV(val)             DIV_RSMASK(val, 0, 0x7)
++#define KDIV(val)             FIELD_GET(GENMASK(31, 16), val)
++#define MDIV(val)             FIELD_GET(GENMASK(15, 6), val)
++#define PDIV(val)             FIELD_GET(GENMASK(5, 0), val)
++#define SDIV(val)             FIELD_GET(GENMASK(2, 0), val)
+ #define CLK_ON_R(reg)         (reg)
+ #define CLK_MON_R(reg)                (0x180 + (reg))
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch b/queue-5.15/clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch
new file mode 100644 (file)
index 0000000..77164e4
--- /dev/null
@@ -0,0 +1,40 @@
+From 2fc5a9726d8632d69afa3aa5f144d44a875e5d3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 20:36:00 +0100
+Subject: clk: scmi: Free scmi_clk allocated when the clocks with invalid info
+ are skipped
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 3537a75e73f3420614a358d0c8b390ea483cc87d ]
+
+Add the missing devm_kfree() when we skip the clocks with invalid or
+missing information from the firmware.
+
+Cc: Cristian Marussi <cristian.marussi@arm.com>
+Cc: Michael Turquette <mturquette@baylibre.com>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: linux-clk@vger.kernel.org
+Fixes: 6d6a1d82eaef ("clk: add support for clocks provided by SCMI")
+Link: https://lore.kernel.org/r/20231004193600.66232-1-sudeep.holla@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk-scmi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
+index 1e357d364ca26..a26027597a0ac 100644
+--- a/drivers/clk/clk-scmi.c
++++ b/drivers/clk/clk-scmi.c
+@@ -178,6 +178,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
+               sclk->info = scmi_proto_clk_ops->info_get(ph, idx);
+               if (!sclk->info) {
+                       dev_dbg(dev, "invalid clock info for idx %d\n", idx);
++                      devm_kfree(dev, sclk);
+                       continue;
+               }
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-ti-add-ti_dt_clk_name-helper-to-use-clock-output.patch b/queue-5.15/clk-ti-add-ti_dt_clk_name-helper-to-use-clock-output.patch
new file mode 100644 (file)
index 0000000..a7e0161
--- /dev/null
@@ -0,0 +1,76 @@
+From 73685d5219ed276863a1eda06b155529f022956a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 09:14:47 +0200
+Subject: clk: ti: Add ti_dt_clk_name() helper to use clock-output-names
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 2c1593328d7f02fe49de5ad6b42c36296c9d6922 ]
+
+Let's create the clock alias based on the clock-output-names property if
+available. Also the component clock drivers can use ti_dt_clk_name() in
+the following patches.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20220204071449.16762-7-tony@atomide.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 7af5b9eadd64 ("clk: ti: fix double free in of_ti_divider_clk_setup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/clk.c   | 20 +++++++++++++++++++-
+ drivers/clk/ti/clock.h |  1 +
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index 29eafab4353ef..b941ce0f3c394 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -402,6 +402,24 @@ static const struct of_device_id simple_clk_match_table[] __initconst = {
+       { }
+ };
++/**
++ * ti_dt_clk_name - init clock name from first output name or node name
++ * @np: device node
++ *
++ * Use the first clock-output-name for the clock name if found. Fall back
++ * to legacy naming based on node name.
++ */
++const char *ti_dt_clk_name(struct device_node *np)
++{
++      const char *name;
++
++      if (!of_property_read_string_index(np, "clock-output-names", 0,
++                                         &name))
++              return name;
++
++      return np->name;
++}
++
+ /**
+  * ti_clk_add_aliases - setup clock aliases
+  *
+@@ -418,7 +436,7 @@ void __init ti_clk_add_aliases(void)
+               clkspec.np = np;
+               clk = of_clk_get_from_provider(&clkspec);
+-              ti_clk_add_alias(NULL, clk, np->name);
++              ti_clk_add_alias(NULL, clk, ti_dt_clk_name(np));
+       }
+ }
+diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
+index f1dd62de2bfcb..938f34e290ed2 100644
+--- a/drivers/clk/ti/clock.h
++++ b/drivers/clk/ti/clock.h
+@@ -214,6 +214,7 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+                           const char *con);
+ struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
+                                   const char *con);
++const char *ti_dt_clk_name(struct device_node *np);
+ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
+ void ti_clk_add_aliases(void);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-ti-change-ti_clk_register-_omap_hw-api.patch b/queue-5.15/clk-ti-change-ti_clk_register-_omap_hw-api.patch
new file mode 100644 (file)
index 0000000..a7fa14b
--- /dev/null
@@ -0,0 +1,383 @@
+From 272f8514e89246faf3b2039ed057bdf9d83966d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Nov 2022 19:11:46 +0100
+Subject: clk: ti: change ti_clk_register[_omap_hw]() API
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 3400d546a741a2b2001d88e7fa29110d45a3930d ]
+
+The ti_clk_register() and ti_clk_register_omap_hw() functions are always
+called with the parameter of type "struct device" set to NULL, since the
+functions from which they are called always have a parameter of type
+"struct device_node". Replacing "struct device" type parameter with
+"struct device_node" will allow you to register a TI clock to the common
+clock framework by taking advantage of the facilities provided by the
+"struct device_node" type. Further, adding the "of_" prefix to the name
+of these functions explicitly binds them to the "struct device_node"
+type.
+
+The patch has been tested on a Beaglebone board.
+
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Tested-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20221113181147.1626585-1-dario.binacchi@amarulasolutions.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 7af5b9eadd64 ("clk: ti: fix double free in of_ti_divider_clk_setup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/apll.c         |  4 ++--
+ drivers/clk/ti/clk-dra7-atl.c |  2 +-
+ drivers/clk/ti/clk.c          | 34 ++++++++++++++++------------------
+ drivers/clk/ti/clkctrl.c      |  4 ++--
+ drivers/clk/ti/clock.h        | 10 +++++-----
+ drivers/clk/ti/composite.c    |  2 +-
+ drivers/clk/ti/divider.c      |  2 +-
+ drivers/clk/ti/dpll.c         |  4 ++--
+ drivers/clk/ti/fixed-factor.c |  2 +-
+ drivers/clk/ti/gate.c         |  6 +++---
+ drivers/clk/ti/interface.c    |  7 ++++---
+ drivers/clk/ti/mux.c          |  6 +++---
+ 12 files changed, 41 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
+index e4db6b9a55c61..f921c6812852f 100644
+--- a/drivers/clk/ti/apll.c
++++ b/drivers/clk/ti/apll.c
+@@ -168,7 +168,7 @@ static void __init omap_clk_register_apll(void *user,
+       ad->clk_bypass = __clk_get_hw(clk);
+       name = ti_dt_clk_name(node);
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               kfree(init->parent_names);
+@@ -408,7 +408,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
+               goto cleanup;
+       name = ti_dt_clk_name(node);
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               kfree(init);
+diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
+index 5c278d6c985e9..62508e74a47a7 100644
+--- a/drivers/clk/ti/clk-dra7-atl.c
++++ b/drivers/clk/ti/clk-dra7-atl.c
+@@ -205,7 +205,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
+       init.parent_names = parent_names;
+-      clk = ti_clk_register(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register(node, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index b941ce0f3c394..6a39fb051b2ee 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -436,7 +436,7 @@ void __init ti_clk_add_aliases(void)
+               clkspec.np = np;
+               clk = of_clk_get_from_provider(&clkspec);
+-              ti_clk_add_alias(NULL, clk, ti_dt_clk_name(np));
++              ti_clk_add_alias(clk, ti_dt_clk_name(np));
+       }
+ }
+@@ -489,7 +489,6 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
+ /**
+  * ti_clk_add_alias - add a clock alias for a TI clock
+- * @dev: device alias for this clock
+  * @clk: clock handle to create alias for
+  * @con: connection ID for this clock
+  *
+@@ -497,7 +496,7 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
+  * and assigns the data to it. Returns 0 if successful, negative error
+  * value otherwise.
+  */
+-int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
++int ti_clk_add_alias(struct clk *clk, const char *con)
+ {
+       struct clk_lookup *cl;
+@@ -511,8 +510,6 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+       if (!cl)
+               return -ENOMEM;
+-      if (dev)
+-              cl->dev_id = dev_name(dev);
+       cl->con_id = con;
+       cl->clk = clk;
+@@ -522,8 +519,8 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+ }
+ /**
+- * ti_clk_register - register a TI clock to the common clock framework
+- * @dev: device for this clock
++ * of_ti_clk_register - register a TI clock to the common clock framework
++ * @node: device node for this clock
+  * @hw: hardware clock handle
+  * @con: connection ID for this clock
+  *
+@@ -531,17 +528,18 @@ int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
+  * alias for it. Returns a handle to the registered clock if successful,
+  * ERR_PTR value in failure.
+  */
+-struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+-                          const char *con)
++struct clk *of_ti_clk_register(struct device_node *node, struct clk_hw *hw,
++                             const char *con)
+ {
+       struct clk *clk;
+       int ret;
+-      clk = clk_register(dev, hw);
+-      if (IS_ERR(clk))
+-              return clk;
++      ret = of_clk_hw_register(node, hw);
++      if (ret)
++              return ERR_PTR(ret);
+-      ret = ti_clk_add_alias(dev, clk, con);
++      clk = hw->clk;
++      ret = ti_clk_add_alias(clk, con);
+       if (ret) {
+               clk_unregister(clk);
+               return ERR_PTR(ret);
+@@ -551,8 +549,8 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+ }
+ /**
+- * ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
+- * @dev: device for this clock
++ * of_ti_clk_register_omap_hw - register a clk_hw_omap to the clock framework
++ * @node: device node for this clock
+  * @hw: hardware clock handle
+  * @con: connection ID for this clock
+  *
+@@ -561,13 +559,13 @@ struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+  * Returns a handle to the registered clock if successful, ERR_PTR value
+  * in failure.
+  */
+-struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
+-                                  const char *con)
++struct clk *of_ti_clk_register_omap_hw(struct device_node *node,
++                                     struct clk_hw *hw, const char *con)
+ {
+       struct clk *clk;
+       struct clk_hw_omap *oclk;
+-      clk = ti_clk_register(dev, hw, con);
++      clk = of_ti_clk_register(node, hw, con);
+       if (IS_ERR(clk))
+               return clk;
+diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
+index 157abc46dcf44..1424b615a4cc5 100644
+--- a/drivers/clk/ti/clkctrl.c
++++ b/drivers/clk/ti/clkctrl.c
+@@ -317,7 +317,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
+       init.ops = ops;
+       init.flags = 0;
+-      clk = ti_clk_register(NULL, clk_hw, init.name);
++      clk = of_ti_clk_register(node, clk_hw, init.name);
+       if (IS_ERR_OR_NULL(clk)) {
+               ret = -EINVAL;
+               goto cleanup;
+@@ -701,7 +701,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
+               init.ops = &omap4_clkctrl_clk_ops;
+               hw->hw.init = &init;
+-              clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name);
++              clk = of_ti_clk_register_omap_hw(node, &hw->hw, init.name);
+               if (IS_ERR_OR_NULL(clk))
+                       goto cleanup;
+diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
+index 938f34e290ed2..821f33ee330e4 100644
+--- a/drivers/clk/ti/clock.h
++++ b/drivers/clk/ti/clock.h
+@@ -210,12 +210,12 @@ extern const struct omap_clkctrl_data dm816_clkctrl_data[];
+ typedef void (*ti_of_clk_init_cb_t)(void *, struct device_node *);
+-struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
+-                          const char *con);
+-struct clk *ti_clk_register_omap_hw(struct device *dev, struct clk_hw *hw,
+-                                  const char *con);
++struct clk *of_ti_clk_register(struct device_node *node, struct clk_hw *hw,
++                             const char *con);
++struct clk *of_ti_clk_register_omap_hw(struct device_node *node,
++                                     struct clk_hw *hw, const char *con);
+ const char *ti_dt_clk_name(struct device_node *np);
+-int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con);
++int ti_clk_add_alias(struct clk *clk, const char *con);
+ void ti_clk_add_aliases(void);
+ void ti_clk_latch(struct clk_omap_reg *reg, s8 shift);
+diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
+index 8d60319be3683..78d44158fb7d9 100644
+--- a/drivers/clk/ti/composite.c
++++ b/drivers/clk/ti/composite.c
+@@ -184,7 +184,7 @@ static void __init _register_composite(void *user,
+                                    &ti_composite_gate_ops, 0);
+       if (!IS_ERR(clk)) {
+-              ret = ti_clk_add_alias(NULL, clk, name);
++              ret = ti_clk_add_alias(clk, name);
+               if (ret) {
+                       clk_unregister(clk);
+                       goto cleanup;
+diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
+index 9fbea0997b432..83931cc299713 100644
+--- a/drivers/clk/ti/divider.c
++++ b/drivers/clk/ti/divider.c
+@@ -334,7 +334,7 @@ static struct clk *_register_divider(struct device_node *node,
+       div->hw.init = &init;
+       /* register the clock */
+-      clk = ti_clk_register(NULL, &div->hw, name);
++      clk = of_ti_clk_register(node, &div->hw, name);
+       if (IS_ERR(clk))
+               kfree(div);
+diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
+index 7c6dc8449b22f..9ef7133f2f57b 100644
+--- a/drivers/clk/ti/dpll.c
++++ b/drivers/clk/ti/dpll.c
+@@ -195,7 +195,7 @@ static void __init _register_dpll(void *user,
+       /* register the clock */
+       name = ti_dt_clk_name(node);
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+@@ -267,7 +267,7 @@ static void _register_dpll_x2(struct device_node *node,
+ #endif
+       /* register the clock */
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (IS_ERR(clk))
+               kfree(clk_hw);
+diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
+index 8cb00d0af9662..a4f9c1c156137 100644
+--- a/drivers/clk/ti/fixed-factor.c
++++ b/drivers/clk/ti/fixed-factor.c
+@@ -62,7 +62,7 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               of_ti_clk_autoidle_setup(node);
+-              ti_clk_add_alias(NULL, clk, clk_name);
++              ti_clk_add_alias(clk, clk_name);
+       }
+ }
+ CLK_OF_DECLARE(ti_fixed_factor_clk, "ti,fixed-factor-clock",
+diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
+index 0033de9beb4cd..b0d9d357861c2 100644
+--- a/drivers/clk/ti/gate.c
++++ b/drivers/clk/ti/gate.c
+@@ -93,7 +93,7 @@ static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *hw)
+       return ret;
+ }
+-static struct clk *_register_gate(struct device *dev, const char *name,
++static struct clk *_register_gate(struct device_node *node, const char *name,
+                                 const char *parent_name, unsigned long flags,
+                                 struct clk_omap_reg *reg, u8 bit_idx,
+                                 u8 clk_gate_flags, const struct clk_ops *ops,
+@@ -123,7 +123,7 @@ static struct clk *_register_gate(struct device *dev, const char *name,
+       init.flags = flags;
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (IS_ERR(clk))
+               kfree(clk_hw);
+@@ -166,7 +166,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
+               clk_gate_flags |= INVERT_ENABLE;
+       name = ti_dt_clk_name(node);
+-      clk = _register_gate(NULL, name, parent_name, flags, &reg,
++      clk = _register_gate(node, name, parent_name, flags, &reg,
+                            enable_bit, clk_gate_flags, ops, hw_ops);
+       if (!IS_ERR(clk))
+diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
+index dd2b455183a91..1ccd5dbf2bb48 100644
+--- a/drivers/clk/ti/interface.c
++++ b/drivers/clk/ti/interface.c
+@@ -32,7 +32,8 @@ static const struct clk_ops ti_interface_clk_ops = {
+       .is_enabled     = &omap2_dflt_clk_is_enabled,
+ };
+-static struct clk *_register_interface(struct device *dev, const char *name,
++static struct clk *_register_interface(struct device_node *node,
++                                     const char *name,
+                                      const char *parent_name,
+                                      struct clk_omap_reg *reg, u8 bit_idx,
+                                      const struct clk_hw_omap_ops *ops)
+@@ -57,7 +58,7 @@ static struct clk *_register_interface(struct device *dev, const char *name,
+       init.num_parents = 1;
+       init.parent_names = &parent_name;
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
++      clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);
+       if (IS_ERR(clk))
+               kfree(clk_hw);
+@@ -88,7 +89,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
+       }
+       name = ti_dt_clk_name(node);
+-      clk = _register_interface(NULL, name, parent_name, &reg,
++      clk = _register_interface(node, name, parent_name, &reg,
+                                 enable_bit, ops);
+       if (!IS_ERR(clk))
+diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
+index 15de513d2d818..4205ff4bad217 100644
+--- a/drivers/clk/ti/mux.c
++++ b/drivers/clk/ti/mux.c
+@@ -126,7 +126,7 @@ const struct clk_ops ti_clk_mux_ops = {
+       .restore_context = clk_mux_restore_context,
+ };
+-static struct clk *_register_mux(struct device *dev, const char *name,
++static struct clk *_register_mux(struct device_node *node, const char *name,
+                                const char * const *parent_names,
+                                u8 num_parents, unsigned long flags,
+                                struct clk_omap_reg *reg, u8 shift, u32 mask,
+@@ -156,7 +156,7 @@ static struct clk *_register_mux(struct device *dev, const char *name,
+       mux->table = table;
+       mux->hw.init = &init;
+-      clk = ti_clk_register(dev, &mux->hw, name);
++      clk = of_ti_clk_register(node, &mux->hw, name);
+       if (IS_ERR(clk))
+               kfree(mux);
+@@ -215,7 +215,7 @@ static void of_mux_clk_setup(struct device_node *node)
+       mask = (1 << fls(mask)) - 1;
+       name = ti_dt_clk_name(node);
+-      clk = _register_mux(NULL, name, parent_names, num_parents,
++      clk = _register_mux(node, name, parent_names, num_parents,
+                           flags, &reg, shift, mask, latch, clk_mux_flags,
+                           NULL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch b/queue-5.15/clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch
new file mode 100644 (file)
index 0000000..35de55d
--- /dev/null
@@ -0,0 +1,51 @@
+From 3eb6c9b627fee0d03c9f5bd460fad4141187cb55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Oct 2023 10:04:36 +0300
+Subject: clk: ti: fix double free in of_ti_divider_clk_setup()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 7af5b9eadd64c9e02a71f97c45bcdf3b64841f6b ]
+
+The "div" pointer is freed in _register_divider() and again in
+of_ti_divider_clk_setup().  Delete the free in _register_divider()
+
+Fixes: fbbc18591585 ("clk: ti: divider: cleanup _register_divider and ti_clk_get_div_table")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/6d36eeec-6c8a-4f11-a579-aa3cd7c38749@moroto.mountain
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/divider.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
+index 83931cc299713..4cc0aaa6cb139 100644
+--- a/drivers/clk/ti/divider.c
++++ b/drivers/clk/ti/divider.c
+@@ -317,7 +317,6 @@ static struct clk *_register_divider(struct device_node *node,
+                                    u32 flags,
+                                    struct clk_omap_divider *div)
+ {
+-      struct clk *clk;
+       struct clk_init_data init;
+       const char *parent_name;
+       const char *name;
+@@ -334,12 +333,7 @@ static struct clk *_register_divider(struct device_node *node,
+       div->hw.init = &init;
+       /* register the clock */
+-      clk = of_ti_clk_register(node, &div->hw, name);
+-
+-      if (IS_ERR(clk))
+-              kfree(div);
+-
+-      return clk;
++      return of_ti_clk_register(node, &div->hw, name);
+ }
+ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-ti-update-component-clocks-to-use-ti_dt_clk_name.patch b/queue-5.15/clk-ti-update-component-clocks-to-use-ti_dt_clk_name.patch
new file mode 100644 (file)
index 0000000..819b397
--- /dev/null
@@ -0,0 +1,212 @@
+From 815a983c9995ddd0e0da5beaf2a7f63a4fd660d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 09:14:49 +0200
+Subject: clk: ti: Update component clocks to use ti_dt_clk_name()
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit ed06099c5d0b329082cc19c58eace0b20bf7fe70 ]
+
+Let's update all the TI component clocks to use ti_dt_clk_name() instead
+of devicetree node name if available.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20220204071449.16762-9-tony@atomide.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 7af5b9eadd64 ("clk: ti: fix double free in of_ti_divider_clk_setup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/autoidle.c     | 2 +-
+ drivers/clk/ti/clk-dra7-atl.c | 6 ++++--
+ drivers/clk/ti/composite.c    | 6 ++++--
+ drivers/clk/ti/divider.c      | 6 ++++--
+ drivers/clk/ti/fixed-factor.c | 2 +-
+ drivers/clk/ti/gate.c         | 4 +++-
+ drivers/clk/ti/interface.c    | 4 +++-
+ drivers/clk/ti/mux.c          | 4 +++-
+ 8 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c
+index f6f8a409f148f..d6e5f1511ace8 100644
+--- a/drivers/clk/ti/autoidle.c
++++ b/drivers/clk/ti/autoidle.c
+@@ -205,7 +205,7 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
+               return -ENOMEM;
+       clk->shift = shift;
+-      clk->name = node->name;
++      clk->name = ti_dt_clk_name(node);
+       ret = ti_clk_get_reg_addr(node, 0, &clk->reg);
+       if (ret) {
+               kfree(clk);
+diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
+index e2e59d78c173f..5c278d6c985e9 100644
+--- a/drivers/clk/ti/clk-dra7-atl.c
++++ b/drivers/clk/ti/clk-dra7-atl.c
+@@ -173,6 +173,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
+       struct dra7_atl_desc *clk_hw = NULL;
+       struct clk_init_data init = { NULL };
+       const char **parent_names = NULL;
++      const char *name;
+       struct clk *clk;
+       clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+@@ -183,7 +184,8 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
+       clk_hw->hw.init = &init;
+       clk_hw->divider = 1;
+-      init.name = node->name;
++      name = ti_dt_clk_name(node);
++      init.name = name;
+       init.ops = &atl_clk_ops;
+       init.flags = CLK_IGNORE_UNUSED;
+       init.num_parents = of_clk_get_parent_count(node);
+@@ -203,7 +205,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
+       init.parent_names = parent_names;
+-      clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
++      clk = ti_clk_register(NULL, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c
+index eaa43575cfa5e..8d60319be3683 100644
+--- a/drivers/clk/ti/composite.c
++++ b/drivers/clk/ti/composite.c
+@@ -125,6 +125,7 @@ static void __init _register_composite(void *user,
+       struct component_clk *comp;
+       int num_parents = 0;
+       const char **parent_names = NULL;
++      const char *name;
+       int i;
+       int ret;
+@@ -172,7 +173,8 @@ static void __init _register_composite(void *user,
+               goto cleanup;
+       }
+-      clk = clk_register_composite(NULL, node->name,
++      name = ti_dt_clk_name(node);
++      clk = clk_register_composite(NULL, name,
+                                    parent_names, num_parents,
+                                    _get_hw(cclk, CLK_COMPONENT_TYPE_MUX),
+                                    &ti_clk_mux_ops,
+@@ -182,7 +184,7 @@ static void __init _register_composite(void *user,
+                                    &ti_composite_gate_ops, 0);
+       if (!IS_ERR(clk)) {
+-              ret = ti_clk_add_alias(NULL, clk, node->name);
++              ret = ti_clk_add_alias(NULL, clk, name);
+               if (ret) {
+                       clk_unregister(clk);
+                       goto cleanup;
+diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
+index 28080df92f722..9fbea0997b432 100644
+--- a/drivers/clk/ti/divider.c
++++ b/drivers/clk/ti/divider.c
+@@ -320,10 +320,12 @@ static struct clk *_register_divider(struct device_node *node,
+       struct clk *clk;
+       struct clk_init_data init;
+       const char *parent_name;
++      const char *name;
+       parent_name = of_clk_get_parent_name(node, 0);
+-      init.name = node->name;
++      name = ti_dt_clk_name(node);
++      init.name = name;
+       init.ops = &ti_clk_divider_ops;
+       init.flags = flags;
+       init.parent_names = (parent_name ? &parent_name : NULL);
+@@ -332,7 +334,7 @@ static struct clk *_register_divider(struct device_node *node,
+       div->hw.init = &init;
+       /* register the clock */
+-      clk = ti_clk_register(NULL, &div->hw, node->name);
++      clk = ti_clk_register(NULL, &div->hw, name);
+       if (IS_ERR(clk))
+               kfree(div);
+diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c
+index 7cbe896db0716..8cb00d0af9662 100644
+--- a/drivers/clk/ti/fixed-factor.c
++++ b/drivers/clk/ti/fixed-factor.c
+@@ -36,7 +36,7 @@
+ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node)
+ {
+       struct clk *clk;
+-      const char *clk_name = node->name;
++      const char *clk_name = ti_dt_clk_name(node);
+       const char *parent_name;
+       u32 div, mult;
+       u32 flags = 0;
+diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c
+index b1d0fdb40a75a..0033de9beb4cd 100644
+--- a/drivers/clk/ti/gate.c
++++ b/drivers/clk/ti/gate.c
+@@ -138,6 +138,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
+       struct clk *clk;
+       const char *parent_name;
+       struct clk_omap_reg reg;
++      const char *name;
+       u8 enable_bit = 0;
+       u32 val;
+       u32 flags = 0;
+@@ -164,7 +165,8 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
+       if (of_property_read_bool(node, "ti,set-bit-to-disable"))
+               clk_gate_flags |= INVERT_ENABLE;
+-      clk = _register_gate(NULL, node->name, parent_name, flags, &reg,
++      name = ti_dt_clk_name(node);
++      clk = _register_gate(NULL, name, parent_name, flags, &reg,
+                            enable_bit, clk_gate_flags, ops, hw_ops);
+       if (!IS_ERR(clk))
+diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c
+index 83e34429d3b10..dd2b455183a91 100644
+--- a/drivers/clk/ti/interface.c
++++ b/drivers/clk/ti/interface.c
+@@ -72,6 +72,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
+       const char *parent_name;
+       struct clk_omap_reg reg;
+       u8 enable_bit = 0;
++      const char *name;
+       u32 val;
+       if (ti_clk_get_reg_addr(node, 0, &reg))
+@@ -86,7 +87,8 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
+               return;
+       }
+-      clk = _register_interface(NULL, node->name, parent_name, &reg,
++      name = ti_dt_clk_name(node);
++      clk = _register_interface(NULL, name, parent_name, &reg,
+                                 enable_bit, ops);
+       if (!IS_ERR(clk))
+diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
+index 0069e7cf3ebcc..15de513d2d818 100644
+--- a/drivers/clk/ti/mux.c
++++ b/drivers/clk/ti/mux.c
+@@ -176,6 +176,7 @@ static void of_mux_clk_setup(struct device_node *node)
+       struct clk_omap_reg reg;
+       unsigned int num_parents;
+       const char **parent_names;
++      const char *name;
+       u8 clk_mux_flags = 0;
+       u32 mask = 0;
+       u32 shift = 0;
+@@ -213,7 +214,8 @@ static void of_mux_clk_setup(struct device_node *node)
+       mask = (1 << fls(mask)) - 1;
+-      clk = _register_mux(NULL, node->name, parent_names, num_parents,
++      name = ti_dt_clk_name(node);
++      clk = _register_mux(NULL, name, parent_names, num_parents,
+                           flags, &reg, shift, mask, latch, clk_mux_flags,
+                           NULL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/clk-ti-update-pll-and-clockdomain-clocks-to-use-ti_d.patch b/queue-5.15/clk-ti-update-pll-and-clockdomain-clocks-to-use-ti_d.patch
new file mode 100644 (file)
index 0000000..2779fd6
--- /dev/null
@@ -0,0 +1,189 @@
+From 3f872f672656ea4f9f168f8cf5ed146cf6c449d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 09:14:48 +0200
+Subject: clk: ti: Update pll and clockdomain clocks to use ti_dt_clk_name()
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 9e56a7d4263ca1c51d867e811cf2dd7e61b6469e ]
+
+Let's update the TI pll and clockdomain clocks to use ti_dt_clk_name()
+instead of devicetree node name if available.
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20220204071449.16762-8-tony@atomide.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 7af5b9eadd64 ("clk: ti: fix double free in of_ti_divider_clk_setup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/apll.c        | 13 +++++++++----
+ drivers/clk/ti/clockdomain.c |  2 +-
+ drivers/clk/ti/dpll.c        |  8 +++++---
+ drivers/clk/ti/fapll.c       | 11 +++++++----
+ 4 files changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
+index ac5bc8857a514..e4db6b9a55c61 100644
+--- a/drivers/clk/ti/apll.c
++++ b/drivers/clk/ti/apll.c
+@@ -139,6 +139,7 @@ static void __init omap_clk_register_apll(void *user,
+       struct clk_hw *hw = user;
+       struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
+       struct dpll_data *ad = clk_hw->dpll_data;
++      const char *name;
+       struct clk *clk;
+       const struct clk_init_data *init = clk_hw->hw.init;
+@@ -166,7 +167,8 @@ static void __init omap_clk_register_apll(void *user,
+       ad->clk_bypass = __clk_get_hw(clk);
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
++      name = ti_dt_clk_name(node);
++      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               kfree(init->parent_names);
+@@ -198,7 +200,7 @@ static void __init of_dra7_apll_setup(struct device_node *node)
+       clk_hw->dpll_data = ad;
+       clk_hw->hw.init = init;
+-      init->name = node->name;
++      init->name = ti_dt_clk_name(node);
+       init->ops = &apll_ck_ops;
+       init->num_parents = of_clk_get_parent_count(node);
+@@ -347,6 +349,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
+       struct dpll_data *ad = NULL;
+       struct clk_hw_omap *clk_hw = NULL;
+       struct clk_init_data *init = NULL;
++      const char *name;
+       struct clk *clk;
+       const char *parent_name;
+       u32 val;
+@@ -362,7 +365,8 @@ static void __init of_omap2_apll_setup(struct device_node *node)
+       clk_hw->dpll_data = ad;
+       clk_hw->hw.init = init;
+       init->ops = &omap2_apll_ops;
+-      init->name = node->name;
++      name = ti_dt_clk_name(node);
++      init->name = name;
+       clk_hw->ops = &omap2_apll_hwops;
+       init->num_parents = of_clk_get_parent_count(node);
+@@ -403,7 +407,8 @@ static void __init of_omap2_apll_setup(struct device_node *node)
+       if (ret)
+               goto cleanup;
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
++      name = ti_dt_clk_name(node);
++      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               kfree(init);
+diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
+index 74831b2752b3b..24179c907774a 100644
+--- a/drivers/clk/ti/clockdomain.c
++++ b/drivers/clk/ti/clockdomain.c
+@@ -131,7 +131,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
+ {
+       struct clk *clk;
+       struct clk_hw *clk_hw;
+-      const char *clkdm_name = node->name;
++      const char *clkdm_name = ti_dt_clk_name(node);
+       int i;
+       unsigned int num_clks;
+diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
+index e9f9aee936ae8..7c6dc8449b22f 100644
+--- a/drivers/clk/ti/dpll.c
++++ b/drivers/clk/ti/dpll.c
+@@ -164,6 +164,7 @@ static void __init _register_dpll(void *user,
+       struct clk_hw *hw = user;
+       struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
+       struct dpll_data *dd = clk_hw->dpll_data;
++      const char *name;
+       struct clk *clk;
+       const struct clk_init_data *init = hw->init;
+@@ -193,7 +194,8 @@ static void __init _register_dpll(void *user,
+       dd->clk_bypass = __clk_get_hw(clk);
+       /* register the clock */
+-      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, node->name);
++      name = ti_dt_clk_name(node);
++      clk = ti_clk_register_omap_hw(NULL, &clk_hw->hw, name);
+       if (!IS_ERR(clk)) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+@@ -227,7 +229,7 @@ static void _register_dpll_x2(struct device_node *node,
+       struct clk *clk;
+       struct clk_init_data init = { NULL };
+       struct clk_hw_omap *clk_hw;
+-      const char *name = node->name;
++      const char *name = ti_dt_clk_name(node);
+       const char *parent_name;
+       parent_name = of_clk_get_parent_name(node, 0);
+@@ -304,7 +306,7 @@ static void __init of_ti_dpll_setup(struct device_node *node,
+       clk_hw->ops = &clkhwops_omap3_dpll;
+       clk_hw->hw.init = init;
+-      init->name = node->name;
++      init->name = ti_dt_clk_name(node);
+       init->ops = ops;
+       init->num_parents = of_clk_get_parent_count(node);
+diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c
+index 8024c6d2b9e95..749c6b73abff3 100644
+--- a/drivers/clk/ti/fapll.c
++++ b/drivers/clk/ti/fapll.c
+@@ -19,6 +19,8 @@
+ #include <linux/of_address.h>
+ #include <linux/clk/ti.h>
++#include "clock.h"
++
+ /* FAPLL Control Register PLL_CTRL */
+ #define FAPLL_MAIN_MULT_N_SHIFT       16
+ #define FAPLL_MAIN_DIV_P_SHIFT        8
+@@ -542,6 +544,7 @@ static void __init ti_fapll_setup(struct device_node *node)
+       struct clk_init_data *init = NULL;
+       const char *parent_name[2];
+       struct clk *pll_clk;
++      const char *name;
+       int i;
+       fd = kzalloc(sizeof(*fd), GFP_KERNEL);
+@@ -559,7 +562,8 @@ static void __init ti_fapll_setup(struct device_node *node)
+               goto free;
+       init->ops = &ti_fapll_ops;
+-      init->name = node->name;
++      name = ti_dt_clk_name(node);
++      init->name = name;
+       init->num_parents = of_clk_get_parent_count(node);
+       if (init->num_parents != 2) {
+@@ -591,7 +595,7 @@ static void __init ti_fapll_setup(struct device_node *node)
+       if (fapll_is_ddr_pll(fd->base))
+               fd->bypass_bit_inverted = true;
+-      fd->name = node->name;
++      fd->name = name;
+       fd->hw.init = init;
+       /* Register the parent PLL */
+@@ -638,8 +642,7 @@ static void __init ti_fapll_setup(struct device_node *node)
+                               freq = NULL;
+               }
+               synth_clk = ti_fapll_synth_setup(fd, freq, div, output_instance,
+-                                               output_name, node->name,
+-                                               pll_clk);
++                                               output_name, name, pll_clk);
+               if (IS_ERR(synth_clk))
+                       continue;
+-- 
+2.42.0
+
diff --git a/queue-5.15/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch b/queue-5.15/crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch
new file mode 100644 (file)
index 0000000..43e8409
--- /dev/null
@@ -0,0 +1,39 @@
+From 51648916509b04fb13d4b445e7bf85355ea8e330 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 18:12:37 +0530
+Subject: crypto: caam/jr - fix Chacha20 + Poly1305 self test failure
+
+From: Gaurav Jain <gaurav.jain@nxp.com>
+
+[ Upstream commit a8d3cdcc092fb2f2882acb6c20473a1be0ef4484 ]
+
+key buffer is not copied in chachapoly_setkey function,
+results in wrong output for encryption/decryption operation.
+
+fix this by memcpy the key in caam_ctx key arrary
+
+Fixes: d6bbd4eea243 ("crypto: caam/jr - add support for Chacha20 + Poly1305")
+Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/caam/caamalg.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
+index d3d8bb0a69900..e156238b4da90 100644
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -566,7 +566,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
+       if (keylen != CHACHA_KEY_SIZE + saltlen)
+               return -EINVAL;
+-      ctx->cdata.key_virt = key;
++      memcpy(ctx->key, key, keylen);
++      ctx->cdata.key_virt = ctx->key;
+       ctx->cdata.keylen = keylen - saltlen;
+       return chachapoly_set_sh_desc(aead);
+-- 
+2.42.0
+
diff --git a/queue-5.15/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch b/queue-5.15/crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch
new file mode 100644 (file)
index 0000000..42b18ac
--- /dev/null
@@ -0,0 +1,39 @@
+From 8e7a1bce651a8d8ecac288a59a7a119fc147db55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 15:14:44 +0530
+Subject: crypto: caam/qi2 - fix Chacha20 + Poly1305 self test failure
+
+From: Gaurav Jain <gaurav.jain@nxp.com>
+
+[ Upstream commit 7b8c6aee0d5b864e70c0da82583f9862e374eaf3 ]
+
+key buffer is not copied in chachapoly_setkey function,
+results in wrong output for encryption/decryption operation.
+
+fix this by memcpy the key in caam_ctx key arrary
+
+Fixes: c10a53367901 ("crypto: caam/qi2 - add support for Chacha20 + Poly1305")
+Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/caam/caamalg_qi2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c
+index 6753f0e6e55d1..35c4e29033d55 100644
+--- a/drivers/crypto/caam/caamalg_qi2.c
++++ b/drivers/crypto/caam/caamalg_qi2.c
+@@ -639,7 +639,8 @@ static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
+       if (keylen != CHACHA_KEY_SIZE + saltlen)
+               return -EINVAL;
+-      ctx->cdata.key_virt = key;
++      memcpy(ctx->key, key, keylen);
++      ctx->cdata.key_virt = ctx->key;
+       ctx->cdata.keylen = keylen - saltlen;
+       return chachapoly_set_sh_desc(aead);
+-- 
+2.42.0
+
diff --git a/queue-5.15/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch b/queue-5.15/crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch
new file mode 100644 (file)
index 0000000..903f2c1
--- /dev/null
@@ -0,0 +1,36 @@
+From 3d7fbdb353d28bd8b18652d9136803a479eefebc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 22:17:29 +0200
+Subject: crypto: hisilicon/hpre - Fix a erroneous check after snprintf()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit c977950146720abff14e46d8c53f5638b06a9182 ]
+
+This error handling looks really strange.
+Check if the string has been truncated instead.
+
+Fixes: 02ab994635eb ("crypto: hisilicon - Fixed some tiny bugs of HPRE")
+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/hisilicon/hpre/hpre_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
+index edc61e4105f30..08e56f1da365c 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
+@@ -854,7 +854,7 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm)
+       for (i = 0; i < clusters_num; i++) {
+               ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i);
+-              if (ret < 0)
++              if (ret >= HPRE_DBGFS_VAL_MAX_LEN)
+                       return -EINVAL;
+               tmp_d = debugfs_create_dir(buf, qm->debug.debug_root);
+-- 
+2.42.0
+
diff --git a/queue-5.15/crypto-qat-fix-deadlock-in-backlog-processing.patch b/queue-5.15/crypto-qat-fix-deadlock-in-backlog-processing.patch
new file mode 100644 (file)
index 0000000..f08071f
--- /dev/null
@@ -0,0 +1,110 @@
+From 6b3d9ebde2c07386924ccc81f4ad196bf6e8fa88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 16:33:21 +0100
+Subject: crypto: qat - fix deadlock in backlog processing
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit 203b01001c4d741205b9c329acddc5193ed56fbd ]
+
+If a request has the flag CRYPTO_TFM_REQ_MAY_BACKLOG set, the function
+qat_alg_send_message_maybacklog(), enqueues it in a backlog list if
+either (1) there is already at least one request in the backlog list, or
+(2) the HW ring is nearly full or (3) the enqueue to the HW ring fails.
+If an interrupt occurs right before the lock in qat_alg_backlog_req() is
+taken and the backlog queue is being emptied, then there is no request
+in the HW queues that can trigger a subsequent interrupt that can clear
+the backlog queue. In addition subsequent requests are enqueued to the
+backlog list and not sent to the hardware.
+
+Fix it by holding the lock while taking the decision if the request
+needs to be included in the backlog queue or not. This synchronizes the
+flow with the interrupt handler that drains the backlog queue.
+
+For performance reasons, the logic has been changed to try to enqueue
+first without holding the lock.
+
+Fixes: 386823839732 ("crypto: qat - add backlog mechanism")
+Reported-by: Mikulas Patocka <mpatocka@redhat.com>
+Closes: https://lore.kernel.org/all/af9581e2-58f9-cc19-428f-6f18f1f83d54@redhat.com/T/
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/qat_algs_send.c | 46 ++++++++++---------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/qat_algs_send.c b/drivers/crypto/qat/qat_common/qat_algs_send.c
+index ff5b4347f7831..607ed88f4b197 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs_send.c
++++ b/drivers/crypto/qat/qat_common/qat_algs_send.c
+@@ -39,40 +39,44 @@ void qat_alg_send_backlog(struct qat_instance_backlog *backlog)
+       spin_unlock_bh(&backlog->lock);
+ }
+-static void qat_alg_backlog_req(struct qat_alg_req *req,
+-                              struct qat_instance_backlog *backlog)
+-{
+-      INIT_LIST_HEAD(&req->list);
+-
+-      spin_lock_bh(&backlog->lock);
+-      list_add_tail(&req->list, &backlog->list);
+-      spin_unlock_bh(&backlog->lock);
+-}
+-
+-static int qat_alg_send_message_maybacklog(struct qat_alg_req *req)
++static bool qat_alg_try_enqueue(struct qat_alg_req *req)
+ {
+       struct qat_instance_backlog *backlog = req->backlog;
+       struct adf_etr_ring_data *tx_ring = req->tx_ring;
+       u32 *fw_req = req->fw_req;
+-      /* If any request is already backlogged, then add to backlog list */
++      /* Check if any request is already backlogged */
+       if (!list_empty(&backlog->list))
+-              goto enqueue;
++              return false;
+-      /* If ring is nearly full, then add to backlog list */
++      /* Check if ring is nearly full */
+       if (adf_ring_nearly_full(tx_ring))
+-              goto enqueue;
++              return false;
+-      /* If adding request to HW ring fails, then add to backlog list */
++      /* Try to enqueue to HW ring */
+       if (adf_send_message(tx_ring, fw_req))
+-              goto enqueue;
++              return false;
+-      return -EINPROGRESS;
++      return true;
++}
+-enqueue:
+-      qat_alg_backlog_req(req, backlog);
+-      return -EBUSY;
++static int qat_alg_send_message_maybacklog(struct qat_alg_req *req)
++{
++      struct qat_instance_backlog *backlog = req->backlog;
++      int ret = -EINPROGRESS;
++
++      if (qat_alg_try_enqueue(req))
++              return ret;
++
++      spin_lock_bh(&backlog->lock);
++      if (!qat_alg_try_enqueue(req)) {
++              list_add_tail(&req->list, &backlog->list);
++              ret = -EBUSY;
++      }
++      spin_unlock_bh(&backlog->lock);
++
++      return ret;
+ }
+ int qat_alg_send_message(struct qat_alg_req *req)
+-- 
+2.42.0
+
diff --git a/queue-5.15/crypto-qat-increase-size-of-buffers.patch b/queue-5.15/crypto-qat-increase-size-of-buffers.patch
new file mode 100644 (file)
index 0000000..a72b9c0
--- /dev/null
@@ -0,0 +1,72 @@
+From 8549520c34980a2bed97a24a4a34a7e1da4892e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 10:03:47 +0100
+Subject: crypto: qat - increase size of buffers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+
+[ Upstream commit 4e4e2ed22d505c5bacf65c6a39bfb6d120d24785 ]
+
+Increase the size of the buffers used for composing the names used for
+the transport debugfs entries and the vector name to avoid a potential
+truncation.
+
+This resolves the following errors when compiling the driver with W=1
+and KCFLAGS=-Werror on GCC 12.3.1:
+
+    drivers/crypto/intel/qat/qat_common/adf_transport_debug.c: In function ‘adf_ring_debugfs_add’:
+    drivers/crypto/intel/qat/qat_common/adf_transport_debug.c:100:60: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
+    drivers/crypto/intel/qat/qat_common/adf_isr.c: In function ‘adf_isr_resource_alloc’:
+    drivers/crypto/intel/qat/qat_common/adf_isr.c:197:47: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size between 0 and 5 [-Werror=format-truncation=]
+
+Fixes: a672a9dc872e ("crypto: qat - Intel(R) QAT transport code")
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Reviewed-by: Damian Muszynski <damian.muszynski@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/adf_accel_devices.h   | 2 +-
+ drivers/crypto/qat/qat_common/adf_transport_debug.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+index 580566cfcb04c..3bb67b22edd6e 100644
+--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
++++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
+@@ -24,7 +24,7 @@
+ #define ADF_PCI_MAX_BARS 3
+ #define ADF_DEVICE_NAME_LENGTH 32
+ #define ADF_ETR_MAX_RINGS_PER_BANK 16
+-#define ADF_MAX_MSIX_VECTOR_NAME 16
++#define ADF_MAX_MSIX_VECTOR_NAME 48
+ #define ADF_DEVICE_NAME_PREFIX "qat_"
+ enum adf_accel_capabilities {
+diff --git a/drivers/crypto/qat/qat_common/adf_transport_debug.c b/drivers/crypto/qat/qat_common/adf_transport_debug.c
+index e69e5907f5950..006867f410bd3 100644
+--- a/drivers/crypto/qat/qat_common/adf_transport_debug.c
++++ b/drivers/crypto/qat/qat_common/adf_transport_debug.c
+@@ -90,7 +90,7 @@ DEFINE_SEQ_ATTRIBUTE(adf_ring_debug);
+ int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name)
+ {
+       struct adf_etr_ring_debug_entry *ring_debug;
+-      char entry_name[8];
++      char entry_name[16];
+       ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL);
+       if (!ring_debug)
+@@ -192,7 +192,7 @@ int adf_bank_debugfs_add(struct adf_etr_bank_data *bank)
+ {
+       struct adf_accel_dev *accel_dev = bank->accel_dev;
+       struct dentry *parent = accel_dev->transport->debug;
+-      char name[8];
++      char name[16];
+       snprintf(name, sizeof(name), "bank_%02d", bank->bank_number);
+       bank->bank_debug_dir = debugfs_create_dir(name, parent);
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-mbox-introduce-the-mbox_send-operation.patch b/queue-5.15/cxl-mbox-introduce-the-mbox_send-operation.patch
new file mode 100644 (file)
index 0000000..4e64c30
--- /dev/null
@@ -0,0 +1,249 @@
+From 95450736c43196f26156fd19c4304c558fc7cc04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 22:12:21 -0700
+Subject: cxl/mbox: Introduce the mbox_send operation
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit b64955a92929346f16df058ad2bb53630eb80466 ]
+
+In preparation for implementing a unit test backend transport for ioctl
+operations, and making the mailbox available to the cxl/pmem
+infrastructure, move the existing PCI specific portion of mailbox handling
+to an "mbox_send" operation.
+
+With this split all the PCI-specific transport details are comprehended
+by a single operation and the rest of the mailbox infrastructure is
+'struct cxl_mem' and 'struct cxl_memdev' generic.
+
+Acked-by: Ben Widawsky <ben.widawsky@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ben Widawsky <ben.widawsky@intel.com>
+Link: https://lore.kernel.org/r/163116434098.2460985.9004760022659400540.stgit@dwillia2-desk3.amr.corp.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 88d3917f82ed ("cxl/mem: Fix shutdown order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/cxlmem.h | 42 ++++++++++++++++++++++++
+ drivers/cxl/pci.c    | 76 ++++++++++++--------------------------------
+ 2 files changed, 63 insertions(+), 55 deletions(-)
+
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index e14bcd7a1ba14..c142532db8cb6 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -66,6 +66,45 @@ struct cxl_memdev *
+ devm_cxl_add_memdev(struct cxl_mem *cxlm,
+                   const struct cdevm_file_operations *cdevm_fops);
++/**
++ * struct cxl_mbox_cmd - A command to be submitted to hardware.
++ * @opcode: (input) The command set and command submitted to hardware.
++ * @payload_in: (input) Pointer to the input payload.
++ * @payload_out: (output) Pointer to the output payload. Must be allocated by
++ *             the caller.
++ * @size_in: (input) Number of bytes to load from @payload_in.
++ * @size_out: (input) Max number of bytes loaded into @payload_out.
++ *            (output) Number of bytes generated by the device. For fixed size
++ *            outputs commands this is always expected to be deterministic. For
++ *            variable sized output commands, it tells the exact number of bytes
++ *            written.
++ * @return_code: (output) Error code returned from hardware.
++ *
++ * This is the primary mechanism used to send commands to the hardware.
++ * All the fields except @payload_* correspond exactly to the fields described in
++ * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and
++ * @payload_out are written to, and read from the Command Payload Registers
++ * defined in CXL 2.0 8.2.8.4.8.
++ */
++struct cxl_mbox_cmd {
++      u16 opcode;
++      void *payload_in;
++      void *payload_out;
++      size_t size_in;
++      size_t size_out;
++      u16 return_code;
++#define CXL_MBOX_SUCCESS 0
++};
++
++/*
++ * CXL 2.0 - Memory capacity multiplier
++ * See Section 8.2.9.5
++ *
++ * Volatile, Persistent, and Partition capacities are specified to be in
++ * multiples of 256MB - define a multiplier to convert to/from bytes.
++ */
++#define CXL_CAPACITY_MULTIPLIER SZ_256M
++
+ /**
+  * struct cxl_mem - A CXL memory device
+  * @dev: The device associated with this CXL device.
+@@ -88,6 +127,7 @@ devm_cxl_add_memdev(struct cxl_mem *cxlm,
+  * @active_persistent_bytes: sum of hard + soft persistent
+  * @next_volatile_bytes: volatile capacity change pending device reset
+  * @next_persistent_bytes: persistent capacity change pending device reset
++ * @mbox_send: @dev specific transport for transmitting mailbox commands
+  *
+  * See section 8.2.9.5.2 Capacity Configuration and Label Storage for
+  * details on capacity parameters.
+@@ -115,5 +155,7 @@ struct cxl_mem {
+       u64 active_persistent_bytes;
+       u64 next_volatile_bytes;
+       u64 next_persistent_bytes;
++
++      int (*mbox_send)(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd);
+ };
+ #endif /* __CXL_MEM_H__ */
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index a242bcd950800..e6cf607448bfe 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -64,45 +64,6 @@ enum opcode {
+       CXL_MBOX_OP_MAX                 = 0x10000
+ };
+-/*
+- * CXL 2.0 - Memory capacity multiplier
+- * See Section 8.2.9.5
+- *
+- * Volatile, Persistent, and Partition capacities are specified to be in
+- * multiples of 256MB - define a multiplier to convert to/from bytes.
+- */
+-#define CXL_CAPACITY_MULTIPLIER SZ_256M
+-
+-/**
+- * struct mbox_cmd - A command to be submitted to hardware.
+- * @opcode: (input) The command set and command submitted to hardware.
+- * @payload_in: (input) Pointer to the input payload.
+- * @payload_out: (output) Pointer to the output payload. Must be allocated by
+- *             the caller.
+- * @size_in: (input) Number of bytes to load from @payload_in.
+- * @size_out: (input) Max number of bytes loaded into @payload_out.
+- *            (output) Number of bytes generated by the device. For fixed size
+- *            outputs commands this is always expected to be deterministic. For
+- *            variable sized output commands, it tells the exact number of bytes
+- *            written.
+- * @return_code: (output) Error code returned from hardware.
+- *
+- * This is the primary mechanism used to send commands to the hardware.
+- * All the fields except @payload_* correspond exactly to the fields described in
+- * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and
+- * @payload_out are written to, and read from the Command Payload Registers
+- * defined in CXL 2.0 8.2.8.4.8.
+- */
+-struct mbox_cmd {
+-      u16 opcode;
+-      void *payload_in;
+-      void *payload_out;
+-      size_t size_in;
+-      size_t size_out;
+-      u16 return_code;
+-#define CXL_MBOX_SUCCESS 0
+-};
+-
+ static DECLARE_RWSEM(cxl_memdev_rwsem);
+ static struct dentry *cxl_debugfs;
+ static bool cxl_raw_allow_all;
+@@ -266,7 +227,7 @@ static bool cxl_is_security_command(u16 opcode)
+ }
+ static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm,
+-                               struct mbox_cmd *mbox_cmd)
++                               struct cxl_mbox_cmd *mbox_cmd)
+ {
+       struct device *dev = cxlm->dev;
+@@ -297,7 +258,7 @@ static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm,
+  * mailbox.
+  */
+ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+-                                 struct mbox_cmd *mbox_cmd)
++                                 struct cxl_mbox_cmd *mbox_cmd)
+ {
+       void __iomem *payload = cxlm->regs.mbox + CXLDEV_MBOX_PAYLOAD_OFFSET;
+       struct device *dev = cxlm->dev;
+@@ -472,6 +433,20 @@ static void cxl_mem_mbox_put(struct cxl_mem *cxlm)
+       mutex_unlock(&cxlm->mbox_mutex);
+ }
++static int cxl_pci_mbox_send(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd)
++{
++      int rc;
++
++      rc = cxl_mem_mbox_get(cxlm);
++      if (rc)
++              return rc;
++
++      rc = __cxl_mem_mbox_send_cmd(cxlm, cmd);
++      cxl_mem_mbox_put(cxlm);
++
++      return rc;
++}
++
+ /**
+  * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
+  * @cxlm: The CXL memory device to communicate with.
+@@ -503,7 +478,7 @@ static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
+                                       s32 *size_out, u32 *retval)
+ {
+       struct device *dev = cxlm->dev;
+-      struct mbox_cmd mbox_cmd = {
++      struct cxl_mbox_cmd mbox_cmd = {
+               .opcode = cmd->opcode,
+               .size_in = cmd->info.size_in,
+               .size_out = cmd->info.size_out,
+@@ -525,10 +500,6 @@ static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
+               }
+       }
+-      rc = cxl_mem_mbox_get(cxlm);
+-      if (rc)
+-              goto out;
+-
+       dev_dbg(dev,
+               "Submitting %s command for user\n"
+               "\topcode: %x\n"
+@@ -539,8 +510,7 @@ static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
+       dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW,
+                     "raw command path used\n");
+-      rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
+-      cxl_mem_mbox_put(cxlm);
++      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
+       if (rc)
+               goto out;
+@@ -874,7 +844,7 @@ static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode,
+                                void *out, size_t out_size)
+ {
+       const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
+-      struct mbox_cmd mbox_cmd = {
++      struct cxl_mbox_cmd mbox_cmd = {
+               .opcode = opcode,
+               .payload_in = in,
+               .size_in = in_size,
+@@ -886,12 +856,7 @@ static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode,
+       if (out_size > cxlm->payload_size)
+               return -E2BIG;
+-      rc = cxl_mem_mbox_get(cxlm);
+-      if (rc)
+-              return rc;
+-
+-      rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd);
+-      cxl_mem_mbox_put(cxlm);
++      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
+       if (rc)
+               return rc;
+@@ -913,6 +878,7 @@ static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm)
+ {
+       const int cap = readl(cxlm->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET);
++      cxlm->mbox_send = cxl_pci_mbox_send;
+       cxlm->payload_size =
+               1 << FIELD_GET(CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK, cap);
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-mbox-move-mailbox-and-other-non-pci-specific-inf.patch b/queue-5.15/cxl-mbox-move-mailbox-and-other-non-pci-specific-inf.patch
new file mode 100644 (file)
index 0000000..8bcdfab
--- /dev/null
@@ -0,0 +1,2190 @@
+From ee60d6cb210a5458e01c8c2e243b44605f8744d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 22:12:32 -0700
+Subject: cxl/mbox: Move mailbox and other non-PCI specific infrastructure to
+ the core
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 4faf31b43468c58e2c8c91cc5fa26f08a6b733be ]
+
+Now that the internals of mailbox operations are abstracted from the PCI
+specifics a bulk of infrastructure can move to the core.
+
+The CXL_PMEM driver intends to proxy LIBNVDIMM UAPI and driver requests
+to the equivalent functionality provided by the CXL hardware mailbox
+interface. In support of that intent move the mailbox implementation to
+a shared location for the CXL_PCI driver native IOCTL path and CXL_PMEM
+nvdimm command proxy path to share.
+
+A unit test framework seeks to implement a unit test backend transport
+for mailbox commands to communicate mocked up payloads. It can reuse all
+of the mailbox infrastructure minus the PCI specifics, so that also gets
+moved to the core.
+
+Finally with the mailbox infrastructure and ioctl handling being
+transport generic there is no longer any need to pass file
+file_operations to devm_cxl_add_memdev(). That allows all the ioctl
+boilerplate to move into the core for unit test reuse.
+
+No functional change intended, just code movement.
+
+Acked-by: Ben Widawsky <ben.widawsky@intel.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/163116435233.2460985.16197340449713287180.stgit@dwillia2-desk3.amr.corp.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 88d3917f82ed ("cxl/mem: Fix shutdown order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../driver-api/cxl/memory-devices.rst         |   3 +
+ drivers/cxl/core/Makefile                     |   1 +
+ drivers/cxl/core/bus.c                        |   4 +
+ drivers/cxl/core/core.h                       |   8 +
+ drivers/cxl/core/mbox.c                       | 825 ++++++++++++++++
+ drivers/cxl/core/memdev.c                     |  81 +-
+ drivers/cxl/cxlmem.h                          |  78 +-
+ drivers/cxl/pci.c                             | 924 +-----------------
+ 8 files changed, 975 insertions(+), 949 deletions(-)
+ create mode 100644 drivers/cxl/core/mbox.c
+
+diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst
+index 50ebcda17ad05..4624951b5c38e 100644
+--- a/Documentation/driver-api/cxl/memory-devices.rst
++++ b/Documentation/driver-api/cxl/memory-devices.rst
+@@ -45,6 +45,9 @@ CXL Core
+ .. kernel-doc:: drivers/cxl/core/regs.c
+    :doc: cxl registers
++.. kernel-doc:: drivers/cxl/core/mbox.c
++   :doc: cxl mbox
++
+ External Interfaces
+ ===================
+diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile
+index 0fdbf3c6ac1a3..07eb8e1fb8a67 100644
+--- a/drivers/cxl/core/Makefile
++++ b/drivers/cxl/core/Makefile
+@@ -6,3 +6,4 @@ cxl_core-y := bus.o
+ cxl_core-y += pmem.o
+ cxl_core-y += regs.o
+ cxl_core-y += memdev.o
++cxl_core-y += mbox.o
+diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c
+index 0987a6423ee06..e37bd74c4d9e7 100644
+--- a/drivers/cxl/core/bus.c
++++ b/drivers/cxl/core/bus.c
+@@ -639,6 +639,8 @@ static __init int cxl_core_init(void)
+ {
+       int rc;
++      cxl_mbox_init();
++
+       rc = cxl_memdev_init();
+       if (rc)
+               return rc;
+@@ -650,6 +652,7 @@ static __init int cxl_core_init(void)
+ err:
+       cxl_memdev_exit();
++      cxl_mbox_exit();
+       return rc;
+ }
+@@ -657,6 +660,7 @@ static void cxl_core_exit(void)
+ {
+       bus_unregister(&cxl_bus_type);
+       cxl_memdev_exit();
++      cxl_mbox_exit();
+ }
+ module_init(cxl_core_init);
+diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
+index 036a3c8106b44..c85b7fbad02dd 100644
+--- a/drivers/cxl/core/core.h
++++ b/drivers/cxl/core/core.h
+@@ -14,7 +14,15 @@ static inline void unregister_cxl_dev(void *dev)
+       device_unregister(dev);
+ }
++struct cxl_send_command;
++struct cxl_mem_query_commands;
++int cxl_query_cmd(struct cxl_memdev *cxlmd,
++                struct cxl_mem_query_commands __user *q);
++int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s);
++
+ int cxl_memdev_init(void);
+ void cxl_memdev_exit(void);
++void cxl_mbox_init(void);
++void cxl_mbox_exit(void);
+ #endif /* __CXL_CORE_H__ */
+diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
+new file mode 100644
+index 0000000000000..31e1839917262
+--- /dev/null
++++ b/drivers/cxl/core/mbox.c
+@@ -0,0 +1,825 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
++#include <linux/io-64-nonatomic-lo-hi.h>
++#include <linux/security.h>
++#include <linux/debugfs.h>
++#include <linux/mutex.h>
++#include <cxlmem.h>
++#include <cxl.h>
++
++#include "core.h"
++
++static bool cxl_raw_allow_all;
++
++/**
++ * DOC: cxl mbox
++ *
++ * Core implementation of the CXL 2.0 Type-3 Memory Device Mailbox. The
++ * implementation is used by the cxl_pci driver to initialize the device
++ * and implement the cxl_mem.h IOCTL UAPI. It also implements the
++ * backend of the cxl_pmem_ctl() transport for LIBNVDIMM.
++ */
++
++#define cxl_for_each_cmd(cmd)                                                  \
++      for ((cmd) = &cxl_mem_commands[0];                                     \
++           ((cmd) - cxl_mem_commands) < ARRAY_SIZE(cxl_mem_commands); (cmd)++)
++
++#define CXL_CMD(_id, sin, sout, _flags)                                        \
++      [CXL_MEM_COMMAND_ID_##_id] = {                                         \
++      .info = {                                                              \
++                      .id = CXL_MEM_COMMAND_ID_##_id,                        \
++                      .size_in = sin,                                        \
++                      .size_out = sout,                                      \
++              },                                                             \
++      .opcode = CXL_MBOX_OP_##_id,                                           \
++      .flags = _flags,                                                       \
++      }
++
++/*
++ * This table defines the supported mailbox commands for the driver. This table
++ * is made up of a UAPI structure. Non-negative values as parameters in the
++ * table will be validated against the user's input. For example, if size_in is
++ * 0, and the user passed in 1, it is an error.
++ */
++static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
++      CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
++#ifdef CONFIG_CXL_MEM_RAW_COMMANDS
++      CXL_CMD(RAW, ~0, ~0, 0),
++#endif
++      CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
++      CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
++      CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
++      CXL_CMD(GET_LSA, 0x8, ~0, 0),
++      CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
++      CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
++      CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0),
++      CXL_CMD(SET_LSA, ~0, 0, 0),
++      CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0),
++      CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0),
++      CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0),
++      CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0),
++      CXL_CMD(GET_POISON, 0x10, ~0, 0),
++      CXL_CMD(INJECT_POISON, 0x8, 0, 0),
++      CXL_CMD(CLEAR_POISON, 0x48, 0, 0),
++      CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
++      CXL_CMD(SCAN_MEDIA, 0x11, 0, 0),
++      CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0),
++};
++
++/*
++ * Commands that RAW doesn't permit. The rationale for each:
++ *
++ * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment /
++ * coordination of transaction timeout values at the root bridge level.
++ *
++ * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live
++ * and needs to be coordinated with HDM updates.
++ *
++ * CXL_MBOX_OP_SET_LSA: The label storage area may be cached by the
++ * driver and any writes from userspace invalidates those contents.
++ *
++ * CXL_MBOX_OP_SET_SHUTDOWN_STATE: Set shutdown state assumes no writes
++ * to the device after it is marked clean, userspace can not make that
++ * assertion.
++ *
++ * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that
++ * is kept up to date with patrol notifications and error management.
++ */
++static u16 cxl_disabled_raw_commands[] = {
++      CXL_MBOX_OP_ACTIVATE_FW,
++      CXL_MBOX_OP_SET_PARTITION_INFO,
++      CXL_MBOX_OP_SET_LSA,
++      CXL_MBOX_OP_SET_SHUTDOWN_STATE,
++      CXL_MBOX_OP_SCAN_MEDIA,
++      CXL_MBOX_OP_GET_SCAN_MEDIA,
++};
++
++/*
++ * Command sets that RAW doesn't permit. All opcodes in this set are
++ * disabled because they pass plain text security payloads over the
++ * user/kernel boundary. This functionality is intended to be wrapped
++ * behind the keys ABI which allows for encrypted payloads in the UAPI
++ */
++static u8 security_command_sets[] = {
++      0x44, /* Sanitize */
++      0x45, /* Persistent Memory Data-at-rest Security */
++      0x46, /* Security Passthrough */
++};
++
++static bool cxl_is_security_command(u16 opcode)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(security_command_sets); i++)
++              if (security_command_sets[i] == (opcode >> 8))
++                      return true;
++      return false;
++}
++
++static struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
++{
++      struct cxl_mem_command *c;
++
++      cxl_for_each_cmd(c)
++              if (c->opcode == opcode)
++                      return c;
++
++      return NULL;
++}
++
++/**
++ * cxl_mem_mbox_send_cmd() - Send a mailbox command to a memory device.
++ * @cxlm: The CXL memory device to communicate with.
++ * @opcode: Opcode for the mailbox command.
++ * @in: The input payload for the mailbox command.
++ * @in_size: The length of the input payload
++ * @out: Caller allocated buffer for the output.
++ * @out_size: Expected size of output.
++ *
++ * Context: Any context. Will acquire and release mbox_mutex.
++ * Return:
++ *  * %>=0    - Number of bytes returned in @out.
++ *  * %-E2BIG - Payload is too large for hardware.
++ *  * %-EBUSY - Couldn't acquire exclusive mailbox access.
++ *  * %-EFAULT        - Hardware error occurred.
++ *  * %-ENXIO - Command completed, but device reported an error.
++ *  * %-EIO   - Unexpected output size.
++ *
++ * Mailbox commands may execute successfully yet the device itself reported an
++ * error. While this distinction can be useful for commands from userspace, the
++ * kernel will only be able to use results when both are successful.
++ *
++ * See __cxl_mem_mbox_send_cmd()
++ */
++int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, void *in,
++                        size_t in_size, void *out, size_t out_size)
++{
++      const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
++      struct cxl_mbox_cmd mbox_cmd = {
++              .opcode = opcode,
++              .payload_in = in,
++              .size_in = in_size,
++              .size_out = out_size,
++              .payload_out = out,
++      };
++      int rc;
++
++      if (out_size > cxlm->payload_size)
++              return -E2BIG;
++
++      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
++      if (rc)
++              return rc;
++
++      /* TODO: Map return code to proper kernel style errno */
++      if (mbox_cmd.return_code != CXL_MBOX_SUCCESS)
++              return -ENXIO;
++
++      /*
++       * Variable sized commands can't be validated and so it's up to the
++       * caller to do that if they wish.
++       */
++      if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size)
++              return -EIO;
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(cxl_mem_mbox_send_cmd);
++
++static bool cxl_mem_raw_command_allowed(u16 opcode)
++{
++      int i;
++
++      if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS))
++              return false;
++
++      if (security_locked_down(LOCKDOWN_PCI_ACCESS))
++              return false;
++
++      if (cxl_raw_allow_all)
++              return true;
++
++      if (cxl_is_security_command(opcode))
++              return false;
++
++      for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++)
++              if (cxl_disabled_raw_commands[i] == opcode)
++                      return false;
++
++      return true;
++}
++
++/**
++ * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
++ * @cxlm: &struct cxl_mem device whose mailbox will be used.
++ * @send_cmd: &struct cxl_send_command copied in from userspace.
++ * @out_cmd: Sanitized and populated &struct cxl_mem_command.
++ *
++ * Return:
++ *  * %0      - @out_cmd is ready to send.
++ *  * %-ENOTTY        - Invalid command specified.
++ *  * %-EINVAL        - Reserved fields or invalid values were used.
++ *  * %-ENOMEM        - Input or output buffer wasn't sized properly.
++ *  * %-EPERM - Attempted to use a protected command.
++ *
++ * The result of this command is a fully validated command in @out_cmd that is
++ * safe to send to the hardware.
++ *
++ * See handle_mailbox_cmd_from_user()
++ */
++static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm,
++                                    const struct cxl_send_command *send_cmd,
++                                    struct cxl_mem_command *out_cmd)
++{
++      const struct cxl_command_info *info;
++      struct cxl_mem_command *c;
++
++      if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
++              return -ENOTTY;
++
++      /*
++       * The user can never specify an input payload larger than what hardware
++       * supports, but output can be arbitrarily large (simply write out as
++       * much data as the hardware provides).
++       */
++      if (send_cmd->in.size > cxlm->payload_size)
++              return -EINVAL;
++
++      /*
++       * Checks are bypassed for raw commands but a WARN/taint will occur
++       * later in the callchain
++       */
++      if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) {
++              const struct cxl_mem_command temp = {
++                      .info = {
++                              .id = CXL_MEM_COMMAND_ID_RAW,
++                              .flags = 0,
++                              .size_in = send_cmd->in.size,
++                              .size_out = send_cmd->out.size,
++                      },
++                      .opcode = send_cmd->raw.opcode
++              };
++
++              if (send_cmd->raw.rsvd)
++                      return -EINVAL;
++
++              /*
++               * Unlike supported commands, the output size of RAW commands
++               * gets passed along without further checking, so it must be
++               * validated here.
++               */
++              if (send_cmd->out.size > cxlm->payload_size)
++                      return -EINVAL;
++
++              if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
++                      return -EPERM;
++
++              memcpy(out_cmd, &temp, sizeof(temp));
++
++              return 0;
++      }
++
++      if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
++              return -EINVAL;
++
++      if (send_cmd->rsvd)
++              return -EINVAL;
++
++      if (send_cmd->in.rsvd || send_cmd->out.rsvd)
++              return -EINVAL;
++
++      /* Convert user's command into the internal representation */
++      c = &cxl_mem_commands[send_cmd->id];
++      info = &c->info;
++
++      /* Check that the command is enabled for hardware */
++      if (!test_bit(info->id, cxlm->enabled_cmds))
++              return -ENOTTY;
++
++      /* Check the input buffer is the expected size */
++      if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
++              return -ENOMEM;
++
++      /* Check the output buffer is at least large enough */
++      if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
++              return -ENOMEM;
++
++      memcpy(out_cmd, c, sizeof(*c));
++      out_cmd->info.size_in = send_cmd->in.size;
++      /*
++       * XXX: out_cmd->info.size_out will be controlled by the driver, and the
++       * specified number of bytes @send_cmd->out.size will be copied back out
++       * to userspace.
++       */
++
++      return 0;
++}
++
++#define cxl_cmd_count ARRAY_SIZE(cxl_mem_commands)
++
++int cxl_query_cmd(struct cxl_memdev *cxlmd,
++                struct cxl_mem_query_commands __user *q)
++{
++      struct device *dev = &cxlmd->dev;
++      struct cxl_mem_command *cmd;
++      u32 n_commands;
++      int j = 0;
++
++      dev_dbg(dev, "Query IOCTL\n");
++
++      if (get_user(n_commands, &q->n_commands))
++              return -EFAULT;
++
++      /* returns the total number if 0 elements are requested. */
++      if (n_commands == 0)
++              return put_user(cxl_cmd_count, &q->n_commands);
++
++      /*
++       * otherwise, return max(n_commands, total commands) cxl_command_info
++       * structures.
++       */
++      cxl_for_each_cmd(cmd) {
++              const struct cxl_command_info *info = &cmd->info;
++
++              if (copy_to_user(&q->commands[j++], info, sizeof(*info)))
++                      return -EFAULT;
++
++              if (j == n_commands)
++                      break;
++      }
++
++      return 0;
++}
++
++/**
++ * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
++ * @cxlm: The CXL memory device to communicate with.
++ * @cmd: The validated command.
++ * @in_payload: Pointer to userspace's input payload.
++ * @out_payload: Pointer to userspace's output payload.
++ * @size_out: (Input) Max payload size to copy out.
++ *            (Output) Payload size hardware generated.
++ * @retval: Hardware generated return code from the operation.
++ *
++ * Return:
++ *  * %0      - Mailbox transaction succeeded. This implies the mailbox
++ *              protocol completed successfully not that the operation itself
++ *              was successful.
++ *  * %-ENOMEM  - Couldn't allocate a bounce buffer.
++ *  * %-EFAULT        - Something happened with copy_to/from_user.
++ *  * %-EINTR - Mailbox acquisition interrupted.
++ *  * %-EXXX  - Transaction level failures.
++ *
++ * Creates the appropriate mailbox command and dispatches it on behalf of a
++ * userspace request. The input and output payloads are copied between
++ * userspace.
++ *
++ * See cxl_send_cmd().
++ */
++static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
++                                      const struct cxl_mem_command *cmd,
++                                      u64 in_payload, u64 out_payload,
++                                      s32 *size_out, u32 *retval)
++{
++      struct device *dev = cxlm->dev;
++      struct cxl_mbox_cmd mbox_cmd = {
++              .opcode = cmd->opcode,
++              .size_in = cmd->info.size_in,
++              .size_out = cmd->info.size_out,
++      };
++      int rc;
++
++      if (cmd->info.size_out) {
++              mbox_cmd.payload_out = kvzalloc(cmd->info.size_out, GFP_KERNEL);
++              if (!mbox_cmd.payload_out)
++                      return -ENOMEM;
++      }
++
++      if (cmd->info.size_in) {
++              mbox_cmd.payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
++                                                 cmd->info.size_in);
++              if (IS_ERR(mbox_cmd.payload_in)) {
++                      kvfree(mbox_cmd.payload_out);
++                      return PTR_ERR(mbox_cmd.payload_in);
++              }
++      }
++
++      dev_dbg(dev,
++              "Submitting %s command for user\n"
++              "\topcode: %x\n"
++              "\tsize: %ub\n",
++              cxl_command_names[cmd->info.id].name, mbox_cmd.opcode,
++              cmd->info.size_in);
++
++      dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW,
++                    "raw command path used\n");
++
++      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
++      if (rc)
++              goto out;
++
++      /*
++       * @size_out contains the max size that's allowed to be written back out
++       * to userspace. While the payload may have written more output than
++       * this it will have to be ignored.
++       */
++      if (mbox_cmd.size_out) {
++              dev_WARN_ONCE(dev, mbox_cmd.size_out > *size_out,
++                            "Invalid return size\n");
++              if (copy_to_user(u64_to_user_ptr(out_payload),
++                               mbox_cmd.payload_out, mbox_cmd.size_out)) {
++                      rc = -EFAULT;
++                      goto out;
++              }
++      }
++
++      *size_out = mbox_cmd.size_out;
++      *retval = mbox_cmd.return_code;
++
++out:
++      kvfree(mbox_cmd.payload_in);
++      kvfree(mbox_cmd.payload_out);
++      return rc;
++}
++
++int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s)
++{
++      struct cxl_mem *cxlm = cxlmd->cxlm;
++      struct device *dev = &cxlmd->dev;
++      struct cxl_send_command send;
++      struct cxl_mem_command c;
++      int rc;
++
++      dev_dbg(dev, "Send IOCTL\n");
++
++      if (copy_from_user(&send, s, sizeof(send)))
++              return -EFAULT;
++
++      rc = cxl_validate_cmd_from_user(cxlmd->cxlm, &send, &c);
++      if (rc)
++              return rc;
++
++      /* Prepare to handle a full payload for variable sized output */
++      if (c.info.size_out < 0)
++              c.info.size_out = cxlm->payload_size;
++
++      rc = handle_mailbox_cmd_from_user(cxlm, &c, send.in.payload,
++                                        send.out.payload, &send.out.size,
++                                        &send.retval);
++      if (rc)
++              return rc;
++
++      if (copy_to_user(s, &send, sizeof(send)))
++              return -EFAULT;
++
++      return 0;
++}
++
++static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out)
++{
++      u32 remaining = size;
++      u32 offset = 0;
++
++      while (remaining) {
++              u32 xfer_size = min_t(u32, remaining, cxlm->payload_size);
++              struct cxl_mbox_get_log {
++                      uuid_t uuid;
++                      __le32 offset;
++                      __le32 length;
++              } __packed log = {
++                      .uuid = *uuid,
++                      .offset = cpu_to_le32(offset),
++                      .length = cpu_to_le32(xfer_size)
++              };
++              int rc;
++
++              rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_LOG, &log,
++                                         sizeof(log), out, xfer_size);
++              if (rc < 0)
++                      return rc;
++
++              out += xfer_size;
++              remaining -= xfer_size;
++              offset += xfer_size;
++      }
++
++      return 0;
++}
++
++/**
++ * cxl_walk_cel() - Walk through the Command Effects Log.
++ * @cxlm: Device.
++ * @size: Length of the Command Effects Log.
++ * @cel: CEL
++ *
++ * Iterate over each entry in the CEL and determine if the driver supports the
++ * command. If so, the command is enabled for the device and can be used later.
++ */
++static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel)
++{
++      struct cel_entry {
++              __le16 opcode;
++              __le16 effect;
++      } __packed * cel_entry;
++      const int cel_entries = size / sizeof(*cel_entry);
++      int i;
++
++      cel_entry = (struct cel_entry *)cel;
++
++      for (i = 0; i < cel_entries; i++) {
++              u16 opcode = le16_to_cpu(cel_entry[i].opcode);
++              struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
++
++              if (!cmd) {
++                      dev_dbg(cxlm->dev,
++                              "Opcode 0x%04x unsupported by driver", opcode);
++                      continue;
++              }
++
++              set_bit(cmd->info.id, cxlm->enabled_cmds);
++      }
++}
++
++struct cxl_mbox_get_supported_logs {
++      __le16 entries;
++      u8 rsvd[6];
++      struct gsl_entry {
++              uuid_t uuid;
++              __le32 size;
++      } __packed entry[];
++} __packed;
++
++static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
++{
++      struct cxl_mbox_get_supported_logs *ret;
++      int rc;
++
++      ret = kvmalloc(cxlm->payload_size, GFP_KERNEL);
++      if (!ret)
++              return ERR_PTR(-ENOMEM);
++
++      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_SUPPORTED_LOGS, NULL,
++                                 0, ret, cxlm->payload_size);
++      if (rc < 0) {
++              kvfree(ret);
++              return ERR_PTR(rc);
++      }
++
++      return ret;
++}
++
++enum {
++      CEL_UUID,
++      VENDOR_DEBUG_UUID,
++};
++
++/* See CXL 2.0 Table 170. Get Log Input Payload */
++static const uuid_t log_uuid[] = {
++      [CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96,
++                             0xb1, 0x62, 0x3b, 0x3f, 0x17),
++      [VENDOR_DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f,
++                                      0xd6, 0x07, 0x19, 0x40, 0x3d, 0x86),
++};
++
++/**
++ * cxl_mem_enumerate_cmds() - Enumerate commands for a device.
++ * @cxlm: The device.
++ *
++ * Returns 0 if enumerate completed successfully.
++ *
++ * CXL devices have optional support for certain commands. This function will
++ * determine the set of supported commands for the hardware and update the
++ * enabled_cmds bitmap in the @cxlm.
++ */
++int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm)
++{
++      struct cxl_mbox_get_supported_logs *gsl;
++      struct device *dev = cxlm->dev;
++      struct cxl_mem_command *cmd;
++      int i, rc;
++
++      gsl = cxl_get_gsl(cxlm);
++      if (IS_ERR(gsl))
++              return PTR_ERR(gsl);
++
++      rc = -ENOENT;
++      for (i = 0; i < le16_to_cpu(gsl->entries); i++) {
++              u32 size = le32_to_cpu(gsl->entry[i].size);
++              uuid_t uuid = gsl->entry[i].uuid;
++              u8 *log;
++
++              dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size);
++
++              if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
++                      continue;
++
++              log = kvmalloc(size, GFP_KERNEL);
++              if (!log) {
++                      rc = -ENOMEM;
++                      goto out;
++              }
++
++              rc = cxl_xfer_log(cxlm, &uuid, size, log);
++              if (rc) {
++                      kvfree(log);
++                      goto out;
++              }
++
++              cxl_walk_cel(cxlm, size, log);
++              kvfree(log);
++
++              /* In case CEL was bogus, enable some default commands. */
++              cxl_for_each_cmd(cmd)
++                      if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE)
++                              set_bit(cmd->info.id, cxlm->enabled_cmds);
++
++              /* Found the required CEL */
++              rc = 0;
++      }
++
++out:
++      kvfree(gsl);
++      return rc;
++}
++EXPORT_SYMBOL_GPL(cxl_mem_enumerate_cmds);
++
++/**
++ * cxl_mem_get_partition_info - Get partition info
++ * @cxlm: cxl_mem instance to update partition info
++ *
++ * Retrieve the current partition info for the device specified.  The active
++ * values are the current capacity in bytes.  If not 0, the 'next' values are
++ * the pending values, in bytes, which take affect on next cold reset.
++ *
++ * Return: 0 if no error: or the result of the mailbox command.
++ *
++ * See CXL @8.2.9.5.2.1 Get Partition Info
++ */
++static int cxl_mem_get_partition_info(struct cxl_mem *cxlm)
++{
++      struct cxl_mbox_get_partition_info {
++              __le64 active_volatile_cap;
++              __le64 active_persistent_cap;
++              __le64 next_volatile_cap;
++              __le64 next_persistent_cap;
++      } __packed pi;
++      int rc;
++
++      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO,
++                                 NULL, 0, &pi, sizeof(pi));
++
++      if (rc)
++              return rc;
++
++      cxlm->active_volatile_bytes =
++              le64_to_cpu(pi.active_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->active_persistent_bytes =
++              le64_to_cpu(pi.active_persistent_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->next_volatile_bytes =
++              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->next_persistent_bytes =
++              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
++
++      return 0;
++}
++
++/**
++ * cxl_mem_identify() - Send the IDENTIFY command to the device.
++ * @cxlm: The device to identify.
++ *
++ * Return: 0 if identify was executed successfully.
++ *
++ * This will dispatch the identify command to the device and on success populate
++ * structures to be exported to sysfs.
++ */
++int cxl_mem_identify(struct cxl_mem *cxlm)
++{
++      /* See CXL 2.0 Table 175 Identify Memory Device Output Payload */
++      struct cxl_mbox_identify {
++              char fw_revision[0x10];
++              __le64 total_capacity;
++              __le64 volatile_capacity;
++              __le64 persistent_capacity;
++              __le64 partition_align;
++              __le16 info_event_log_size;
++              __le16 warning_event_log_size;
++              __le16 failure_event_log_size;
++              __le16 fatal_event_log_size;
++              __le32 lsa_size;
++              u8 poison_list_max_mer[3];
++              __le16 inject_poison_limit;
++              u8 poison_caps;
++              u8 qos_telemetry_caps;
++      } __packed id;
++      int rc;
++
++      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_IDENTIFY, NULL, 0, &id,
++                                 sizeof(id));
++      if (rc < 0)
++              return rc;
++
++      cxlm->total_bytes =
++              le64_to_cpu(id.total_capacity) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->volatile_only_bytes =
++              le64_to_cpu(id.volatile_capacity) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->persistent_only_bytes =
++              le64_to_cpu(id.persistent_capacity) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->partition_align_bytes =
++              le64_to_cpu(id.partition_align) * CXL_CAPACITY_MULTIPLIER;
++
++      dev_dbg(cxlm->dev,
++              "Identify Memory Device\n"
++              "     total_bytes = %#llx\n"
++              "     volatile_only_bytes = %#llx\n"
++              "     persistent_only_bytes = %#llx\n"
++              "     partition_align_bytes = %#llx\n",
++              cxlm->total_bytes, cxlm->volatile_only_bytes,
++              cxlm->persistent_only_bytes, cxlm->partition_align_bytes);
++
++      cxlm->lsa_size = le32_to_cpu(id.lsa_size);
++      memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(cxl_mem_identify);
++
++int cxl_mem_create_range_info(struct cxl_mem *cxlm)
++{
++      int rc;
++
++      if (cxlm->partition_align_bytes == 0) {
++              cxlm->ram_range.start = 0;
++              cxlm->ram_range.end = cxlm->volatile_only_bytes - 1;
++              cxlm->pmem_range.start = cxlm->volatile_only_bytes;
++              cxlm->pmem_range.end = cxlm->volatile_only_bytes +
++                                     cxlm->persistent_only_bytes - 1;
++              return 0;
++      }
++
++      rc = cxl_mem_get_partition_info(cxlm);
++      if (rc) {
++              dev_err(cxlm->dev, "Failed to query partition information\n");
++              return rc;
++      }
++
++      dev_dbg(cxlm->dev,
++              "Get Partition Info\n"
++              "     active_volatile_bytes = %#llx\n"
++              "     active_persistent_bytes = %#llx\n"
++              "     next_volatile_bytes = %#llx\n"
++              "     next_persistent_bytes = %#llx\n",
++              cxlm->active_volatile_bytes, cxlm->active_persistent_bytes,
++              cxlm->next_volatile_bytes, cxlm->next_persistent_bytes);
++
++      cxlm->ram_range.start = 0;
++      cxlm->ram_range.end = cxlm->active_volatile_bytes - 1;
++
++      cxlm->pmem_range.start = cxlm->active_volatile_bytes;
++      cxlm->pmem_range.end =
++              cxlm->active_volatile_bytes + cxlm->active_persistent_bytes - 1;
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(cxl_mem_create_range_info);
++
++struct cxl_mem *cxl_mem_create(struct device *dev)
++{
++      struct cxl_mem *cxlm;
++
++      cxlm = devm_kzalloc(dev, sizeof(*cxlm), GFP_KERNEL);
++      if (!cxlm) {
++              dev_err(dev, "No memory available\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      mutex_init(&cxlm->mbox_mutex);
++      cxlm->dev = dev;
++      cxlm->enabled_cmds =
++              devm_kmalloc_array(dev, BITS_TO_LONGS(cxl_cmd_count),
++                                 sizeof(unsigned long),
++                                 GFP_KERNEL | __GFP_ZERO);
++      if (!cxlm->enabled_cmds) {
++              dev_err(dev, "No memory available for bitmap\n");
++              return ERR_PTR(-ENOMEM);
++      }
++
++      return cxlm;
++}
++EXPORT_SYMBOL_GPL(cxl_mem_create);
++
++static struct dentry *cxl_debugfs;
++
++void __init cxl_mbox_init(void)
++{
++      struct dentry *mbox_debugfs;
++
++      cxl_debugfs = debugfs_create_dir("cxl", NULL);
++      mbox_debugfs = debugfs_create_dir("mbox", cxl_debugfs);
++      debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs,
++                          &cxl_raw_allow_all);
++}
++
++void cxl_mbox_exit(void)
++{
++      debugfs_remove_recursive(cxl_debugfs);
++}
+diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
+index 331ef7d6c5984..df2ba87238c29 100644
+--- a/drivers/cxl/core/memdev.c
++++ b/drivers/cxl/core/memdev.c
+@@ -8,6 +8,8 @@
+ #include <cxlmem.h>
+ #include "core.h"
++static DECLARE_RWSEM(cxl_memdev_rwsem);
++
+ /*
+  * An entire PCI topology full of devices should be enough for any
+  * config
+@@ -132,16 +134,21 @@ static const struct device_type cxl_memdev_type = {
+       .groups = cxl_memdev_attribute_groups,
+ };
++static void cxl_memdev_shutdown(struct device *dev)
++{
++      struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
++
++      down_write(&cxl_memdev_rwsem);
++      cxlmd->cxlm = NULL;
++      up_write(&cxl_memdev_rwsem);
++}
++
+ static void cxl_memdev_unregister(void *_cxlmd)
+ {
+       struct cxl_memdev *cxlmd = _cxlmd;
+       struct device *dev = &cxlmd->dev;
+-      struct cdev *cdev = &cxlmd->cdev;
+-      const struct cdevm_file_operations *cdevm_fops;
+-
+-      cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops);
+-      cdevm_fops->shutdown(dev);
++      cxl_memdev_shutdown(dev);
+       cdev_device_del(&cxlmd->cdev, dev);
+       put_device(dev);
+ }
+@@ -180,16 +187,72 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm,
+       return ERR_PTR(rc);
+ }
++static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
++                             unsigned long arg)
++{
++      switch (cmd) {
++      case CXL_MEM_QUERY_COMMANDS:
++              return cxl_query_cmd(cxlmd, (void __user *)arg);
++      case CXL_MEM_SEND_COMMAND:
++              return cxl_send_cmd(cxlmd, (void __user *)arg);
++      default:
++              return -ENOTTY;
++      }
++}
++
++static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
++                           unsigned long arg)
++{
++      struct cxl_memdev *cxlmd = file->private_data;
++      int rc = -ENXIO;
++
++      down_read(&cxl_memdev_rwsem);
++      if (cxlmd->cxlm)
++              rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
++      up_read(&cxl_memdev_rwsem);
++
++      return rc;
++}
++
++static int cxl_memdev_open(struct inode *inode, struct file *file)
++{
++      struct cxl_memdev *cxlmd =
++              container_of(inode->i_cdev, typeof(*cxlmd), cdev);
++
++      get_device(&cxlmd->dev);
++      file->private_data = cxlmd;
++
++      return 0;
++}
++
++static int cxl_memdev_release_file(struct inode *inode, struct file *file)
++{
++      struct cxl_memdev *cxlmd =
++              container_of(inode->i_cdev, typeof(*cxlmd), cdev);
++
++      put_device(&cxlmd->dev);
++
++      return 0;
++}
++
++static const struct file_operations cxl_memdev_fops = {
++      .owner = THIS_MODULE,
++      .unlocked_ioctl = cxl_memdev_ioctl,
++      .open = cxl_memdev_open,
++      .release = cxl_memdev_release_file,
++      .compat_ioctl = compat_ptr_ioctl,
++      .llseek = noop_llseek,
++};
++
+ struct cxl_memdev *
+-devm_cxl_add_memdev(struct cxl_mem *cxlm,
+-                  const struct cdevm_file_operations *cdevm_fops)
++devm_cxl_add_memdev(struct cxl_mem *cxlm)
+ {
+       struct cxl_memdev *cxlmd;
+       struct device *dev;
+       struct cdev *cdev;
+       int rc;
+-      cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops);
++      cxlmd = cxl_memdev_alloc(cxlm, &cxl_memdev_fops);
+       if (IS_ERR(cxlmd))
+               return cxlmd;
+@@ -219,7 +282,7 @@ devm_cxl_add_memdev(struct cxl_mem *cxlm,
+        * The cdev was briefly live, shutdown any ioctl operations that
+        * saw that state.
+        */
+-      cdevm_fops->shutdown(dev);
++      cxl_memdev_shutdown(dev);
+       put_device(dev);
+       return ERR_PTR(rc);
+ }
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index c142532db8cb6..f5d3326a1d0b1 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -2,6 +2,7 @@
+ /* Copyright(c) 2020-2021 Intel Corporation. */
+ #ifndef __CXL_MEM_H__
+ #define __CXL_MEM_H__
++#include <uapi/linux/cxl_mem.h>
+ #include <linux/cdev.h>
+ #include "cxl.h"
+@@ -28,21 +29,6 @@
+       (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) !=                       \
+        CXLMDEV_RESET_NEEDED_NOT)
+-/**
+- * struct cdevm_file_operations - devm coordinated cdev file operations
+- * @fops: file operations that are synchronized against @shutdown
+- * @shutdown: disconnect driver data
+- *
+- * @shutdown is invoked in the devres release path to disconnect any
+- * driver instance data from @dev. It assumes synchronization with any
+- * fops operation that requires driver data. After @shutdown an
+- * operation may only reference @device data.
+- */
+-struct cdevm_file_operations {
+-      struct file_operations fops;
+-      void (*shutdown)(struct device *dev);
+-};
+-
+ /**
+  * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device
+  * @dev: driver core device object
+@@ -62,9 +48,7 @@ static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
+       return container_of(dev, struct cxl_memdev, dev);
+ }
+-struct cxl_memdev *
+-devm_cxl_add_memdev(struct cxl_mem *cxlm,
+-                  const struct cdevm_file_operations *cdevm_fops);
++struct cxl_memdev *devm_cxl_add_memdev(struct cxl_mem *cxlm);
+ /**
+  * struct cxl_mbox_cmd - A command to be submitted to hardware.
+@@ -158,4 +142,62 @@ struct cxl_mem {
+       int (*mbox_send)(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd);
+ };
++
++enum cxl_opcode {
++      CXL_MBOX_OP_INVALID             = 0x0000,
++      CXL_MBOX_OP_RAW                 = CXL_MBOX_OP_INVALID,
++      CXL_MBOX_OP_GET_FW_INFO         = 0x0200,
++      CXL_MBOX_OP_ACTIVATE_FW         = 0x0202,
++      CXL_MBOX_OP_GET_SUPPORTED_LOGS  = 0x0400,
++      CXL_MBOX_OP_GET_LOG             = 0x0401,
++      CXL_MBOX_OP_IDENTIFY            = 0x4000,
++      CXL_MBOX_OP_GET_PARTITION_INFO  = 0x4100,
++      CXL_MBOX_OP_SET_PARTITION_INFO  = 0x4101,
++      CXL_MBOX_OP_GET_LSA             = 0x4102,
++      CXL_MBOX_OP_SET_LSA             = 0x4103,
++      CXL_MBOX_OP_GET_HEALTH_INFO     = 0x4200,
++      CXL_MBOX_OP_GET_ALERT_CONFIG    = 0x4201,
++      CXL_MBOX_OP_SET_ALERT_CONFIG    = 0x4202,
++      CXL_MBOX_OP_GET_SHUTDOWN_STATE  = 0x4203,
++      CXL_MBOX_OP_SET_SHUTDOWN_STATE  = 0x4204,
++      CXL_MBOX_OP_GET_POISON          = 0x4300,
++      CXL_MBOX_OP_INJECT_POISON       = 0x4301,
++      CXL_MBOX_OP_CLEAR_POISON        = 0x4302,
++      CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303,
++      CXL_MBOX_OP_SCAN_MEDIA          = 0x4304,
++      CXL_MBOX_OP_GET_SCAN_MEDIA      = 0x4305,
++      CXL_MBOX_OP_MAX                 = 0x10000
++};
++
++/**
++ * struct cxl_mem_command - Driver representation of a memory device command
++ * @info: Command information as it exists for the UAPI
++ * @opcode: The actual bits used for the mailbox protocol
++ * @flags: Set of flags effecting driver behavior.
++ *
++ *  * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag
++ *    will be enabled by the driver regardless of what hardware may have
++ *    advertised.
++ *
++ * The cxl_mem_command is the driver's internal representation of commands that
++ * are supported by the driver. Some of these commands may not be supported by
++ * the hardware. The driver will use @info to validate the fields passed in by
++ * the user then submit the @opcode to the hardware.
++ *
++ * See struct cxl_command_info.
++ */
++struct cxl_mem_command {
++      struct cxl_command_info info;
++      enum cxl_opcode opcode;
++      u32 flags;
++#define CXL_CMD_FLAG_NONE 0
++#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
++};
++
++int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, void *in,
++                        size_t in_size, void *out, size_t out_size);
++int cxl_mem_identify(struct cxl_mem *cxlm);
++int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm);
++int cxl_mem_create_range_info(struct cxl_mem *cxlm);
++struct cxl_mem *cxl_mem_create(struct device *dev);
+ #endif /* __CXL_MEM_H__ */
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index 36b2dbf407120..f6f2d1268062a 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -1,16 +1,12 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
+-#include <uapi/linux/cxl_mem.h>
+-#include <linux/security.h>
+-#include <linux/debugfs.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/module.h>
+ #include <linux/sizes.h>
+ #include <linux/mutex.h>
+ #include <linux/list.h>
+-#include <linux/cdev.h>
+ #include <linux/pci.h>
+ #include <linux/io.h>
+-#include <linux/io-64-nonatomic-lo-hi.h>
+ #include "cxlmem.h"
+ #include "pci.h"
+ #include "cxl.h"
+@@ -37,162 +33,6 @@
+ /* CXL 2.0 - 8.2.8.4 */
+ #define CXL_MAILBOX_TIMEOUT_MS (2 * HZ)
+-enum opcode {
+-      CXL_MBOX_OP_INVALID             = 0x0000,
+-      CXL_MBOX_OP_RAW                 = CXL_MBOX_OP_INVALID,
+-      CXL_MBOX_OP_GET_FW_INFO         = 0x0200,
+-      CXL_MBOX_OP_ACTIVATE_FW         = 0x0202,
+-      CXL_MBOX_OP_GET_SUPPORTED_LOGS  = 0x0400,
+-      CXL_MBOX_OP_GET_LOG             = 0x0401,
+-      CXL_MBOX_OP_IDENTIFY            = 0x4000,
+-      CXL_MBOX_OP_GET_PARTITION_INFO  = 0x4100,
+-      CXL_MBOX_OP_SET_PARTITION_INFO  = 0x4101,
+-      CXL_MBOX_OP_GET_LSA             = 0x4102,
+-      CXL_MBOX_OP_SET_LSA             = 0x4103,
+-      CXL_MBOX_OP_GET_HEALTH_INFO     = 0x4200,
+-      CXL_MBOX_OP_GET_ALERT_CONFIG    = 0x4201,
+-      CXL_MBOX_OP_SET_ALERT_CONFIG    = 0x4202,
+-      CXL_MBOX_OP_GET_SHUTDOWN_STATE  = 0x4203,
+-      CXL_MBOX_OP_SET_SHUTDOWN_STATE  = 0x4204,
+-      CXL_MBOX_OP_GET_POISON          = 0x4300,
+-      CXL_MBOX_OP_INJECT_POISON       = 0x4301,
+-      CXL_MBOX_OP_CLEAR_POISON        = 0x4302,
+-      CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303,
+-      CXL_MBOX_OP_SCAN_MEDIA          = 0x4304,
+-      CXL_MBOX_OP_GET_SCAN_MEDIA      = 0x4305,
+-      CXL_MBOX_OP_MAX                 = 0x10000
+-};
+-
+-static DECLARE_RWSEM(cxl_memdev_rwsem);
+-static struct dentry *cxl_debugfs;
+-static bool cxl_raw_allow_all;
+-
+-enum {
+-      CEL_UUID,
+-      VENDOR_DEBUG_UUID,
+-};
+-
+-/* See CXL 2.0 Table 170. Get Log Input Payload */
+-static const uuid_t log_uuid[] = {
+-      [CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96,
+-                             0xb1, 0x62, 0x3b, 0x3f, 0x17),
+-      [VENDOR_DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f,
+-                                      0xd6, 0x07, 0x19, 0x40, 0x3d, 0x86),
+-};
+-
+-/**
+- * struct cxl_mem_command - Driver representation of a memory device command
+- * @info: Command information as it exists for the UAPI
+- * @opcode: The actual bits used for the mailbox protocol
+- * @flags: Set of flags effecting driver behavior.
+- *
+- *  * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag
+- *    will be enabled by the driver regardless of what hardware may have
+- *    advertised.
+- *
+- * The cxl_mem_command is the driver's internal representation of commands that
+- * are supported by the driver. Some of these commands may not be supported by
+- * the hardware. The driver will use @info to validate the fields passed in by
+- * the user then submit the @opcode to the hardware.
+- *
+- * See struct cxl_command_info.
+- */
+-struct cxl_mem_command {
+-      struct cxl_command_info info;
+-      enum opcode opcode;
+-      u32 flags;
+-#define CXL_CMD_FLAG_NONE 0
+-#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0)
+-};
+-
+-#define CXL_CMD(_id, sin, sout, _flags)                                        \
+-      [CXL_MEM_COMMAND_ID_##_id] = {                                         \
+-      .info = {                                                              \
+-                      .id = CXL_MEM_COMMAND_ID_##_id,                        \
+-                      .size_in = sin,                                        \
+-                      .size_out = sout,                                      \
+-              },                                                             \
+-      .opcode = CXL_MBOX_OP_##_id,                                           \
+-      .flags = _flags,                                                       \
+-      }
+-
+-/*
+- * This table defines the supported mailbox commands for the driver. This table
+- * is made up of a UAPI structure. Non-negative values as parameters in the
+- * table will be validated against the user's input. For example, if size_in is
+- * 0, and the user passed in 1, it is an error.
+- */
+-static struct cxl_mem_command mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
+-      CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
+-#ifdef CONFIG_CXL_MEM_RAW_COMMANDS
+-      CXL_CMD(RAW, ~0, ~0, 0),
+-#endif
+-      CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
+-      CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
+-      CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
+-      CXL_CMD(GET_LSA, 0x8, ~0, 0),
+-      CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
+-      CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
+-      CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0),
+-      CXL_CMD(SET_LSA, ~0, 0, 0),
+-      CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0),
+-      CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0),
+-      CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0),
+-      CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0),
+-      CXL_CMD(GET_POISON, 0x10, ~0, 0),
+-      CXL_CMD(INJECT_POISON, 0x8, 0, 0),
+-      CXL_CMD(CLEAR_POISON, 0x48, 0, 0),
+-      CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
+-      CXL_CMD(SCAN_MEDIA, 0x11, 0, 0),
+-      CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0),
+-};
+-
+-/*
+- * Commands that RAW doesn't permit. The rationale for each:
+- *
+- * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment /
+- * coordination of transaction timeout values at the root bridge level.
+- *
+- * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live
+- * and needs to be coordinated with HDM updates.
+- *
+- * CXL_MBOX_OP_SET_LSA: The label storage area may be cached by the
+- * driver and any writes from userspace invalidates those contents.
+- *
+- * CXL_MBOX_OP_SET_SHUTDOWN_STATE: Set shutdown state assumes no writes
+- * to the device after it is marked clean, userspace can not make that
+- * assertion.
+- *
+- * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that
+- * is kept up to date with patrol notifications and error management.
+- */
+-static u16 cxl_disabled_raw_commands[] = {
+-      CXL_MBOX_OP_ACTIVATE_FW,
+-      CXL_MBOX_OP_SET_PARTITION_INFO,
+-      CXL_MBOX_OP_SET_LSA,
+-      CXL_MBOX_OP_SET_SHUTDOWN_STATE,
+-      CXL_MBOX_OP_SCAN_MEDIA,
+-      CXL_MBOX_OP_GET_SCAN_MEDIA,
+-};
+-
+-/*
+- * Command sets that RAW doesn't permit. All opcodes in this set are
+- * disabled because they pass plain text security payloads over the
+- * user/kernel boundary. This functionality is intended to be wrapped
+- * behind the keys ABI which allows for encrypted payloads in the UAPI
+- */
+-static u8 security_command_sets[] = {
+-      0x44, /* Sanitize */
+-      0x45, /* Persistent Memory Data-at-rest Security */
+-      0x46, /* Security Passthrough */
+-};
+-
+-#define cxl_for_each_cmd(cmd)                                                  \
+-      for ((cmd) = &mem_commands[0];                                         \
+-           ((cmd) - mem_commands) < ARRAY_SIZE(mem_commands); (cmd)++)
+-
+-#define cxl_cmd_count ARRAY_SIZE(mem_commands)
+-
+ static int cxl_mem_wait_for_doorbell(struct cxl_mem *cxlm)
+ {
+       const unsigned long start = jiffies;
+@@ -215,16 +55,6 @@ static int cxl_mem_wait_for_doorbell(struct cxl_mem *cxlm)
+       return 0;
+ }
+-static bool cxl_is_security_command(u16 opcode)
+-{
+-      int i;
+-
+-      for (i = 0; i < ARRAY_SIZE(security_command_sets); i++)
+-              if (security_command_sets[i] == (opcode >> 8))
+-                      return true;
+-      return false;
+-}
+-
+ static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm,
+                                struct cxl_mbox_cmd *mbox_cmd)
+ {
+@@ -446,433 +276,6 @@ static int cxl_pci_mbox_send(struct cxl_mem *cxlm, struct cxl_mbox_cmd *cmd)
+       return rc;
+ }
+-/**
+- * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace.
+- * @cxlm: The CXL memory device to communicate with.
+- * @cmd: The validated command.
+- * @in_payload: Pointer to userspace's input payload.
+- * @out_payload: Pointer to userspace's output payload.
+- * @size_out: (Input) Max payload size to copy out.
+- *            (Output) Payload size hardware generated.
+- * @retval: Hardware generated return code from the operation.
+- *
+- * Return:
+- *  * %0      - Mailbox transaction succeeded. This implies the mailbox
+- *              protocol completed successfully not that the operation itself
+- *              was successful.
+- *  * %-ENOMEM  - Couldn't allocate a bounce buffer.
+- *  * %-EFAULT        - Something happened with copy_to/from_user.
+- *  * %-EINTR - Mailbox acquisition interrupted.
+- *  * %-EXXX  - Transaction level failures.
+- *
+- * Creates the appropriate mailbox command and dispatches it on behalf of a
+- * userspace request. The input and output payloads are copied between
+- * userspace.
+- *
+- * See cxl_send_cmd().
+- */
+-static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
+-                                      const struct cxl_mem_command *cmd,
+-                                      u64 in_payload, u64 out_payload,
+-                                      s32 *size_out, u32 *retval)
+-{
+-      struct device *dev = cxlm->dev;
+-      struct cxl_mbox_cmd mbox_cmd = {
+-              .opcode = cmd->opcode,
+-              .size_in = cmd->info.size_in,
+-              .size_out = cmd->info.size_out,
+-      };
+-      int rc;
+-
+-      if (cmd->info.size_out) {
+-              mbox_cmd.payload_out = kvzalloc(cmd->info.size_out, GFP_KERNEL);
+-              if (!mbox_cmd.payload_out)
+-                      return -ENOMEM;
+-      }
+-
+-      if (cmd->info.size_in) {
+-              mbox_cmd.payload_in = vmemdup_user(u64_to_user_ptr(in_payload),
+-                                                 cmd->info.size_in);
+-              if (IS_ERR(mbox_cmd.payload_in)) {
+-                      kvfree(mbox_cmd.payload_out);
+-                      return PTR_ERR(mbox_cmd.payload_in);
+-              }
+-      }
+-
+-      dev_dbg(dev,
+-              "Submitting %s command for user\n"
+-              "\topcode: %x\n"
+-              "\tsize: %ub\n",
+-              cxl_command_names[cmd->info.id].name, mbox_cmd.opcode,
+-              cmd->info.size_in);
+-
+-      dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW,
+-                    "raw command path used\n");
+-
+-      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
+-      if (rc)
+-              goto out;
+-
+-      /*
+-       * @size_out contains the max size that's allowed to be written back out
+-       * to userspace. While the payload may have written more output than
+-       * this it will have to be ignored.
+-       */
+-      if (mbox_cmd.size_out) {
+-              dev_WARN_ONCE(dev, mbox_cmd.size_out > *size_out,
+-                            "Invalid return size\n");
+-              if (copy_to_user(u64_to_user_ptr(out_payload),
+-                               mbox_cmd.payload_out, mbox_cmd.size_out)) {
+-                      rc = -EFAULT;
+-                      goto out;
+-              }
+-      }
+-
+-      *size_out = mbox_cmd.size_out;
+-      *retval = mbox_cmd.return_code;
+-
+-out:
+-      kvfree(mbox_cmd.payload_in);
+-      kvfree(mbox_cmd.payload_out);
+-      return rc;
+-}
+-
+-static bool cxl_mem_raw_command_allowed(u16 opcode)
+-{
+-      int i;
+-
+-      if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS))
+-              return false;
+-
+-      if (security_locked_down(LOCKDOWN_PCI_ACCESS))
+-              return false;
+-
+-      if (cxl_raw_allow_all)
+-              return true;
+-
+-      if (cxl_is_security_command(opcode))
+-              return false;
+-
+-      for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++)
+-              if (cxl_disabled_raw_commands[i] == opcode)
+-                      return false;
+-
+-      return true;
+-}
+-
+-/**
+- * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND.
+- * @cxlm: &struct cxl_mem device whose mailbox will be used.
+- * @send_cmd: &struct cxl_send_command copied in from userspace.
+- * @out_cmd: Sanitized and populated &struct cxl_mem_command.
+- *
+- * Return:
+- *  * %0      - @out_cmd is ready to send.
+- *  * %-ENOTTY        - Invalid command specified.
+- *  * %-EINVAL        - Reserved fields or invalid values were used.
+- *  * %-ENOMEM        - Input or output buffer wasn't sized properly.
+- *  * %-EPERM - Attempted to use a protected command.
+- *
+- * The result of this command is a fully validated command in @out_cmd that is
+- * safe to send to the hardware.
+- *
+- * See handle_mailbox_cmd_from_user()
+- */
+-static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm,
+-                                    const struct cxl_send_command *send_cmd,
+-                                    struct cxl_mem_command *out_cmd)
+-{
+-      const struct cxl_command_info *info;
+-      struct cxl_mem_command *c;
+-
+-      if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX)
+-              return -ENOTTY;
+-
+-      /*
+-       * The user can never specify an input payload larger than what hardware
+-       * supports, but output can be arbitrarily large (simply write out as
+-       * much data as the hardware provides).
+-       */
+-      if (send_cmd->in.size > cxlm->payload_size)
+-              return -EINVAL;
+-
+-      /*
+-       * Checks are bypassed for raw commands but a WARN/taint will occur
+-       * later in the callchain
+-       */
+-      if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) {
+-              const struct cxl_mem_command temp = {
+-                      .info = {
+-                              .id = CXL_MEM_COMMAND_ID_RAW,
+-                              .flags = 0,
+-                              .size_in = send_cmd->in.size,
+-                              .size_out = send_cmd->out.size,
+-                      },
+-                      .opcode = send_cmd->raw.opcode
+-              };
+-
+-              if (send_cmd->raw.rsvd)
+-                      return -EINVAL;
+-
+-              /*
+-               * Unlike supported commands, the output size of RAW commands
+-               * gets passed along without further checking, so it must be
+-               * validated here.
+-               */
+-              if (send_cmd->out.size > cxlm->payload_size)
+-                      return -EINVAL;
+-
+-              if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode))
+-                      return -EPERM;
+-
+-              memcpy(out_cmd, &temp, sizeof(temp));
+-
+-              return 0;
+-      }
+-
+-      if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK)
+-              return -EINVAL;
+-
+-      if (send_cmd->rsvd)
+-              return -EINVAL;
+-
+-      if (send_cmd->in.rsvd || send_cmd->out.rsvd)
+-              return -EINVAL;
+-
+-      /* Convert user's command into the internal representation */
+-      c = &mem_commands[send_cmd->id];
+-      info = &c->info;
+-
+-      /* Check that the command is enabled for hardware */
+-      if (!test_bit(info->id, cxlm->enabled_cmds))
+-              return -ENOTTY;
+-
+-      /* Check the input buffer is the expected size */
+-      if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
+-              return -ENOMEM;
+-
+-      /* Check the output buffer is at least large enough */
+-      if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
+-              return -ENOMEM;
+-
+-      memcpy(out_cmd, c, sizeof(*c));
+-      out_cmd->info.size_in = send_cmd->in.size;
+-      /*
+-       * XXX: out_cmd->info.size_out will be controlled by the driver, and the
+-       * specified number of bytes @send_cmd->out.size will be copied back out
+-       * to userspace.
+-       */
+-
+-      return 0;
+-}
+-
+-static int cxl_query_cmd(struct cxl_memdev *cxlmd,
+-                       struct cxl_mem_query_commands __user *q)
+-{
+-      struct device *dev = &cxlmd->dev;
+-      struct cxl_mem_command *cmd;
+-      u32 n_commands;
+-      int j = 0;
+-
+-      dev_dbg(dev, "Query IOCTL\n");
+-
+-      if (get_user(n_commands, &q->n_commands))
+-              return -EFAULT;
+-
+-      /* returns the total number if 0 elements are requested. */
+-      if (n_commands == 0)
+-              return put_user(cxl_cmd_count, &q->n_commands);
+-
+-      /*
+-       * otherwise, return max(n_commands, total commands) cxl_command_info
+-       * structures.
+-       */
+-      cxl_for_each_cmd(cmd) {
+-              const struct cxl_command_info *info = &cmd->info;
+-
+-              if (copy_to_user(&q->commands[j++], info, sizeof(*info)))
+-                      return -EFAULT;
+-
+-              if (j == n_commands)
+-                      break;
+-      }
+-
+-      return 0;
+-}
+-
+-static int cxl_send_cmd(struct cxl_memdev *cxlmd,
+-                      struct cxl_send_command __user *s)
+-{
+-      struct cxl_mem *cxlm = cxlmd->cxlm;
+-      struct device *dev = &cxlmd->dev;
+-      struct cxl_send_command send;
+-      struct cxl_mem_command c;
+-      int rc;
+-
+-      dev_dbg(dev, "Send IOCTL\n");
+-
+-      if (copy_from_user(&send, s, sizeof(send)))
+-              return -EFAULT;
+-
+-      rc = cxl_validate_cmd_from_user(cxlmd->cxlm, &send, &c);
+-      if (rc)
+-              return rc;
+-
+-      /* Prepare to handle a full payload for variable sized output */
+-      if (c.info.size_out < 0)
+-              c.info.size_out = cxlm->payload_size;
+-
+-      rc = handle_mailbox_cmd_from_user(cxlm, &c, send.in.payload,
+-                                        send.out.payload, &send.out.size,
+-                                        &send.retval);
+-      if (rc)
+-              return rc;
+-
+-      if (copy_to_user(s, &send, sizeof(send)))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd,
+-                             unsigned long arg)
+-{
+-      switch (cmd) {
+-      case CXL_MEM_QUERY_COMMANDS:
+-              return cxl_query_cmd(cxlmd, (void __user *)arg);
+-      case CXL_MEM_SEND_COMMAND:
+-              return cxl_send_cmd(cxlmd, (void __user *)arg);
+-      default:
+-              return -ENOTTY;
+-      }
+-}
+-
+-static long cxl_memdev_ioctl(struct file *file, unsigned int cmd,
+-                           unsigned long arg)
+-{
+-      struct cxl_memdev *cxlmd = file->private_data;
+-      int rc = -ENXIO;
+-
+-      down_read(&cxl_memdev_rwsem);
+-      if (cxlmd->cxlm)
+-              rc = __cxl_memdev_ioctl(cxlmd, cmd, arg);
+-      up_read(&cxl_memdev_rwsem);
+-
+-      return rc;
+-}
+-
+-static int cxl_memdev_open(struct inode *inode, struct file *file)
+-{
+-      struct cxl_memdev *cxlmd =
+-              container_of(inode->i_cdev, typeof(*cxlmd), cdev);
+-
+-      get_device(&cxlmd->dev);
+-      file->private_data = cxlmd;
+-
+-      return 0;
+-}
+-
+-static int cxl_memdev_release_file(struct inode *inode, struct file *file)
+-{
+-      struct cxl_memdev *cxlmd =
+-              container_of(inode->i_cdev, typeof(*cxlmd), cdev);
+-
+-      put_device(&cxlmd->dev);
+-
+-      return 0;
+-}
+-
+-static void cxl_memdev_shutdown(struct device *dev)
+-{
+-      struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+-
+-      down_write(&cxl_memdev_rwsem);
+-      cxlmd->cxlm = NULL;
+-      up_write(&cxl_memdev_rwsem);
+-}
+-
+-static const struct cdevm_file_operations cxl_memdev_fops = {
+-      .fops = {
+-              .owner = THIS_MODULE,
+-              .unlocked_ioctl = cxl_memdev_ioctl,
+-              .open = cxl_memdev_open,
+-              .release = cxl_memdev_release_file,
+-              .compat_ioctl = compat_ptr_ioctl,
+-              .llseek = noop_llseek,
+-      },
+-      .shutdown = cxl_memdev_shutdown,
+-};
+-
+-static inline struct cxl_mem_command *cxl_mem_find_command(u16 opcode)
+-{
+-      struct cxl_mem_command *c;
+-
+-      cxl_for_each_cmd(c)
+-              if (c->opcode == opcode)
+-                      return c;
+-
+-      return NULL;
+-}
+-
+-/**
+- * cxl_mem_mbox_send_cmd() - Send a mailbox command to a memory device.
+- * @cxlm: The CXL memory device to communicate with.
+- * @opcode: Opcode for the mailbox command.
+- * @in: The input payload for the mailbox command.
+- * @in_size: The length of the input payload
+- * @out: Caller allocated buffer for the output.
+- * @out_size: Expected size of output.
+- *
+- * Context: Any context. Will acquire and release mbox_mutex.
+- * Return:
+- *  * %>=0    - Number of bytes returned in @out.
+- *  * %-E2BIG - Payload is too large for hardware.
+- *  * %-EBUSY - Couldn't acquire exclusive mailbox access.
+- *  * %-EFAULT        - Hardware error occurred.
+- *  * %-ENXIO - Command completed, but device reported an error.
+- *  * %-EIO   - Unexpected output size.
+- *
+- * Mailbox commands may execute successfully yet the device itself reported an
+- * error. While this distinction can be useful for commands from userspace, the
+- * kernel will only be able to use results when both are successful.
+- *
+- * See __cxl_mem_mbox_send_cmd()
+- */
+-static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode,
+-                               void *in, size_t in_size,
+-                               void *out, size_t out_size)
+-{
+-      const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
+-      struct cxl_mbox_cmd mbox_cmd = {
+-              .opcode = opcode,
+-              .payload_in = in,
+-              .size_in = in_size,
+-              .size_out = out_size,
+-              .payload_out = out,
+-      };
+-      int rc;
+-
+-      if (out_size > cxlm->payload_size)
+-              return -E2BIG;
+-
+-      rc = cxlm->mbox_send(cxlm, &mbox_cmd);
+-      if (rc)
+-              return rc;
+-
+-      /* TODO: Map return code to proper kernel style errno */
+-      if (mbox_cmd.return_code != CXL_MBOX_SUCCESS)
+-              return -ENXIO;
+-
+-      /*
+-       * Variable sized commands can't be validated and so it's up to the
+-       * caller to do that if they wish.
+-       */
+-      if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size)
+-              return -EIO;
+-
+-      return 0;
+-}
+-
+ static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm)
+ {
+       const int cap = readl(cxlm->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET);
+@@ -901,30 +304,6 @@ static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm)
+       return 0;
+ }
+-static struct cxl_mem *cxl_mem_create(struct device *dev)
+-{
+-      struct cxl_mem *cxlm;
+-
+-      cxlm = devm_kzalloc(dev, sizeof(*cxlm), GFP_KERNEL);
+-      if (!cxlm) {
+-              dev_err(dev, "No memory available\n");
+-              return ERR_PTR(-ENOMEM);
+-      }
+-
+-      mutex_init(&cxlm->mbox_mutex);
+-      cxlm->dev = dev;
+-      cxlm->enabled_cmds =
+-              devm_kmalloc_array(dev, BITS_TO_LONGS(cxl_cmd_count),
+-                                 sizeof(unsigned long),
+-                                 GFP_KERNEL | __GFP_ZERO);
+-      if (!cxlm->enabled_cmds) {
+-              dev_err(dev, "No memory available for bitmap\n");
+-              return ERR_PTR(-ENOMEM);
+-      }
+-
+-      return cxlm;
+-}
+-
+ static void __iomem *cxl_mem_map_regblock(struct cxl_mem *cxlm,
+                                         u8 bar, u64 offset)
+ {
+@@ -1132,298 +511,6 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
+       return ret;
+ }
+-static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out)
+-{
+-      u32 remaining = size;
+-      u32 offset = 0;
+-
+-      while (remaining) {
+-              u32 xfer_size = min_t(u32, remaining, cxlm->payload_size);
+-              struct cxl_mbox_get_log {
+-                      uuid_t uuid;
+-                      __le32 offset;
+-                      __le32 length;
+-              } __packed log = {
+-                      .uuid = *uuid,
+-                      .offset = cpu_to_le32(offset),
+-                      .length = cpu_to_le32(xfer_size)
+-              };
+-              int rc;
+-
+-              rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_LOG, &log,
+-                                         sizeof(log), out, xfer_size);
+-              if (rc < 0)
+-                      return rc;
+-
+-              out += xfer_size;
+-              remaining -= xfer_size;
+-              offset += xfer_size;
+-      }
+-
+-      return 0;
+-}
+-
+-/**
+- * cxl_walk_cel() - Walk through the Command Effects Log.
+- * @cxlm: Device.
+- * @size: Length of the Command Effects Log.
+- * @cel: CEL
+- *
+- * Iterate over each entry in the CEL and determine if the driver supports the
+- * command. If so, the command is enabled for the device and can be used later.
+- */
+-static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel)
+-{
+-      struct cel_entry {
+-              __le16 opcode;
+-              __le16 effect;
+-      } __packed * cel_entry;
+-      const int cel_entries = size / sizeof(*cel_entry);
+-      int i;
+-
+-      cel_entry = (struct cel_entry *)cel;
+-
+-      for (i = 0; i < cel_entries; i++) {
+-              u16 opcode = le16_to_cpu(cel_entry[i].opcode);
+-              struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
+-
+-              if (!cmd) {
+-                      dev_dbg(cxlm->dev,
+-                              "Opcode 0x%04x unsupported by driver", opcode);
+-                      continue;
+-              }
+-
+-              set_bit(cmd->info.id, cxlm->enabled_cmds);
+-      }
+-}
+-
+-struct cxl_mbox_get_supported_logs {
+-      __le16 entries;
+-      u8 rsvd[6];
+-      struct gsl_entry {
+-              uuid_t uuid;
+-              __le32 size;
+-      } __packed entry[];
+-} __packed;
+-
+-static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
+-{
+-      struct cxl_mbox_get_supported_logs *ret;
+-      int rc;
+-
+-      ret = kvmalloc(cxlm->payload_size, GFP_KERNEL);
+-      if (!ret)
+-              return ERR_PTR(-ENOMEM);
+-
+-      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_SUPPORTED_LOGS, NULL,
+-                                 0, ret, cxlm->payload_size);
+-      if (rc < 0) {
+-              kvfree(ret);
+-              return ERR_PTR(rc);
+-      }
+-
+-      return ret;
+-}
+-
+-/**
+- * cxl_mem_get_partition_info - Get partition info
+- * @cxlm: cxl_mem instance to update partition info
+- *
+- * Retrieve the current partition info for the device specified.  If not 0, the
+- * 'next' values are pending and take affect on next cold reset.
+- *
+- * Return: 0 if no error: or the result of the mailbox command.
+- *
+- * See CXL @8.2.9.5.2.1 Get Partition Info
+- */
+-static int cxl_mem_get_partition_info(struct cxl_mem *cxlm)
+-{
+-      struct cxl_mbox_get_partition_info {
+-              __le64 active_volatile_cap;
+-              __le64 active_persistent_cap;
+-              __le64 next_volatile_cap;
+-              __le64 next_persistent_cap;
+-      } __packed pi;
+-      int rc;
+-
+-      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO,
+-                                 NULL, 0, &pi, sizeof(pi));
+-      if (rc)
+-              return rc;
+-
+-      cxlm->active_volatile_bytes =
+-              le64_to_cpu(pi.active_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
+-      cxlm->active_persistent_bytes =
+-              le64_to_cpu(pi.active_persistent_cap) * CXL_CAPACITY_MULTIPLIER;
+-      cxlm->next_volatile_bytes =
+-              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
+-      cxlm->next_persistent_bytes =
+-              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
+-
+-      return 0;
+-}
+-
+-/**
+- * cxl_mem_enumerate_cmds() - Enumerate commands for a device.
+- * @cxlm: The device.
+- *
+- * Returns 0 if enumerate completed successfully.
+- *
+- * CXL devices have optional support for certain commands. This function will
+- * determine the set of supported commands for the hardware and update the
+- * enabled_cmds bitmap in the @cxlm.
+- */
+-static int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm)
+-{
+-      struct cxl_mbox_get_supported_logs *gsl;
+-      struct device *dev = cxlm->dev;
+-      struct cxl_mem_command *cmd;
+-      int i, rc;
+-
+-      gsl = cxl_get_gsl(cxlm);
+-      if (IS_ERR(gsl))
+-              return PTR_ERR(gsl);
+-
+-      rc = -ENOENT;
+-      for (i = 0; i < le16_to_cpu(gsl->entries); i++) {
+-              u32 size = le32_to_cpu(gsl->entry[i].size);
+-              uuid_t uuid = gsl->entry[i].uuid;
+-              u8 *log;
+-
+-              dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size);
+-
+-              if (!uuid_equal(&uuid, &log_uuid[CEL_UUID]))
+-                      continue;
+-
+-              log = kvmalloc(size, GFP_KERNEL);
+-              if (!log) {
+-                      rc = -ENOMEM;
+-                      goto out;
+-              }
+-
+-              rc = cxl_xfer_log(cxlm, &uuid, size, log);
+-              if (rc) {
+-                      kvfree(log);
+-                      goto out;
+-              }
+-
+-              cxl_walk_cel(cxlm, size, log);
+-              kvfree(log);
+-
+-              /* In case CEL was bogus, enable some default commands. */
+-              cxl_for_each_cmd(cmd)
+-                      if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE)
+-                              set_bit(cmd->info.id, cxlm->enabled_cmds);
+-
+-              /* Found the required CEL */
+-              rc = 0;
+-      }
+-
+-out:
+-      kvfree(gsl);
+-      return rc;
+-}
+-
+-/**
+- * cxl_mem_identify() - Send the IDENTIFY command to the device.
+- * @cxlm: The device to identify.
+- *
+- * Return: 0 if identify was executed successfully.
+- *
+- * This will dispatch the identify command to the device and on success populate
+- * structures to be exported to sysfs.
+- */
+-static int cxl_mem_identify(struct cxl_mem *cxlm)
+-{
+-      /* See CXL 2.0 Table 175 Identify Memory Device Output Payload */
+-      struct cxl_mbox_identify {
+-              char fw_revision[0x10];
+-              __le64 total_capacity;
+-              __le64 volatile_capacity;
+-              __le64 persistent_capacity;
+-              __le64 partition_align;
+-              __le16 info_event_log_size;
+-              __le16 warning_event_log_size;
+-              __le16 failure_event_log_size;
+-              __le16 fatal_event_log_size;
+-              __le32 lsa_size;
+-              u8 poison_list_max_mer[3];
+-              __le16 inject_poison_limit;
+-              u8 poison_caps;
+-              u8 qos_telemetry_caps;
+-      } __packed id;
+-      int rc;
+-
+-      rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_IDENTIFY, NULL, 0, &id,
+-                                 sizeof(id));
+-      if (rc < 0)
+-              return rc;
+-
+-      cxlm->total_bytes = le64_to_cpu(id.total_capacity);
+-      cxlm->total_bytes *= CXL_CAPACITY_MULTIPLIER;
+-
+-      cxlm->volatile_only_bytes = le64_to_cpu(id.volatile_capacity);
+-      cxlm->volatile_only_bytes *= CXL_CAPACITY_MULTIPLIER;
+-
+-      cxlm->persistent_only_bytes = le64_to_cpu(id.persistent_capacity);
+-      cxlm->persistent_only_bytes *= CXL_CAPACITY_MULTIPLIER;
+-
+-      cxlm->partition_align_bytes = le64_to_cpu(id.partition_align);
+-      cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER;
+-
+-      dev_dbg(cxlm->dev,
+-              "Identify Memory Device\n"
+-              "     total_bytes = %#llx\n"
+-              "     volatile_only_bytes = %#llx\n"
+-              "     persistent_only_bytes = %#llx\n"
+-              "     partition_align_bytes = %#llx\n",
+-              cxlm->total_bytes, cxlm->volatile_only_bytes,
+-              cxlm->persistent_only_bytes, cxlm->partition_align_bytes);
+-
+-      cxlm->lsa_size = le32_to_cpu(id.lsa_size);
+-      memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
+-
+-      return 0;
+-}
+-
+-static int cxl_mem_create_range_info(struct cxl_mem *cxlm)
+-{
+-      int rc;
+-
+-      if (cxlm->partition_align_bytes == 0) {
+-              cxlm->ram_range.start = 0;
+-              cxlm->ram_range.end = cxlm->volatile_only_bytes - 1;
+-              cxlm->pmem_range.start = cxlm->volatile_only_bytes;
+-              cxlm->pmem_range.end = cxlm->volatile_only_bytes +
+-                                      cxlm->persistent_only_bytes - 1;
+-              return 0;
+-      }
+-
+-      rc = cxl_mem_get_partition_info(cxlm);
+-      if (rc < 0) {
+-              dev_err(cxlm->dev, "Failed to query partition information\n");
+-              return rc;
+-      }
+-
+-      dev_dbg(cxlm->dev,
+-              "Get Partition Info\n"
+-              "     active_volatile_bytes = %#llx\n"
+-              "     active_persistent_bytes = %#llx\n"
+-              "     next_volatile_bytes = %#llx\n"
+-              "     next_persistent_bytes = %#llx\n",
+-              cxlm->active_volatile_bytes, cxlm->active_persistent_bytes,
+-              cxlm->next_volatile_bytes, cxlm->next_persistent_bytes);
+-
+-      cxlm->ram_range.start = 0;
+-      cxlm->ram_range.end = cxlm->active_volatile_bytes - 1;
+-
+-      cxlm->pmem_range.start = cxlm->active_volatile_bytes;
+-      cxlm->pmem_range.end = cxlm->active_volatile_bytes +
+-                              cxlm->active_persistent_bytes - 1;
+-
+-      return 0;
+-}
+-
+ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+       struct cxl_memdev *cxlmd;
+@@ -1458,7 +545,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (rc)
+               return rc;
+-      cxlmd = devm_cxl_add_memdev(cxlm, &cxl_memdev_fops);
++      cxlmd = devm_cxl_add_memdev(cxlm);
+       if (IS_ERR(cxlmd))
+               return PTR_ERR(cxlmd);
+@@ -1486,7 +573,6 @@ static struct pci_driver cxl_mem_driver = {
+ static __init int cxl_mem_init(void)
+ {
+-      struct dentry *mbox_debugfs;
+       int rc;
+       /* Double check the anonymous union trickery in struct cxl_regs */
+@@ -1497,17 +583,11 @@ static __init int cxl_mem_init(void)
+       if (rc)
+               return rc;
+-      cxl_debugfs = debugfs_create_dir("cxl", NULL);
+-      mbox_debugfs = debugfs_create_dir("mbox", cxl_debugfs);
+-      debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs,
+-                          &cxl_raw_allow_all);
+-
+       return 0;
+ }
+ static __exit void cxl_mem_exit(void)
+ {
+-      debugfs_remove_recursive(cxl_debugfs);
+       pci_unregister_driver(&cxl_mem_driver);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-mem-fix-shutdown-order.patch b/queue-5.15/cxl-mem-fix-shutdown-order.patch
new file mode 100644 (file)
index 0000000..5b54673
--- /dev/null
@@ -0,0 +1,84 @@
+From 4cb065db9dcd2f5640134546185d56f521b9567a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 18:02:07 -0700
+Subject: cxl/mem: Fix shutdown order
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 88d3917f82ed4215a2154432c26de1480a61b209 ]
+
+Ira reports that removing cxl_mock_mem causes a crash with the following
+trace:
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000044
+ [..]
+ RIP: 0010:cxl_region_decode_reset+0x7f/0x180 [cxl_core]
+ [..]
+ Call Trace:
+  <TASK>
+  cxl_region_detach+0xe8/0x210 [cxl_core]
+  cxl_decoder_kill_region+0x27/0x40 [cxl_core]
+  cxld_unregister+0x29/0x40 [cxl_core]
+  devres_release_all+0xb8/0x110
+  device_unbind_cleanup+0xe/0x70
+  device_release_driver_internal+0x1d2/0x210
+  bus_remove_device+0xd7/0x150
+  device_del+0x155/0x3e0
+  device_unregister+0x13/0x60
+  devm_release_action+0x4d/0x90
+  ? __pfx_unregister_port+0x10/0x10 [cxl_core]
+  delete_endpoint+0x121/0x130 [cxl_core]
+  devres_release_all+0xb8/0x110
+  device_unbind_cleanup+0xe/0x70
+  device_release_driver_internal+0x1d2/0x210
+  bus_remove_device+0xd7/0x150
+  device_del+0x155/0x3e0
+  ? lock_release+0x142/0x290
+  cdev_device_del+0x15/0x50
+  cxl_memdev_unregister+0x54/0x70 [cxl_core]
+
+This crash is due to the clearing out the cxl_memdev's driver context
+(@cxlds) before the subsystem is done with it. This is ultimately due to
+the region(s), that this memdev is a member, being torn down and expecting
+to be able to de-reference @cxlds, like here:
+
+static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+...
+                if (cxlds->rcd)
+                        goto endpoint_reset;
+...
+
+Fix it by keeping the driver context valid until memdev-device
+unregistration, and subsequently the entire stack of related
+dependencies, unwinds.
+
+Fixes: 9cc238c7a526 ("cxl/pci: Introduce cdevm_file_operations")
+Reported-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Tested-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/memdev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
+index df2ba87238c29..235758d23ee02 100644
+--- a/drivers/cxl/core/memdev.c
++++ b/drivers/cxl/core/memdev.c
+@@ -148,8 +148,8 @@ static void cxl_memdev_unregister(void *_cxlmd)
+       struct cxl_memdev *cxlmd = _cxlmd;
+       struct device *dev = &cxlmd->dev;
+-      cxl_memdev_shutdown(dev);
+       cdev_device_del(&cxlmd->cdev, dev);
++      cxl_memdev_shutdown(dev);
+       put_device(dev);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-pci-clean-up-cxl_mem_get_partition_info.patch b/queue-5.15/cxl-pci-clean-up-cxl_mem_get_partition_info.patch
new file mode 100644 (file)
index 0000000..5e4d473
--- /dev/null
@@ -0,0 +1,136 @@
+From 2aa7660aae4c8173c4527cb49fa9dcc9d81e01cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Sep 2021 15:24:32 -0700
+Subject: cxl/pci: Clean up cxl_mem_get_partition_info()
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 13e7749d06b335774bbb341c65a0232484beb457 ]
+
+Commit 0b9159d0ff21 ("cxl/pci: Store memory capacity values") missed
+updating the kernel-doc for 'struct cxl_mem' leading to the following
+warnings:
+
+./scripts/kernel-doc -v drivers/cxl/cxlmem.h 2>&1 | grep warn
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'total_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'volatile_only_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'persistent_only_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'partition_align_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'active_volatile_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'active_persistent_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'next_volatile_bytes' not described in 'cxl_mem'
+drivers/cxl/cxlmem.h:107: warning: Function parameter or member 'next_persistent_bytes' not described in 'cxl_mem'
+
+Also, it is redundant to describe those same parameters in the
+kernel-doc for cxl_mem_get_partition_info(). Given the only user of that
+routine updates the values in @cxlm, just do that implicitly internal to
+the helper.
+
+Cc: Ira Weiny <ira.weiny@intel.com>
+Reported-by: Ben Widawsky <ben.widawsky@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/163157174216.2653013.1277706528753990974.stgit@dwillia2-desk3.amr.corp.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 88d3917f82ed ("cxl/mem: Fix shutdown order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/cxlmem.h | 15 +++++++++++++--
+ drivers/cxl/pci.c    | 35 +++++++++++------------------------
+ 2 files changed, 24 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index d5334df83fb25..e14bcd7a1ba14 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -78,8 +78,19 @@ devm_cxl_add_memdev(struct cxl_mem *cxlm,
+  * @mbox_mutex: Mutex to synchronize mailbox access.
+  * @firmware_version: Firmware version for the memory device.
+  * @enabled_cmds: Hardware commands found enabled in CEL.
+- * @pmem_range: Persistent memory capacity information.
+- * @ram_range: Volatile memory capacity information.
++ * @pmem_range: Active Persistent memory capacity configuration
++ * @ram_range: Active Volatile memory capacity configuration
++ * @total_bytes: sum of all possible capacities
++ * @volatile_only_bytes: hard volatile capacity
++ * @persistent_only_bytes: hard persistent capacity
++ * @partition_align_bytes: alignment size for partition-able capacity
++ * @active_volatile_bytes: sum of hard + soft volatile
++ * @active_persistent_bytes: sum of hard + soft persistent
++ * @next_volatile_bytes: volatile capacity change pending device reset
++ * @next_persistent_bytes: persistent capacity change pending device reset
++ *
++ * See section 8.2.9.5.2 Capacity Configuration and Label Storage for
++ * details on capacity parameters.
+  */
+ struct cxl_mem {
+       struct device *dev;
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index 7b8ff6e592c46..a242bcd950800 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -1262,11 +1262,7 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
+ /**
+  * cxl_mem_get_partition_info - Get partition info
+- * @cxlm: The device to act on
+- * @active_volatile_bytes: returned active volatile capacity
+- * @active_persistent_bytes: returned active persistent capacity
+- * @next_volatile_bytes: return next volatile capacity
+- * @next_persistent_bytes: return next persistent capacity
++ * @cxlm: cxl_mem instance to update partition info
+  *
+  * Retrieve the current partition info for the device specified.  If not 0, the
+  * 'next' values are pending and take affect on next cold reset.
+@@ -1275,11 +1271,7 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm)
+  *
+  * See CXL @8.2.9.5.2.1 Get Partition Info
+  */
+-static int cxl_mem_get_partition_info(struct cxl_mem *cxlm,
+-                                    u64 *active_volatile_bytes,
+-                                    u64 *active_persistent_bytes,
+-                                    u64 *next_volatile_bytes,
+-                                    u64 *next_persistent_bytes)
++static int cxl_mem_get_partition_info(struct cxl_mem *cxlm)
+ {
+       struct cxl_mbox_get_partition_info {
+               __le64 active_volatile_cap;
+@@ -1294,15 +1286,14 @@ static int cxl_mem_get_partition_info(struct cxl_mem *cxlm,
+       if (rc)
+               return rc;
+-      *active_volatile_bytes = le64_to_cpu(pi.active_volatile_cap);
+-      *active_persistent_bytes = le64_to_cpu(pi.active_persistent_cap);
+-      *next_volatile_bytes = le64_to_cpu(pi.next_volatile_cap);
+-      *next_persistent_bytes = le64_to_cpu(pi.next_volatile_cap);
+-
+-      *active_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
+-      *active_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
+-      *next_volatile_bytes *= CXL_CAPACITY_MULTIPLIER;
+-      *next_persistent_bytes *= CXL_CAPACITY_MULTIPLIER;
++      cxlm->active_volatile_bytes =
++              le64_to_cpu(pi.active_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->active_persistent_bytes =
++              le64_to_cpu(pi.active_persistent_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->next_volatile_bytes =
++              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
++      cxlm->next_persistent_bytes =
++              le64_to_cpu(pi.next_volatile_cap) * CXL_CAPACITY_MULTIPLIER;
+       return 0;
+ }
+@@ -1443,11 +1434,7 @@ static int cxl_mem_create_range_info(struct cxl_mem *cxlm)
+               return 0;
+       }
+-      rc = cxl_mem_get_partition_info(cxlm,
+-                                      &cxlm->active_volatile_bytes,
+-                                      &cxlm->active_persistent_bytes,
+-                                      &cxlm->next_volatile_bytes,
+-                                      &cxlm->next_persistent_bytes);
++      rc = cxl_mem_get_partition_info(cxlm);
+       if (rc < 0) {
+               dev_err(cxlm->dev, "Failed to query partition information\n");
+               return rc;
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-pci-drop-idr.h.patch b/queue-5.15/cxl-pci-drop-idr.h.patch
new file mode 100644 (file)
index 0000000..34aee16
--- /dev/null
@@ -0,0 +1,39 @@
+From 450f15a5d86562de77ca4dc7fd882f5f0067d251 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 22:12:26 -0700
+Subject: cxl/pci: Drop idr.h
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 4cb35f1ca05a42acbc4a3c8cf7de1029a06558d0 ]
+
+Commit 3d135db51024 ("cxl/core: Move memdev management to core") left
+this straggling include for cxl_memdev setup. Clean it up.
+
+Cc: Ben Widawsky <ben.widawsky@intel.com>
+Reported-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ben Widawsky <ben.widawsky@intel.com>
+Link: https://lore.kernel.org/r/163116434668.2460985.12264757586266849616.stgit@dwillia2-desk3.amr.corp.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 88d3917f82ed ("cxl/mem: Fix shutdown order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/pci.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index e6cf607448bfe..36b2dbf407120 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -8,7 +8,6 @@
+ #include <linux/mutex.h>
+ #include <linux/list.h>
+ #include <linux/cdev.h>
+-#include <linux/idr.h>
+ #include <linux/pci.h>
+ #include <linux/io.h>
+ #include <linux/io-64-nonatomic-lo-hi.h>
+-- 
+2.42.0
+
diff --git a/queue-5.15/cxl-pci-make-struct-cxl_mem-device-type-generic.patch b/queue-5.15/cxl-pci-make-struct-cxl_mem-device-type-generic.patch
new file mode 100644 (file)
index 0000000..74b8107
--- /dev/null
@@ -0,0 +1,355 @@
+From fec63be32a3f61c396c2ba2b911db98b92a54107 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 22:12:09 -0700
+Subject: cxl/pci: Make 'struct cxl_mem' device type generic
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 99e222a5f1b67dd17c2c780f4eb9a694707d3bf7 ]
+
+In preparation for adding a unit test provider of a cxl_memdev, convert
+the 'struct cxl_mem' driver context to carry a generic device rather
+than a pci device.
+
+Note, some dev_dbg() lines needed extra reformatting per clang-format.
+
+This conversion also allows the cxl_mem_create() and
+devm_cxl_add_memdev() calling conventions to be simplified. The "host"
+for a cxl_memdev, must be the same device for the driver that allocated
+@cxlm.
+
+Acked-by: Ben Widawsky <ben.widawsky@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Ben Widawsky <ben.widawsky@intel.com>
+Link: https://lore.kernel.org/r/163116432973.2460985.7553504957932024222.stgit@dwillia2-desk3.amr.corp.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 88d3917f82ed ("cxl/mem: Fix shutdown order")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/memdev.c |  7 ++--
+ drivers/cxl/cxlmem.h      |  6 ++--
+ drivers/cxl/pci.c         | 75 ++++++++++++++++++---------------------
+ 3 files changed, 41 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
+index a9c317e320107..331ef7d6c5984 100644
+--- a/drivers/cxl/core/memdev.c
++++ b/drivers/cxl/core/memdev.c
+@@ -149,7 +149,6 @@ static void cxl_memdev_unregister(void *_cxlmd)
+ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm,
+                                          const struct file_operations *fops)
+ {
+-      struct pci_dev *pdev = cxlm->pdev;
+       struct cxl_memdev *cxlmd;
+       struct device *dev;
+       struct cdev *cdev;
+@@ -166,7 +165,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm,
+       dev = &cxlmd->dev;
+       device_initialize(dev);
+-      dev->parent = &pdev->dev;
++      dev->parent = cxlm->dev;
+       dev->bus = &cxl_bus_type;
+       dev->devt = MKDEV(cxl_mem_major, cxlmd->id);
+       dev->type = &cxl_memdev_type;
+@@ -182,7 +181,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm,
+ }
+ struct cxl_memdev *
+-devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm,
++devm_cxl_add_memdev(struct cxl_mem *cxlm,
+                   const struct cdevm_file_operations *cdevm_fops)
+ {
+       struct cxl_memdev *cxlmd;
+@@ -210,7 +209,7 @@ devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm,
+       if (rc)
+               goto err;
+-      rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd);
++      rc = devm_add_action_or_reset(cxlm->dev, cxl_memdev_unregister, cxlmd);
+       if (rc)
+               return ERR_PTR(rc);
+       return cxlmd;
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index 6c0b1e2ea97c7..d5334df83fb25 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -63,12 +63,12 @@ static inline struct cxl_memdev *to_cxl_memdev(struct device *dev)
+ }
+ struct cxl_memdev *
+-devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm,
++devm_cxl_add_memdev(struct cxl_mem *cxlm,
+                   const struct cdevm_file_operations *cdevm_fops);
+ /**
+  * struct cxl_mem - A CXL memory device
+- * @pdev: The PCI device associated with this CXL device.
++ * @dev: The device associated with this CXL device.
+  * @cxlmd: Logical memory device chardev / interface
+  * @regs: Parsed register blocks
+  * @payload_size: Size of space for payload
+@@ -82,7 +82,7 @@ devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm,
+  * @ram_range: Volatile memory capacity information.
+  */
+ struct cxl_mem {
+-      struct pci_dev *pdev;
++      struct device *dev;
+       struct cxl_memdev *cxlmd;
+       struct cxl_regs regs;
+diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
+index 5444b5a7fd3c4..7b8ff6e592c46 100644
+--- a/drivers/cxl/pci.c
++++ b/drivers/cxl/pci.c
+@@ -250,7 +250,7 @@ static int cxl_mem_wait_for_doorbell(struct cxl_mem *cxlm)
+               cpu_relax();
+       }
+-      dev_dbg(&cxlm->pdev->dev, "Doorbell wait took %dms",
++      dev_dbg(cxlm->dev, "Doorbell wait took %dms",
+               jiffies_to_msecs(end) - jiffies_to_msecs(start));
+       return 0;
+ }
+@@ -268,7 +268,7 @@ static bool cxl_is_security_command(u16 opcode)
+ static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm,
+                                struct mbox_cmd *mbox_cmd)
+ {
+-      struct device *dev = &cxlm->pdev->dev;
++      struct device *dev = cxlm->dev;
+       dev_dbg(dev, "Mailbox command (opcode: %#x size: %zub) timed out\n",
+               mbox_cmd->opcode, mbox_cmd->size_in);
+@@ -300,6 +300,7 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+                                  struct mbox_cmd *mbox_cmd)
+ {
+       void __iomem *payload = cxlm->regs.mbox + CXLDEV_MBOX_PAYLOAD_OFFSET;
++      struct device *dev = cxlm->dev;
+       u64 cmd_reg, status_reg;
+       size_t out_len;
+       int rc;
+@@ -325,8 +326,7 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+       /* #1 */
+       if (cxl_doorbell_busy(cxlm)) {
+-              dev_err_ratelimited(&cxlm->pdev->dev,
+-                                  "Mailbox re-busy after acquiring\n");
++              dev_err_ratelimited(dev, "Mailbox re-busy after acquiring\n");
+               return -EBUSY;
+       }
+@@ -345,7 +345,7 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+       writeq(cmd_reg, cxlm->regs.mbox + CXLDEV_MBOX_CMD_OFFSET);
+       /* #4 */
+-      dev_dbg(&cxlm->pdev->dev, "Sending command\n");
++      dev_dbg(dev, "Sending command\n");
+       writel(CXLDEV_MBOX_CTRL_DOORBELL,
+              cxlm->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET);
+@@ -362,7 +362,7 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+               FIELD_GET(CXLDEV_MBOX_STATUS_RET_CODE_MASK, status_reg);
+       if (mbox_cmd->return_code != 0) {
+-              dev_dbg(&cxlm->pdev->dev, "Mailbox operation had an error\n");
++              dev_dbg(dev, "Mailbox operation had an error\n");
+               return 0;
+       }
+@@ -399,7 +399,7 @@ static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm,
+  */
+ static int cxl_mem_mbox_get(struct cxl_mem *cxlm)
+ {
+-      struct device *dev = &cxlm->pdev->dev;
++      struct device *dev = cxlm->dev;
+       u64 md_status;
+       int rc;
+@@ -502,7 +502,7 @@ static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm,
+                                       u64 in_payload, u64 out_payload,
+                                       s32 *size_out, u32 *retval)
+ {
+-      struct device *dev = &cxlm->pdev->dev;
++      struct device *dev = cxlm->dev;
+       struct mbox_cmd mbox_cmd = {
+               .opcode = cmd->opcode,
+               .size_in = cmd->info.size_in,
+@@ -925,20 +925,19 @@ static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm)
+        */
+       cxlm->payload_size = min_t(size_t, cxlm->payload_size, SZ_1M);
+       if (cxlm->payload_size < 256) {
+-              dev_err(&cxlm->pdev->dev, "Mailbox is too small (%zub)",
++              dev_err(cxlm->dev, "Mailbox is too small (%zub)",
+                       cxlm->payload_size);
+               return -ENXIO;
+       }
+-      dev_dbg(&cxlm->pdev->dev, "Mailbox payload sized %zu",
++      dev_dbg(cxlm->dev, "Mailbox payload sized %zu",
+               cxlm->payload_size);
+       return 0;
+ }
+-static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev)
++static struct cxl_mem *cxl_mem_create(struct device *dev)
+ {
+-      struct device *dev = &pdev->dev;
+       struct cxl_mem *cxlm;
+       cxlm = devm_kzalloc(dev, sizeof(*cxlm), GFP_KERNEL);
+@@ -948,7 +947,7 @@ static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev)
+       }
+       mutex_init(&cxlm->mbox_mutex);
+-      cxlm->pdev = pdev;
++      cxlm->dev = dev;
+       cxlm->enabled_cmds =
+               devm_kmalloc_array(dev, BITS_TO_LONGS(cxl_cmd_count),
+                                  sizeof(unsigned long),
+@@ -964,9 +963,9 @@ static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev)
+ static void __iomem *cxl_mem_map_regblock(struct cxl_mem *cxlm,
+                                         u8 bar, u64 offset)
+ {
+-      struct pci_dev *pdev = cxlm->pdev;
+-      struct device *dev = &pdev->dev;
+       void __iomem *addr;
++      struct device *dev = cxlm->dev;
++      struct pci_dev *pdev = to_pci_dev(dev);
+       /* Basic sanity check that BAR is big enough */
+       if (pci_resource_len(pdev, bar) < offset) {
+@@ -989,7 +988,7 @@ static void __iomem *cxl_mem_map_regblock(struct cxl_mem *cxlm,
+ static void cxl_mem_unmap_regblock(struct cxl_mem *cxlm, void __iomem *base)
+ {
+-      pci_iounmap(cxlm->pdev, base);
++      pci_iounmap(to_pci_dev(cxlm->dev), base);
+ }
+ static int cxl_mem_dvsec(struct pci_dev *pdev, int dvsec)
+@@ -1018,10 +1017,9 @@ static int cxl_mem_dvsec(struct pci_dev *pdev, int dvsec)
+ static int cxl_probe_regs(struct cxl_mem *cxlm, void __iomem *base,
+                         struct cxl_register_map *map)
+ {
+-      struct pci_dev *pdev = cxlm->pdev;
+-      struct device *dev = &pdev->dev;
+       struct cxl_component_reg_map *comp_map;
+       struct cxl_device_reg_map *dev_map;
++      struct device *dev = cxlm->dev;
+       switch (map->reg_type) {
+       case CXL_REGLOC_RBI_COMPONENT:
+@@ -1057,8 +1055,8 @@ static int cxl_probe_regs(struct cxl_mem *cxlm, void __iomem *base,
+ static int cxl_map_regs(struct cxl_mem *cxlm, struct cxl_register_map *map)
+ {
+-      struct pci_dev *pdev = cxlm->pdev;
+-      struct device *dev = &pdev->dev;
++      struct device *dev = cxlm->dev;
++      struct pci_dev *pdev = to_pci_dev(dev);
+       switch (map->reg_type) {
+       case CXL_REGLOC_RBI_COMPONENT:
+@@ -1096,13 +1094,12 @@ static void cxl_decode_register_block(u32 reg_lo, u32 reg_hi,
+  */
+ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
+ {
+-      struct pci_dev *pdev = cxlm->pdev;
+-      struct device *dev = &pdev->dev;
+-      u32 regloc_size, regblocks;
+       void __iomem *base;
+-      int regloc, i, n_maps;
++      u32 regloc_size, regblocks;
++      int regloc, i, n_maps, ret = 0;
++      struct device *dev = cxlm->dev;
++      struct pci_dev *pdev = to_pci_dev(dev);
+       struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES];
+-      int ret = 0;
+       regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
+       if (!regloc) {
+@@ -1226,7 +1223,7 @@ static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel)
+               struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
+               if (!cmd) {
+-                      dev_dbg(&cxlm->pdev->dev,
++                      dev_dbg(cxlm->dev,
+                               "Opcode 0x%04x unsupported by driver", opcode);
+                       continue;
+               }
+@@ -1323,7 +1320,7 @@ static int cxl_mem_get_partition_info(struct cxl_mem *cxlm,
+ static int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm)
+ {
+       struct cxl_mbox_get_supported_logs *gsl;
+-      struct device *dev = &cxlm->pdev->dev;
++      struct device *dev = cxlm->dev;
+       struct cxl_mem_command *cmd;
+       int i, rc;
+@@ -1418,15 +1415,14 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
+       cxlm->partition_align_bytes = le64_to_cpu(id.partition_align);
+       cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER;
+-      dev_dbg(&cxlm->pdev->dev, "Identify Memory Device\n"
++      dev_dbg(cxlm->dev,
++              "Identify Memory Device\n"
+               "     total_bytes = %#llx\n"
+               "     volatile_only_bytes = %#llx\n"
+               "     persistent_only_bytes = %#llx\n"
+               "     partition_align_bytes = %#llx\n",
+-                      cxlm->total_bytes,
+-                      cxlm->volatile_only_bytes,
+-                      cxlm->persistent_only_bytes,
+-                      cxlm->partition_align_bytes);
++              cxlm->total_bytes, cxlm->volatile_only_bytes,
++              cxlm->persistent_only_bytes, cxlm->partition_align_bytes);
+       cxlm->lsa_size = le32_to_cpu(id.lsa_size);
+       memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision));
+@@ -1453,19 +1449,18 @@ static int cxl_mem_create_range_info(struct cxl_mem *cxlm)
+                                       &cxlm->next_volatile_bytes,
+                                       &cxlm->next_persistent_bytes);
+       if (rc < 0) {
+-              dev_err(&cxlm->pdev->dev, "Failed to query partition information\n");
++              dev_err(cxlm->dev, "Failed to query partition information\n");
+               return rc;
+       }
+-      dev_dbg(&cxlm->pdev->dev, "Get Partition Info\n"
++      dev_dbg(cxlm->dev,
++              "Get Partition Info\n"
+               "     active_volatile_bytes = %#llx\n"
+               "     active_persistent_bytes = %#llx\n"
+               "     next_volatile_bytes = %#llx\n"
+               "     next_persistent_bytes = %#llx\n",
+-                      cxlm->active_volatile_bytes,
+-                      cxlm->active_persistent_bytes,
+-                      cxlm->next_volatile_bytes,
+-                      cxlm->next_persistent_bytes);
++              cxlm->active_volatile_bytes, cxlm->active_persistent_bytes,
++              cxlm->next_volatile_bytes, cxlm->next_persistent_bytes);
+       cxlm->ram_range.start = 0;
+       cxlm->ram_range.end = cxlm->active_volatile_bytes - 1;
+@@ -1487,7 +1482,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (rc)
+               return rc;
+-      cxlm = cxl_mem_create(pdev);
++      cxlm = cxl_mem_create(&pdev->dev);
+       if (IS_ERR(cxlm))
+               return PTR_ERR(cxlm);
+@@ -1511,7 +1506,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (rc)
+               return rc;
+-      cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops);
++      cxlmd = devm_cxl_add_memdev(cxlm, &cxl_memdev_fops);
+       if (IS_ERR(cxlmd))
+               return PTR_ERR(cxlmd);
+-- 
+2.42.0
+
diff --git a/queue-5.15/dmaengine-idxd-register-dsa_bus_type-before-register.patch b/queue-5.15/dmaengine-idxd-register-dsa_bus_type-before-register.patch
new file mode 100644 (file)
index 0000000..ff26053
--- /dev/null
@@ -0,0 +1,63 @@
+From cef30404d7f329fd0a8c3b58d65b02f3fe799dfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 09:22:32 -0700
+Subject: dmaengine: idxd: Register dsa_bus_type before registering idxd
+ sub-drivers
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+[ Upstream commit 88928addeec577386e8c83b48b5bc24d28ba97fd ]
+
+idxd sub-drivers belong to bus dsa_bus_type. Thus, dsa_bus_type must be
+registered in dsa bus init before idxd drivers can be registered.
+
+But the order is wrong when both idxd and idxd_bus are builtin drivers.
+In this case, idxd driver is compiled and linked before idxd_bus driver.
+Since the initcall order is determined by the link order, idxd sub-drivers
+are registered in idxd initcall before dsa_bus_type is registered
+in idxd_bus initcall. idxd initcall fails:
+
+[   21.562803] calling  idxd_init_module+0x0/0x110 @ 1
+[   21.570761] Driver 'idxd' was unable to register with bus_type 'dsa' because the bus was not initialized.
+[   21.586475] initcall idxd_init_module+0x0/0x110 returned -22 after 15717 usecs
+[   21.597178] calling  dsa_bus_init+0x0/0x20 @ 1
+
+To fix the issue, compile and link idxd_bus driver before idxd driver
+to ensure the right registration order.
+
+Fixes: d9e5481fca74 ("dmaengine: dsa: move dsa_bus_type out of idxd driver to standalone")
+Reported-by: Michael Prinke <michael.prinke@intel.com>
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Lijun Pan <lijun.pan@intel.com>
+Tested-by: Lijun Pan <lijun.pan@intel.com>
+Link: https://lore.kernel.org/r/20230924162232.1409454-1-fenghua.yu@intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/idxd/Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile
+index a1e9f2b3a37cc..817ffa95a9b11 100644
+--- a/drivers/dma/idxd/Makefile
++++ b/drivers/dma/idxd/Makefile
+@@ -1,12 +1,12 @@
+ ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD
++obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o
++idxd_bus-y := bus.o
++
+ obj-$(CONFIG_INTEL_IDXD) += idxd.o
+ idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o
+ idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o
+-obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o
+-idxd_bus-y := bus.o
+-
+ obj-$(CONFIG_INTEL_IDXD_COMPAT) += idxd_compat.o
+ idxd_compat-y := compat.o
+-- 
+2.42.0
+
diff --git a/queue-5.15/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch b/queue-5.15/dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch
new file mode 100644 (file)
index 0000000..e3a392f
--- /dev/null
@@ -0,0 +1,43 @@
+From b293bb4c2bf0ee22c8ab169c53a13b9c0fc26be4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Oct 2023 13:13:09 +0200
+Subject: dmaengine: pxa_dma: Remove an erroneous BUG_ON() in pxad_free_desc()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 83c761f568733277ce1f7eb9dc9e890649c29a8c ]
+
+If pxad_alloc_desc() fails on the first dma_pool_alloc() call, then
+sw_desc->nb_desc is zero.
+In such a case pxad_free_desc() is called and it will BUG_ON().
+
+Remove this erroneous BUG_ON().
+
+It is also useless, because if "sw_desc->nb_desc == 0", then, on the first
+iteration of the for loop, i is -1 and the loop will not be executed.
+(both i and sw_desc->nb_desc are 'int')
+
+Fixes: a57e16cf0333 ("dmaengine: pxa: add pxa dmaengine driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/c8fc5563c9593c914fde41f0f7d1489a21b45a9a.1696676782.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/pxa_dma.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
+index e613ace79ea83..2731dc27f9d71 100644
+--- a/drivers/dma/pxa_dma.c
++++ b/drivers/dma/pxa_dma.c
+@@ -722,7 +722,6 @@ static void pxad_free_desc(struct virt_dma_desc *vd)
+       dma_addr_t dma;
+       struct pxad_desc_sw *sw_desc = to_pxad_sw_desc(vd);
+-      BUG_ON(sw_desc->nb_desc == 0);
+       for (i = sw_desc->nb_desc - 1; i >= 0; i--) {
+               if (i > 0)
+                       dma = sw_desc->hw_desc[i - 1]->ddadr;
+-- 
+2.42.0
+
diff --git a/queue-5.15/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch b/queue-5.15/dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch
new file mode 100644 (file)
index 0000000..3ed4f0c
--- /dev/null
@@ -0,0 +1,48 @@
+From 21cbc9a74b2edd6e2fd17e7c47c28ba0530f60a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 15:59:59 +0300
+Subject: dmaengine: ti: edma: handle irq_of_parse_and_map() errors
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 14f6d317913f634920a640e9047aa2e66f5bdcb7 ]
+
+Zero is not a valid IRQ for in-kernel code and the irq_of_parse_and_map()
+function returns zero on error.  So this check for valid IRQs should only
+accept values > 0.
+
+Fixes: 2b6b3b742019 ("ARM/dmaengine: edma: Merge the two drivers under drivers/dma/")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Link: https://lore.kernel.org/r/f15cb6a7-8449-4f79-98b6-34072f04edbc@moroto.mountain
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/ti/edma.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
+index 35d81bd857f11..a1adc8d91fd8d 100644
+--- a/drivers/dma/ti/edma.c
++++ b/drivers/dma/ti/edma.c
+@@ -2459,7 +2459,7 @@ static int edma_probe(struct platform_device *pdev)
+       if (irq < 0 && node)
+               irq = irq_of_parse_and_map(node, 0);
+-      if (irq >= 0) {
++      if (irq > 0) {
+               irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint",
+                                         dev_name(dev));
+               ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name,
+@@ -2475,7 +2475,7 @@ static int edma_probe(struct platform_device *pdev)
+       if (irq < 0 && node)
+               irq = irq_of_parse_and_map(node, 2);
+-      if (irq >= 0) {
++      if (irq > 0) {
+               irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint",
+                                         dev_name(dev));
+               ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name,
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch b/queue-5.15/drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch
new file mode 100644 (file)
index 0000000..52e73bd
--- /dev/null
@@ -0,0 +1,50 @@
+From 49d2451d6b1a1e1518954a829261c73a3f2bb3ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 11:02:51 -0500
+Subject: drm/amdkfd: fix some race conditions in vram buffer alloc/free of svm
+ code
+
+From: Xiaogang Chen <xiaogang.chen@amd.com>
+
+[ Upstream commit 7bfaa160caed8192f8262c4638f552cad94bcf5a ]
+
+This patch fixes:
+1: ref number of prange's svm_bo got decreased by an async call from hmm. When
+wait svm_bo of prange got released we shoul also wait prang->svm_bo become NULL,
+otherwise prange->svm_bo may be set to null after allocate new vram buffer.
+
+2: During waiting svm_bo of prange got released in a while loop should reschedule
+current task to give other tasks oppotunity to run, specially the the workque
+task that handles svm_bo ref release, otherwise we may enter to softlock.
+
+Signed-off-by: Xiaogang.Chen <xiaogang.chen@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_svm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+index 22a70aaccf13c..86135ca33e5be 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+@@ -433,11 +433,11 @@ svm_range_validate_svm_bo(struct amdgpu_device *adev, struct svm_range *prange)
+       /* We need a new svm_bo. Spin-loop to wait for concurrent
+        * svm_range_bo_release to finish removing this range from
+-       * its range list. After this, it is safe to reuse the
+-       * svm_bo pointer and svm_bo_list head.
++       * its range list and set prange->svm_bo to null. After this,
++       * it is safe to reuse the svm_bo pointer and svm_bo_list head.
+        */
+-      while (!list_empty_careful(&prange->svm_bo_list))
+-              ;
++      while (!list_empty_careful(&prange->svm_bo_list) || prange->svm_bo)
++              cond_resched();
+       return false;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-add-hot-plug-detection.patch b/queue-5.15/drm-bridge-lt8912b-add-hot-plug-detection.patch
new file mode 100644 (file)
index 0000000..1d5f273
--- /dev/null
@@ -0,0 +1,74 @@
+From ac2522362394c2b4eda54d4b81f1135836b4edce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 12:23:20 +0100
+Subject: drm/bridge: lt8912b: Add hot plug detection
+
+From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+
+[ Upstream commit 3b0a01a6a5224ed9b3f69f44edaa889b2e2b9779 ]
+
+Enable hot plug detection when it is available on the HDMI port.
+Without this connecting to a different monitor with incompatible timing
+before the 10 seconds poll period will lead to a broken display output.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Reviewed-by: Adrien Grassein <adrien.grassein@gmail.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221128112320.25708-1-francesco@dolcini.it
+Stable-dep-of: 941882a0e96d ("drm/bridge: lt8912b: Fix bridge_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 6ad3b2d1819f1..a89e505aa3811 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -506,14 +506,27 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
+       return 0;
+ }
++static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status)
++{
++      struct lt8912 *lt = data;
++
++      if (lt->bridge.dev)
++              drm_helper_hpd_irq_event(lt->bridge.dev);
++}
++
+ static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
+ {
+       int ret;
+       struct lt8912 *lt = bridge_to_lt8912(bridge);
+       struct drm_connector *connector = &lt->connector;
+-      connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+-                          DRM_CONNECTOR_POLL_DISCONNECT;
++      if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) {
++              drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt);
++              connector->polled = DRM_CONNECTOR_POLL_HPD;
++      } else {
++              connector->polled = DRM_CONNECTOR_POLL_CONNECT |
++                                  DRM_CONNECTOR_POLL_DISCONNECT;
++      }
+       ret = drm_connector_init(bridge->dev, connector,
+                                &lt8912_connector_funcs,
+@@ -567,6 +580,10 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+       if (lt->is_attached) {
+               lt8912_hard_power_off(lt);
++
++              if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
++                      drm_bridge_hpd_disable(lt->hdmi_port);
++
+               drm_connector_unregister(&lt->connector);
+               drm_connector_cleanup(&lt->connector);
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch b/queue-5.15/drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch
new file mode 100644 (file)
index 0000000..e1c2412
--- /dev/null
@@ -0,0 +1,46 @@
+From e0842810e16a4adfac827f17a838c9e9e724d703 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:48:13 +0300
+Subject: drm/bridge: lt8912b: Add missing drm_bridge_attach call
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit f45acf7acf75921c0409d452f0165f51a19a74fd ]
+
+The driver does not call drm_bridge_attach(), which causes the next
+bridge to not be added to the bridge chain. This causes the pipeline
+init to fail when DRM_BRIDGE_ATTACH_NO_CONNECTOR is used.
+
+Add the call to drm_bridge_attach().
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-4-c542692c6a2f@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 73b6fcae6dca8..6891863ed5104 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -548,6 +548,13 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,
+       struct lt8912 *lt = bridge_to_lt8912(bridge);
+       int ret;
++      ret = drm_bridge_attach(bridge->encoder, lt->hdmi_port, bridge,
++                              DRM_BRIDGE_ATTACH_NO_CONNECTOR);
++      if (ret < 0) {
++              dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret);
++              return ret;
++      }
++
+       if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+               ret = lt8912_bridge_connector_init(bridge);
+               if (ret) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-fix-bridge_detach.patch b/queue-5.15/drm-bridge-lt8912b-fix-bridge_detach.patch
new file mode 100644 (file)
index 0000000..de54ea0
--- /dev/null
@@ -0,0 +1,82 @@
+From 91da7a12a3eb0d3b19a628f1dd58c2f0e4024054 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:48:10 +0300
+Subject: drm/bridge: lt8912b: Fix bridge_detach
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 941882a0e96d245f38116e940912b404b6a93c6f ]
+
+The driver calls lt8912_bridge_detach() from its lt8912_remove()
+function. As the DRM core detaches bridges automatically, this leads to
+calling lt8912_bridge_detach() twice. The code probably has tried to
+manage the double-call with the 'is_attached' variable, but the driver
+never sets the variable to false, so its of no help.
+
+Fix the issue by dropping the call to lt8912_bridge_detach() from
+lt8912_remove(), as the DRM core will handle the detach call for us,
+and also drop the useless is_attached field.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-1-c542692c6a2f@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index a89e505aa3811..d435cb3ed3808 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -43,7 +43,6 @@ struct lt8912 {
+       u8 data_lanes;
+       bool is_power_on;
+-      bool is_attached;
+ };
+ static int lt8912_write_init_config(struct lt8912 *lt)
+@@ -565,8 +564,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,
+       if (ret)
+               goto error;
+-      lt->is_attached = true;
+-
+       return 0;
+ error:
+@@ -578,15 +575,13 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+ {
+       struct lt8912 *lt = bridge_to_lt8912(bridge);
+-      if (lt->is_attached) {
+-              lt8912_hard_power_off(lt);
++      lt8912_hard_power_off(lt);
+-              if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
+-                      drm_bridge_hpd_disable(lt->hdmi_port);
++      if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
++              drm_bridge_hpd_disable(lt->hdmi_port);
+-              drm_connector_unregister(&lt->connector);
+-              drm_connector_cleanup(&lt->connector);
+-      }
++      drm_connector_unregister(&lt->connector);
++      drm_connector_cleanup(&lt->connector);
+ }
+ static enum drm_connector_status
+@@ -746,7 +741,6 @@ static int lt8912_remove(struct i2c_client *client)
+ {
+       struct lt8912 *lt = i2c_get_clientdata(client);
+-      lt8912_bridge_detach(&lt->bridge);
+       drm_bridge_remove(&lt->bridge);
+       lt8912_free_i2c(lt);
+       lt8912_put_dt(lt);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch b/queue-5.15/drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch
new file mode 100644 (file)
index 0000000..41c3283
--- /dev/null
@@ -0,0 +1,109 @@
+From b0f481c45c01d2a386e38f0c1e4912aa7a661981 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:48:11 +0300
+Subject: drm/bridge: lt8912b: Fix crash on bridge detach
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 44283993144a03af9df31934d6c32bbd42d1a347 ]
+
+The lt8912b driver, in its bridge detach function, calls
+drm_connector_unregister() and drm_connector_cleanup().
+
+drm_connector_unregister() should be called only for connectors
+explicitly registered with drm_connector_register(), which is not the
+case in lt8912b.
+
+The driver's drm_connector_funcs.destroy hook is set to
+drm_connector_cleanup().
+
+Thus the driver should not call either drm_connector_unregister() nor
+drm_connector_cleanup() in its lt8912_bridge_detach(), as they cause a
+crash on bridge detach:
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+Mem abort info:
+  ESR = 0x0000000096000006
+  EC = 0x25: DABT (current EL), IL = 32 bits
+  SET = 0, FnV = 0
+  EA = 0, S1PTW = 0
+  FSC = 0x06: level 2 translation fault
+Data abort info:
+  ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
+  CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+  GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+user pgtable: 4k pages, 48-bit VAs, pgdp=00000000858f3000
+[0000000000000000] pgd=0800000085918003, p4d=0800000085918003, pud=0800000085431003, pmd=0000000000000000
+Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
+Modules linked in: tidss(-) display_connector lontium_lt8912b tc358768 panel_lvds panel_simple drm_dma_helper drm_kms_helper drm drm_panel_orientation_quirks
+CPU: 3 PID: 462 Comm: rmmod Tainted: G        W          6.5.0-rc2+ #2
+Hardware name: Toradex Verdin AM62 on Verdin Development Board (DT)
+pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : drm_connector_cleanup+0x78/0x2d4 [drm]
+lr : lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b]
+sp : ffff800082ed3a90
+x29: ffff800082ed3a90 x28: ffff0000040c1940 x27: 0000000000000000
+x26: 0000000000000000 x25: dead000000000122 x24: dead000000000122
+x23: dead000000000100 x22: ffff000003fb6388 x21: 0000000000000000
+x20: 0000000000000000 x19: ffff000003fb6260 x18: fffffffffffe56e8
+x17: 0000000000000000 x16: 0010000000000000 x15: 0000000000000038
+x14: 0000000000000000 x13: ffff800081914b48 x12: 000000000000040e
+x11: 000000000000015a x10: ffff80008196ebb8 x9 : ffff800081914b48
+x8 : 00000000ffffefff x7 : ffff0000040c1940 x6 : ffff80007aa649d0
+x5 : 0000000000000000 x4 : 0000000000000001 x3 : ffff80008159e008
+x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
+Call trace:
+ drm_connector_cleanup+0x78/0x2d4 [drm]
+ lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b]
+ drm_bridge_detach+0x44/0x84 [drm]
+ drm_encoder_cleanup+0x40/0xb8 [drm]
+ drmm_encoder_alloc_release+0x1c/0x30 [drm]
+ drm_managed_release+0xac/0x148 [drm]
+ drm_dev_put.part.0+0x88/0xb8 [drm]
+ devm_drm_dev_init_release+0x14/0x24 [drm]
+ devm_action_release+0x14/0x20
+ release_nodes+0x5c/0x90
+ devres_release_all+0x8c/0xe0
+ device_unbind_cleanup+0x18/0x68
+ device_release_driver_internal+0x208/0x23c
+ driver_detach+0x4c/0x94
+ bus_remove_driver+0x70/0xf4
+ driver_unregister+0x30/0x60
+ platform_driver_unregister+0x14/0x20
+ tidss_platform_driver_exit+0x18/0xb2c [tidss]
+ __arm64_sys_delete_module+0x1a0/0x2b4
+ invoke_syscall+0x48/0x110
+ el0_svc_common.constprop.0+0x60/0x10c
+ do_el0_svc_compat+0x1c/0x40
+ el0_svc_compat+0x40/0xac
+ el0t_32_sync_handler+0xb0/0x138
+ el0t_32_sync+0x194/0x198
+Code: 9104a276 f2fbd5b7 aa0203e1 91008af8 (f85c0420)
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-2-c542692c6a2f@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index d435cb3ed3808..b1e5acca171be 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -579,9 +579,6 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+       if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
+               drm_bridge_hpd_disable(lt->hdmi_port);
+-
+-      drm_connector_unregister(&lt->connector);
+-      drm_connector_cleanup(&lt->connector);
+ }
+ static enum drm_connector_status
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch b/queue-5.15/drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch
new file mode 100644 (file)
index 0000000..49c9c24
--- /dev/null
@@ -0,0 +1,44 @@
+From 47f9aa56c92b0ee9b131f1fa7c30d75fb2560be2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:48:12 +0300
+Subject: drm/bridge: lt8912b: Manually disable HPD only if it was enabled
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 6985c5efc4057bc79137807295d84ada3123d051 ]
+
+lt8912b only calls drm_bridge_hpd_enable() if it creates a connector and
+the next bridge has DRM_BRIDGE_OP_HPD set. However, when calling
+drm_bridge_hpd_disable() it misses checking if a connector was created,
+calling drm_bridge_hpd_disable() even if HPD was never enabled. I don't
+see any issues caused by this wrong call, though.
+
+Add the check to avoid wrongly calling drm_bridge_hpd_disable().
+
+Fixes: 3b0a01a6a522 ("drm/bridge: lt8912b: Add hot plug detection")
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230804-lt8912b-v1-3-c542692c6a2f@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index b1e5acca171be..73b6fcae6dca8 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -577,7 +577,7 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+       lt8912_hard_power_off(lt);
+-      if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
++      if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
+               drm_bridge_hpd_disable(lt->hdmi_port);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-register-and-attach-our-dsi-devic.patch b/queue-5.15/drm-bridge-lt8912b-register-and-attach-our-dsi-devic.patch
new file mode 100644 (file)
index 0000000..28572bf
--- /dev/null
@@ -0,0 +1,56 @@
+From 3c4515b29563df7f164c18188c98821f2da3f2d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 17:15:21 +0200
+Subject: drm/bridge: lt8912b: Register and attach our DSI device at probe
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit d89078c37b10f05fa4f4791b71db2572db361b68 ]
+
+In order to avoid any probe ordering issue, the best practice is to move
+the secondary MIPI-DSI device registration and attachment to the
+MIPI-DSI host at probe time. Let's do this.
+
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211025151536.1048186-7-maxime@cerno.tech
+Stable-dep-of: 941882a0e96d ("drm/bridge: lt8912b: Fix bridge_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 24ca22b0b9f56..6ad3b2d1819f1 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -552,10 +552,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,
+       if (ret)
+               goto error;
+-      ret = lt8912_attach_dsi(lt);
+-      if (ret)
+-              goto error;
+-
+       lt->is_attached = true;
+       return 0;
+@@ -714,8 +710,15 @@ static int lt8912_probe(struct i2c_client *client,
+       drm_bridge_add(&lt->bridge);
++      ret = lt8912_attach_dsi(lt);
++      if (ret)
++              goto err_attach;
++
+       return 0;
++err_attach:
++      drm_bridge_remove(&lt->bridge);
++      lt8912_free_i2c(lt);
+ err_i2c:
+       lt8912_put_dt(lt);
+ err_dt_parse:
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt8912b-switch-to-devm-mipi-dsi-helpers.patch b/queue-5.15/drm-bridge-lt8912b-switch-to-devm-mipi-dsi-helpers.patch
new file mode 100644 (file)
index 0000000..6c29b29
--- /dev/null
@@ -0,0 +1,77 @@
+From 9e99f0286e16b79585c4303b7ecb03979e67ef29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 17:15:20 +0200
+Subject: drm/bridge: lt8912b: Switch to devm MIPI-DSI helpers
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 1fdbf66e3d40257902b4c5cdf872730dae24004f ]
+
+Let's switch to the new devm MIPI-DSI function to register and attach
+our secondary device.
+
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211025151536.1048186-6-maxime@cerno.tech
+Stable-dep-of: 941882a0e96d ("drm/bridge: lt8912b: Fix bridge_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 20 ++++----------------
+ 1 file changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index d3fd76a0a34ae..24ca22b0b9f56 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -481,11 +481,11 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
+               return -EPROBE_DEFER;
+       }
+-      dsi = mipi_dsi_device_register_full(host, &info);
++      dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+       if (IS_ERR(dsi)) {
+               ret = PTR_ERR(dsi);
+               dev_err(dev, "failed to create dsi device (%d)\n", ret);
+-              goto err_dsi_device;
++              return ret;
+       }
+       lt->dsi = dsi;
+@@ -497,24 +497,13 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
+                         MIPI_DSI_MODE_LPM |
+                         MIPI_DSI_MODE_NO_EOT_PACKET;
+-      ret = mipi_dsi_attach(dsi);
++      ret = devm_mipi_dsi_attach(dev, dsi);
+       if (ret < 0) {
+               dev_err(dev, "failed to attach dsi to host\n");
+-              goto err_dsi_attach;
++              return ret;
+       }
+       return 0;
+-
+-err_dsi_attach:
+-      mipi_dsi_device_unregister(dsi);
+-err_dsi_device:
+-      return ret;
+-}
+-
+-static void lt8912_detach_dsi(struct lt8912 *lt)
+-{
+-      mipi_dsi_detach(lt->dsi);
+-      mipi_dsi_device_unregister(lt->dsi);
+ }
+ static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
+@@ -581,7 +570,6 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+       struct lt8912 *lt = bridge_to_lt8912(bridge);
+       if (lt->is_attached) {
+-              lt8912_detach_dsi(lt);
+               lt8912_hard_power_off(lt);
+               drm_connector_unregister(&lt->connector);
+               drm_connector_cleanup(&lt->connector);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch b/queue-5.15/drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch
new file mode 100644 (file)
index 0000000..b17650b
--- /dev/null
@@ -0,0 +1,97 @@
+From e361bf4a5728d60658080eea4a8fe30ee27820cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 01:00:02 +0300
+Subject: drm/bridge: lt9611uxc: fix the race in the error path
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 15fe53be46eaf4f6339cd433972ecc90513e3076 ]
+
+If DSI host attachment fails, the LT9611UXC driver will remove the
+bridge without ensuring that there is no outstanding HPD work being
+done. In rare cases this can result in the warnings regarding the mutex
+being incorrect. Fix this by forcebly freing IRQ and flushing the work.
+
+DEBUG_LOCKS_WARN_ON(lock->magic != lock)
+WARNING: CPU: 0 PID: 10 at kernel/locking/mutex.c:582 __mutex_lock+0x468/0x77c
+Modules linked in:
+CPU: 0 PID: 10 Comm: kworker/0:1 Tainted: G     U             6.6.0-rc5-next-20231011-gd81f81c2b682-dirty #1206
+Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
+Workqueue: events lt9611uxc_hpd_work
+pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : __mutex_lock+0x468/0x77c
+lr : __mutex_lock+0x468/0x77c
+sp : ffff8000800a3c70
+x29: ffff8000800a3c70 x28: 0000000000000000 x27: ffffd595fe333000
+x26: ffff7c2f0002c005 x25: ffffd595ff1b3000 x24: ffffd595fccda5a0
+x23: 0000000000000000 x22: 0000000000000002 x21: ffff7c2f056d91c8
+x20: 0000000000000000 x19: ffff7c2f056d91c8 x18: fffffffffffe8db0
+x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000
+x14: 000000000006efb8 x13: 0000000000000000 x12: 0000000000000037
+x11: 0000000000000001 x10: 0000000000001470 x9 : ffff8000800a3ae0
+x8 : ffff7c2f0027f8d0 x7 : ffff7c2f0027e400 x6 : ffffd595fc702b54
+x5 : 0000000000000000 x4 : ffff8000800a0000 x3 : 0000000000000000
+x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff7c2f0027e400
+Call trace:
+ __mutex_lock+0x468/0x77c
+ mutex_lock_nested+0x24/0x30
+ drm_bridge_hpd_notify+0x2c/0x5c
+ lt9611uxc_hpd_work+0x6c/0x80
+ process_one_work+0x1ec/0x51c
+ worker_thread+0x1ec/0x3e4
+ kthread+0x120/0x124
+ ret_from_fork+0x10/0x20
+irq event stamp: 15799
+hardirqs last  enabled at (15799): [<ffffd595fc702ba4>] finish_task_switch.isra.0+0xa8/0x278
+hardirqs last disabled at (15798): [<ffffd595fd5a1580>] __schedule+0x7b8/0xbd8
+softirqs last  enabled at (15794): [<ffffd595fc690698>] __do_softirq+0x498/0x4e0
+softirqs last disabled at (15771): [<ffffd595fc69615c>] ____do_softirq+0x10/0x1c
+
+Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231011220002.382422-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index 1e33b3150bdc5..2a848e14181bd 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -927,9 +927,9 @@ static int lt9611uxc_probe(struct i2c_client *client,
+       init_waitqueue_head(&lt9611uxc->wq);
+       INIT_WORK(&lt9611uxc->work, lt9611uxc_hpd_work);
+-      ret = devm_request_threaded_irq(dev, client->irq, NULL,
+-                                      lt9611uxc_irq_thread_handler,
+-                                      IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
++      ret = request_threaded_irq(client->irq, NULL,
++                                 lt9611uxc_irq_thread_handler,
++                                 IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
+       if (ret) {
+               dev_err(dev, "failed to request irq\n");
+               goto err_disable_regulators;
+@@ -965,6 +965,8 @@ static int lt9611uxc_probe(struct i2c_client *client,
+       return lt9611uxc_audio_init(dev, lt9611uxc);
+ err_remove_bridge:
++      free_irq(client->irq, lt9611uxc);
++      cancel_work_sync(&lt9611uxc->work);
+       drm_bridge_remove(&lt9611uxc->bridge);
+ err_disable_regulators:
+@@ -981,7 +983,7 @@ static int lt9611uxc_remove(struct i2c_client *client)
+ {
+       struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
+-      disable_irq(client->irq);
++      free_irq(client->irq, lt9611uxc);
+       cancel_work_sync(&lt9611uxc->work);
+       lt9611uxc_audio_exit(lt9611uxc);
+       drm_bridge_remove(&lt9611uxc->bridge);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt9611uxc-register-and-attach-our-dsi-dev.patch b/queue-5.15/drm-bridge-lt9611uxc-register-and-attach-our-dsi-dev.patch
new file mode 100644 (file)
index 0000000..b2bd8c2
--- /dev/null
@@ -0,0 +1,76 @@
+From b5b7ebc758de810cde1fe1a8b6dc0c360a16ce5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 17:15:25 +0200
+Subject: drm/bridge: lt9611uxc: Register and attach our DSI device at probe
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 4a46ace5ac621c0f84b3910bc3c93acf6c93963b ]
+
+In order to avoid any probe ordering issue, the best practice is to move
+the secondary MIPI-DSI device registration and attachment to the
+MIPI-DSI host at probe time. Let's do this.
+
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211025151536.1048186-11-maxime@cerno.tech
+Stable-dep-of: 15fe53be46ea ("drm/bridge: lt9611uxc: fix the race in the error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 31 +++++++++++++---------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index b58842f69fff1..1e33b3150bdc5 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -367,18 +367,6 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
+                       return ret;
+       }
+-      /* Attach primary DSI */
+-      lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node);
+-      if (IS_ERR(lt9611uxc->dsi0))
+-              return PTR_ERR(lt9611uxc->dsi0);
+-
+-      /* Attach secondary DSI, if specified */
+-      if (lt9611uxc->dsi1_node) {
+-              lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node);
+-              if (IS_ERR(lt9611uxc->dsi1))
+-                      return PTR_ERR(lt9611uxc->dsi1);
+-      }
+-
+       return 0;
+ }
+@@ -958,8 +946,27 @@ static int lt9611uxc_probe(struct i2c_client *client,
+       drm_bridge_add(&lt9611uxc->bridge);
++      /* Attach primary DSI */
++      lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node);
++      if (IS_ERR(lt9611uxc->dsi0)) {
++              ret = PTR_ERR(lt9611uxc->dsi0);
++              goto err_remove_bridge;
++      }
++
++      /* Attach secondary DSI, if specified */
++      if (lt9611uxc->dsi1_node) {
++              lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node);
++              if (IS_ERR(lt9611uxc->dsi1)) {
++                      ret = PTR_ERR(lt9611uxc->dsi1);
++                      goto err_remove_bridge;
++              }
++      }
++
+       return lt9611uxc_audio_init(dev, lt9611uxc);
++err_remove_bridge:
++      drm_bridge_remove(&lt9611uxc->bridge);
++
+ err_disable_regulators:
+       regulator_bulk_disable(ARRAY_SIZE(lt9611uxc->supplies), lt9611uxc->supplies);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-lt9611uxc-switch-to-devm-mipi-dsi-helpers.patch b/queue-5.15/drm-bridge-lt9611uxc-switch-to-devm-mipi-dsi-helpers.patch
new file mode 100644 (file)
index 0000000..057b660
--- /dev/null
@@ -0,0 +1,113 @@
+From 3efc5c224d70063d85d9dbedcf4c850335afe2c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 17:15:24 +0200
+Subject: drm/bridge: lt9611uxc: Switch to devm MIPI-DSI helpers
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 293ada7b058e536d9d53d0d8840c6ba8c2f718e4 ]
+
+Let's switch to the new devm MIPI-DSI function to register and attach
+our secondary device.
+
+Acked-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211025151536.1048186-10-maxime@cerno.tech
+Stable-dep-of: 15fe53be46ea ("drm/bridge: lt9611uxc: fix the race in the error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 38 +++++-----------------
+ 1 file changed, 8 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index c4454d0f6cad5..b58842f69fff1 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -258,17 +258,18 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc,
+       const struct mipi_dsi_device_info info = { "lt9611uxc", 0, NULL };
+       struct mipi_dsi_device *dsi;
+       struct mipi_dsi_host *host;
++      struct device *dev = lt9611uxc->dev;
+       int ret;
+       host = of_find_mipi_dsi_host_by_node(dsi_node);
+       if (!host) {
+-              dev_err(lt9611uxc->dev, "failed to find dsi host\n");
++              dev_err(dev, "failed to find dsi host\n");
+               return ERR_PTR(-EPROBE_DEFER);
+       }
+-      dsi = mipi_dsi_device_register_full(host, &info);
++      dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+       if (IS_ERR(dsi)) {
+-              dev_err(lt9611uxc->dev, "failed to create dsi device\n");
++              dev_err(dev, "failed to create dsi device\n");
+               return dsi;
+       }
+@@ -277,10 +278,9 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc,
+       dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+                         MIPI_DSI_MODE_VIDEO_HSE;
+-      ret = mipi_dsi_attach(dsi);
++      ret = devm_mipi_dsi_attach(dev, dsi);
+       if (ret < 0) {
+-              dev_err(lt9611uxc->dev, "failed to attach dsi to host\n");
+-              mipi_dsi_device_unregister(dsi);
++              dev_err(dev, "failed to attach dsi to host\n");
+               return ERR_PTR(ret);
+       }
+@@ -355,19 +355,6 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc
+       return drm_connector_attach_encoder(&lt9611uxc->connector, bridge->encoder);
+ }
+-static void lt9611uxc_bridge_detach(struct drm_bridge *bridge)
+-{
+-      struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
+-
+-      if (lt9611uxc->dsi1) {
+-              mipi_dsi_detach(lt9611uxc->dsi1);
+-              mipi_dsi_device_unregister(lt9611uxc->dsi1);
+-      }
+-
+-      mipi_dsi_detach(lt9611uxc->dsi0);
+-      mipi_dsi_device_unregister(lt9611uxc->dsi0);
+-}
+-
+ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
+                                  enum drm_bridge_attach_flags flags)
+ {
+@@ -388,19 +375,11 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
+       /* Attach secondary DSI, if specified */
+       if (lt9611uxc->dsi1_node) {
+               lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node);
+-              if (IS_ERR(lt9611uxc->dsi1)) {
+-                      ret = PTR_ERR(lt9611uxc->dsi1);
+-                      goto err_unregister_dsi0;
+-              }
++              if (IS_ERR(lt9611uxc->dsi1))
++                      return PTR_ERR(lt9611uxc->dsi1);
+       }
+       return 0;
+-
+-err_unregister_dsi0:
+-      mipi_dsi_detach(lt9611uxc->dsi0);
+-      mipi_dsi_device_unregister(lt9611uxc->dsi0);
+-
+-      return ret;
+ }
+ static enum drm_mode_status
+@@ -544,7 +523,6 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge,
+ static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = {
+       .attach = lt9611uxc_bridge_attach,
+-      .detach = lt9611uxc_bridge_detach,
+       .mode_valid = lt9611uxc_bridge_mode_valid,
+       .mode_set = lt9611uxc_bridge_mode_set,
+       .detect = lt9611uxc_bridge_detect,
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-tc358768-disable-non-continuous-clock-mod.patch b/queue-5.15/drm-bridge-tc358768-disable-non-continuous-clock-mod.patch
new file mode 100644 (file)
index 0000000..0ba3d45
--- /dev/null
@@ -0,0 +1,78 @@
+From b2d5f4025af48f6cacb05d6613566856e094ecca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Oct 2021 02:34:46 +0300
+Subject: drm/bridge: tc358768: Disable non-continuous clock mode
+
+From: Dmitry Osipenko <digetx@gmail.com>
+
+[ Upstream commit fbc5a90e82c1131869e76ce5b082693b8a75c121 ]
+
+Non-continuous clock mode doesn't work because driver doesn't support it
+properly. The bridge driver programs wrong bitfields that are required by
+the non-continuous mode (BTACNTRL1 register bitfields are swapped in the
+code), but fixing them doesn't help.
+
+Display panel of ASUS Transformer TF700T tablet supports non-continuous
+mode and display doesn't work at all using that mode. There are no
+device-trees that are actively using this DSI bridge in upstream yet,
+so clearly the broken mode wasn't ever tested properly. It's a bit too
+difficult to get LP mode working, hence let's disable the offending mode
+for now and fall back to continuous mode.
+
+Tested-by: Andreas Westman Dorcsak <hedmoo@yahoo.com> # Asus TF700T
+Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> #TF700T
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20211002233447.1105-5-digetx@gmail.com
+Stable-dep-of: 66962d5c3c51 ("drm/bridge: tc358768: Fix bit updates")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index da37dfd81a6fb..1e5304274ce20 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -637,6 +637,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+ {
+       struct tc358768_priv *priv = bridge_to_tc358768(bridge);
+       struct mipi_dsi_device *dsi_dev = priv->output.dev;
++      unsigned long mode_flags = dsi_dev->mode_flags;
+       u32 val, val2, lptxcnt, hact, data_type;
+       s32 raw_val;
+       const struct drm_display_mode *mode;
+@@ -644,6 +645,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+       u32 dsiclk, dsibclk;
+       int ret, i;
++      if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
++              dev_warn_once(priv->dev, "Non-continuous mode unimplemented, falling back to continuous\n");
++              mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS;
++      }
++
+       tc358768_hw_enable(priv);
+       ret = tc358768_sw_reset(priv);
+@@ -779,7 +785,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+               val |= BIT(i + 1);
+       tc358768_write(priv, TC358768_HSTXVREGEN, val);
+-      if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
++      if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+               tc358768_write(priv, TC358768_TXOPTIONCNTRL, 0x1);
+       /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
+@@ -836,7 +842,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+       val |= TC358768_DSI_CONTROL_TXMD;
+-      if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
++      if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+               val |= TC358768_DSI_CONTROL_HSCKMD;
+       if (dsi_dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-tc358768-fix-bit-updates.patch b/queue-5.15/drm-bridge-tc358768-fix-bit-updates.patch
new file mode 100644 (file)
index 0000000..d743ca0
--- /dev/null
@@ -0,0 +1,66 @@
+From 7692a35b9d796feffb0b88e02c0695f34ace12ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 09:50:51 +0300
+Subject: drm/bridge: tc358768: Fix bit updates
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 66962d5c3c51377b9b90cae35b7e038950438e02 ]
+
+The driver has a few places where it does:
+
+if (thing_is_enabled_in_config)
+       update_thing_bit_in_hw()
+
+This means that if the thing is _not_ enabled, the bit never gets
+cleared. This affects the h/vsyncs and continuous DSI clock bits.
+
+Fix the driver to always update the bit.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Reviewed-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T
+Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-4-31725f008a50@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 1e5304274ce20..d81c35a85330b 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -785,8 +785,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+               val |= BIT(i + 1);
+       tc358768_write(priv, TC358768_HSTXVREGEN, val);
+-      if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+-              tc358768_write(priv, TC358768_TXOPTIONCNTRL, 0x1);
++      tc358768_write(priv, TC358768_TXOPTIONCNTRL,
++                     (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0));
+       /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
+       val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
+@@ -822,11 +822,12 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
+       tc358768_write(priv, TC358768_DSI_HACT, hact);
+       /* VSYNC polarity */
+-      if (!(mode->flags & DRM_MODE_FLAG_NVSYNC))
+-              tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), BIT(5));
++      tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5),
++                           (mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIT(5) : 0);
++
+       /* HSYNC polarity */
+-      if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+-              tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), BIT(0));
++      tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0),
++                           (mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIT(0) : 0);
+       /* Start DSI Tx */
+       tc358768_write(priv, TC358768_DSI_START, 0x1);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch b/queue-5.15/drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch
new file mode 100644 (file)
index 0000000..0936acb
--- /dev/null
@@ -0,0 +1,46 @@
+From 2c1f76f09b61b3c16b1e286a8a739e2588f61aa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 09:50:49 +0300
+Subject: drm/bridge: tc358768: Fix use of uninitialized variable
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit a2d9036615f0adfa5b0a46bb2ce42ef1d9a04fbe ]
+
+smatch reports:
+
+drivers/gpu/drm/bridge/tc358768.c:223 tc358768_update_bits() error: uninitialized symbol 'orig'.
+
+Fix this by bailing out from tc358768_update_bits() if the
+tc358768_read() produces an error.
+
+Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
+Reviewed-by: Peter Ujfalusi <peter.ujfalusi@gmail.com>
+Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # Asus TF700T
+Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230906-tc358768-v4-2-31725f008a50@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358768.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
+index 8b1bdffc5005d..da37dfd81a6fb 100644
+--- a/drivers/gpu/drm/bridge/tc358768.c
++++ b/drivers/gpu/drm/bridge/tc358768.c
+@@ -217,6 +217,10 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask,
+       u32 tmp, orig;
+       tc358768_read(priv, reg, &orig);
++
++      if (priv->error)
++              return;
++
+       tmp = orig & ~mask;
+       tmp |= val & mask;
+       if (tmp != orig)
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch b/queue-5.15/drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch
new file mode 100644 (file)
index 0000000..03fa3f6
--- /dev/null
@@ -0,0 +1,47 @@
+From 61b1471f1681c392ead9e8516f865c36748d38ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 20:57:21 +0800
+Subject: drm/mediatek: Fix iommu fault by swapping FBs after updating plane
+ state
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 3ec71e05ae6e7f46512e568ed81c92be589003dd ]
+
+According to the comment in drm_atomic_helper_async_commit(),
+we should make sure FBs have been swapped, so that cleanups in the
+new_state performs a cleanup in the old FB.
+
+So we should move swapping FBs after calling mtk_plane_update_new_state(),
+to avoid using the old FB which could be freed.
+
+Fixes: 1a64a7aff8da ("drm/mediatek: Fix cursor plane no update")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230809125722.24112-2-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+index 734a1fb052dfd..eda072a3bf9ae 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+@@ -154,9 +154,9 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
+       plane->state->src_y = new_state->src_y;
+       plane->state->src_h = new_state->src_h;
+       plane->state->src_w = new_state->src_w;
+-      swap(plane->state->fb, new_state->fb);
+       mtk_plane_update_new_state(new_state, new_plane_state);
++      swap(plane->state->fb, new_state->fb);
+       wmb(); /* Make sure the above parameters are set before update */
+       new_plane_state->pending.async_dirty = true;
+       mtk_drm_crtc_async_update(new_state->crtc, plane, state);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch b/queue-5.15/drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch
new file mode 100644 (file)
index 0000000..90433b2
--- /dev/null
@@ -0,0 +1,55 @@
+From bea5db616f5d960066aceae0cf963881dab6b52b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 20:57:22 +0800
+Subject: drm/mediatek: Fix iommu fault during crtc enabling
+
+From: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 53412dc2905401207f264dc30890f6b9e41524a6 ]
+
+The difference between drm_atomic_helper_commit_tail() and
+drm_atomic_helper_commit_tail_rpm() is
+drm_atomic_helper_commit_tail() will commit plane first and
+then enable crtc, drm_atomic_helper_commit_tail_rpm() will
+enable crtc first and then commit plane.
+
+Before mediatek-drm enables crtc, the power and clk required
+by OVL have not been turned on, so the commit plane cannot be
+committed before crtc is enabled. That means OVL layer should
+not be enabled before crtc is enabled.
+Therefore, the atomic_commit_tail of mediatek-drm is hooked with
+drm_atomic_helper_commit_tail_rpm().
+
+Another reason is that the plane_state of drm_atomic_state is not
+synchronized with the plane_state stored in mtk_crtc during crtc enablng,
+so just set all planes to disabled.
+
+Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
+Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230809125722.24112-3-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index 0b93013061e6a..f2264633be1b7 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -362,6 +362,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
+               unsigned int local_layer;
+               plane_state = to_mtk_plane_state(plane->state);
++
++              /* should not enable layer before crtc enabled */
++              plane_state->pending.enable = false;
+               comp = mtk_drm_ddp_comp_for_plane(crtc, plane, &local_layer);
+               if (comp)
+                       mtk_ddp_comp_layer_config(comp, local_layer,
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch b/queue-5.15/drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch
new file mode 100644 (file)
index 0000000..2e6e853
--- /dev/null
@@ -0,0 +1,67 @@
+From 9020fdcd57d70b8d51b55548a0854f43f34607ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 12:42:34 +0200
+Subject: drm: mediatek: mtk_dsi: Fix NO_EOT_PACKET settings/handling
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 5855d422a6f250f3518f43b49092c8e87a5e42be ]
+
+Due to the initial confusion about MIPI_DSI_MODE_EOT_PACKET, properly
+renamed to MIPI_DSI_MODE_NO_EOT_PACKET, reflecting its actual meaning,
+both the DSI_TXRX_CON register setting for bit (HSTX_)DIS_EOT and the
+later calculation for horizontal sync-active (HSA), back (HBP) and
+front (HFP) porches got incorrect due to the logic being inverted.
+
+This means that a number of settings were wrong because....:
+ - DSI_TXRX_CON register setting: bit (HSTX_)DIS_EOT should be
+   set in order to disable the End of Transmission packet;
+ - Horizontal Sync and Back/Front porches: The delta used to
+   calculate all of HSA, HBP and HFP should account for the
+   additional EOT packet.
+
+Before this change...
+ - Bit (HSTX_)DIS_EOT was being set when EOT packet was enabled;
+ - For HSA/HBP/HFP delta... all three were wrong, as words were
+   added when EOT disabled, instead of when EOT packet enabled!
+
+Invert the logic around flag MIPI_DSI_MODE_NO_EOT_PACKET in the
+MediaTek DSI driver to fix the aforementioned issues.
+
+Fixes: 8b2b99fd7931 ("drm/mediatek: dsi: Fine tune the line time caused by EOTp")
+Fixes: c87d1c4b5b9a ("drm/mediatek: dsi: Use symbolized register definition")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Tested-by: Michael Walle <mwalle@kernel.org>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230523104234.7849-1-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 98b1204c92906..57eaf111b6a8a 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -406,7 +406,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
+       if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+               tmp_reg |= HSTX_CKLP_EN;
+-      if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET))
++      if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
+               tmp_reg |= DIS_EOT;
+       writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
+@@ -483,7 +483,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
+                         timing->da_hs_zero + timing->da_hs_exit + 3;
+       delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12;
+-      delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 2 : 0;
++      delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 0 : 2;
+       horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp;
+       horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte;
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-mipi-dsi-create-devm-device-attachment.patch b/queue-5.15/drm-mipi-dsi-create-devm-device-attachment.patch
new file mode 100644 (file)
index 0000000..9ae8f67
--- /dev/null
@@ -0,0 +1,89 @@
+From 48507e6d11abce4b0ad9519d5bd9dfc0518d4e68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Sep 2021 12:11:58 +0200
+Subject: drm/mipi-dsi: Create devm device attachment
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit db6568498b35a4d5d5a99420df27ed25fae31406 ]
+
+MIPI-DSI devices need to call mipi_dsi_attach() when their probe is done
+to attach against their host.
+
+However, at removal or when an error occurs, that attachment needs to be
+undone through a call to mipi_dsi_detach().
+
+Let's create a device-managed variant of the attachment function that
+will automatically detach the device at unbind.
+
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210910101218.1632297-5-maxime@cerno.tech
+Stable-dep-of: 941882a0e96d ("drm/bridge: lt8912b: Fix bridge_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dsi.c | 35 ++++++++++++++++++++++++++++++++++
+ include/drm/drm_mipi_dsi.h     |  1 +
+ 2 files changed, 36 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
+index bedbbfeab2a98..d98b08c65db93 100644
+--- a/drivers/gpu/drm/drm_mipi_dsi.c
++++ b/drivers/gpu/drm/drm_mipi_dsi.c
+@@ -392,6 +392,41 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi)
+ }
+ EXPORT_SYMBOL(mipi_dsi_detach);
++static void devm_mipi_dsi_detach(void *arg)
++{
++      struct mipi_dsi_device *dsi = arg;
++
++      mipi_dsi_detach(dsi);
++}
++
++/**
++ * devm_mipi_dsi_attach - Attach a MIPI-DSI device to its DSI Host
++ * @dev: device to tie the MIPI-DSI device attachment lifetime to
++ * @dsi: DSI peripheral
++ *
++ * This is the managed version of mipi_dsi_attach() which automatically
++ * calls mipi_dsi_detach() when @dev is unbound.
++ *
++ * Returns:
++ * 0 on success, a negative error code on failure.
++ */
++int devm_mipi_dsi_attach(struct device *dev,
++                       struct mipi_dsi_device *dsi)
++{
++      int ret;
++
++      ret = mipi_dsi_attach(dsi);
++      if (ret)
++              return ret;
++
++      ret = devm_add_action_or_reset(dev, devm_mipi_dsi_detach, dsi);
++      if (ret)
++              return ret;
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(devm_mipi_dsi_attach);
++
+ static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
+                                       struct mipi_dsi_msg *msg)
+ {
+diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
+index 5105464052704..d9af72024d66d 100644
+--- a/include/drm/drm_mipi_dsi.h
++++ b/include/drm/drm_mipi_dsi.h
+@@ -233,6 +233,7 @@ devm_mipi_dsi_device_register_full(struct device *dev, struct mipi_dsi_host *hos
+ struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
+ int mipi_dsi_attach(struct mipi_dsi_device *dsi);
+ int mipi_dsi_detach(struct mipi_dsi_device *dsi);
++int devm_mipi_dsi_attach(struct device *dev, struct mipi_dsi_device *dsi);
+ int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi);
+ int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi);
+ int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-mipi-dsi-create-devm-device-registration.patch b/queue-5.15/drm-mipi-dsi-create-devm-device-registration.patch
new file mode 100644 (file)
index 0000000..d3e378f
--- /dev/null
@@ -0,0 +1,103 @@
+From c3d566132ac0cbd3f5eec283f97b610e8a88fd11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Sep 2021 12:11:57 +0200
+Subject: drm/mipi-dsi: Create devm device registration
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit a1419fb4a73e47f0eab2985dff594ed52397471b ]
+
+Devices that take their data through the MIPI-DSI bus but are controlled
+through a secondary bus like I2C have to register a secondary device on
+the MIPI-DSI bus through the mipi_dsi_device_register_full() function.
+
+At removal or when an error occurs, that device needs to be removed
+through a call to mipi_dsi_device_unregister().
+
+Let's create a device-managed variant of the registration function that
+will automatically unregister the device at unbind.
+
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210910101218.1632297-4-maxime@cerno.tech
+Stable-dep-of: 941882a0e96d ("drm/bridge: lt8912b: Fix bridge_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dsi.c | 46 ++++++++++++++++++++++++++++++++++
+ include/drm/drm_mipi_dsi.h     |  3 +++
+ 2 files changed, 49 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
+index 0c806e99e8690..bedbbfeab2a98 100644
+--- a/drivers/gpu/drm/drm_mipi_dsi.c
++++ b/drivers/gpu/drm/drm_mipi_dsi.c
+@@ -246,6 +246,52 @@ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi)
+ }
+ EXPORT_SYMBOL(mipi_dsi_device_unregister);
++static void devm_mipi_dsi_device_unregister(void *arg)
++{
++      struct mipi_dsi_device *dsi = arg;
++
++      mipi_dsi_device_unregister(dsi);
++}
++
++/**
++ * devm_mipi_dsi_device_register_full - create a managed MIPI DSI device
++ * @dev: device to tie the MIPI-DSI device lifetime to
++ * @host: DSI host to which this device is connected
++ * @info: pointer to template containing DSI device information
++ *
++ * Create a MIPI DSI device by using the device information provided by
++ * mipi_dsi_device_info template
++ *
++ * This is the managed version of mipi_dsi_device_register_full() which
++ * automatically calls mipi_dsi_device_unregister() when @dev is
++ * unbound.
++ *
++ * Returns:
++ * A pointer to the newly created MIPI DSI device, or, a pointer encoded
++ * with an error
++ */
++struct mipi_dsi_device *
++devm_mipi_dsi_device_register_full(struct device *dev,
++                                 struct mipi_dsi_host *host,
++                                 const struct mipi_dsi_device_info *info)
++{
++      struct mipi_dsi_device *dsi;
++      int ret;
++
++      dsi = mipi_dsi_device_register_full(host, info);
++      if (IS_ERR(dsi))
++              return dsi;
++
++      ret = devm_add_action_or_reset(dev,
++                                     devm_mipi_dsi_device_unregister,
++                                     dsi);
++      if (ret)
++              return ERR_PTR(ret);
++
++      return dsi;
++}
++EXPORT_SYMBOL_GPL(devm_mipi_dsi_device_register_full);
++
+ static DEFINE_MUTEX(host_lock);
+ static LIST_HEAD(host_list);
+diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
+index 1d263eb0b2e12..5105464052704 100644
+--- a/include/drm/drm_mipi_dsi.h
++++ b/include/drm/drm_mipi_dsi.h
+@@ -227,6 +227,9 @@ struct mipi_dsi_device *
+ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
+                             const struct mipi_dsi_device_info *info);
+ void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi);
++struct mipi_dsi_device *
++devm_mipi_dsi_device_register_full(struct device *dev, struct mipi_dsi_host *host,
++                                 const struct mipi_dsi_device_info *info);
+ struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
+ int mipi_dsi_attach(struct mipi_dsi_device *dsi);
+ int mipi_dsi_detach(struct mipi_dsi_device *dsi);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch b/queue-5.15/drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch
new file mode 100644 (file)
index 0000000..ddea5c9
--- /dev/null
@@ -0,0 +1,41 @@
+From 188d674b81875a5a1bcca02e0cbf34c92729e588 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 04:29:08 +0300
+Subject: drm/msm/dsi: use msm_gem_kernel_put to free TX buffer
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 69b321b2c3df4f7e51a9de587e41f324b0b717b0 ]
+
+Use exiting function to free the allocated GEM object instead of
+open-coding it. This has a bonus of internally calling
+msm_gem_put_vaddr() to compensate for msm_gem_get_vaddr() in
+msm_get_kernel_new().
+
+Fixes: 1e29dff00400 ("drm/msm: Add a common function to free kernel buffer objects")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/562239/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index 85dec6167e0b6..8d0612caf6c21 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -1154,8 +1154,7 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
+       priv = dev->dev_private;
+       if (msm_host->tx_gem_obj) {
+-              msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace);
+-              drm_gem_object_put(msm_host->tx_gem_obj);
++              msm_gem_kernel_put(msm_host->tx_gem_obj, priv->kms->aspace);
+               msm_host->tx_gem_obj = NULL;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-radeon-possible-buffer-overflow.patch b/queue-5.15/drm-radeon-possible-buffer-overflow.patch
new file mode 100644 (file)
index 0000000..1f85c39
--- /dev/null
@@ -0,0 +1,47 @@
+From 065d07e8165b48868062d4d6e4c91bbe4597a9a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 19:33:49 +0800
+Subject: drm/radeon: possible buffer overflow
+
+From: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+
+[ Upstream commit dd05484f99d16715a88eedfca363828ef9a4c2d4 ]
+
+Buffer 'afmt_status' of size 6 could overflow, since index 'afmt_idx' is
+checked after access.
+
+Fixes: 5cc4e5fc293b ("drm/radeon: Cleanup HDMI audio interrupt handling for evergreen")
+Co-developed-by: Ivanov Mikhail <ivanov.mikhail1@huawei-partners.com>
+Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/evergreen.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
+index eeb590d2dec2e..e84596bb98f7a 100644
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -4820,14 +4820,15 @@ int evergreen_irq_process(struct radeon_device *rdev)
+                       break;
+               case 44: /* hdmi */
+                       afmt_idx = src_data;
+-                      if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
+-                              DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+-
+                       if (afmt_idx > 5) {
+                               DRM_ERROR("Unhandled interrupt: %d %d\n",
+                                         src_id, src_data);
+                               break;
+                       }
++
++                      if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
++                              DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
++
+                       afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG;
+                       queue_hdmi = true;
+                       DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1);
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch b/queue-5.15/drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch
new file mode 100644 (file)
index 0000000..97634ac
--- /dev/null
@@ -0,0 +1,60 @@
+From e449edee866e355fc4c0bc4f3679fc4e526aac99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 19:34:31 +0200
+Subject: drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 44b968d0d0868b7a9b7a5c64464ada464ff4d532 ]
+
+cdn_dp_audio_codec_init() can fail. So add some error handling.
+
+If component_add() fails, the previous cdn_dp_audio_codec_init() call
+should be undone, as already done in the remove function.
+
+Fixes: 88582f564692 ("drm/rockchip: cdn-dp: Don't unregister audio dev when unbinding")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/8494a41602fadb7439630921a9779640698f2f9f.1693676045.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/cdn-dp-core.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+index 20e63cadec8c7..b9ef35a35c857 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+@@ -1146,6 +1146,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
+       struct cdn_dp_device *dp;
+       struct extcon_dev *extcon;
+       struct phy *phy;
++      int ret;
+       int i;
+       dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+@@ -1186,9 +1187,19 @@ static int cdn_dp_probe(struct platform_device *pdev)
+       mutex_init(&dp->lock);
+       dev_set_drvdata(dev, dp);
+-      cdn_dp_audio_codec_init(dp, dev);
++      ret = cdn_dp_audio_codec_init(dp, dev);
++      if (ret)
++              return ret;
++
++      ret = component_add(dev, &cdn_dp_component_ops);
++      if (ret)
++              goto err_audio_deinit;
+-      return component_add(dev, &cdn_dp_component_ops);
++      return 0;
++
++err_audio_deinit:
++      platform_device_unregister(dp->audio_pdev);
++      return ret;
+ }
+ static int cdn_dp_remove(struct platform_device *pdev)
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch b/queue-5.15/drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch
new file mode 100644 (file)
index 0000000..9c465f8
--- /dev/null
@@ -0,0 +1,40 @@
+From 0636b7dca86cf5cfbceda917d3028d4ff66a952c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 11:01:48 +0300
+Subject: drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 6471da5ee311d53ef46eebcb7725bc94266cc0cf ]
+
+The "ret" variable is declared as ssize_t and it can hold negative error
+codes but the "rk_obj->base.size" variable is type size_t.  This means
+that when we compare them, they are both type promoted to size_t and the
+negative error code becomes a high unsigned value and is treated as
+success.  Add a cast to fix this.
+
+Fixes: 38f993b7c59e ("drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/2bfa28b5-145d-4b9e-a18a-98819dd686ce@moroto.mountain
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+index 3b18b6a7acd3e..bde358d8309c3 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+@@ -39,7 +39,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
+       ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt,
+                               prot);
+-      if (ret < rk_obj->base.size) {
++      if (ret < (ssize_t)rk_obj->base.size) {
+               DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
+                         ret, rk_obj->base.size);
+               ret = -ENOMEM;
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch b/queue-5.15/drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch
new file mode 100644 (file)
index 0000000..7a59160
--- /dev/null
@@ -0,0 +1,43 @@
+From e27ba74b2b93f483b670ff56b0e2c74eb16db249 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 22:33:20 +0000
+Subject: drm/rockchip: vop: Fix call to crtc reset helper
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 5aacd290837828c089a83ac9795c74c4c9e2c923 ]
+
+Allocation of crtc_state may fail in vop_crtc_reset, causing an invalid
+pointer to be passed to __drm_atomic_helper_crtc_reset.
+
+Fix this by adding a NULL check of crtc_state, similar to other drivers.
+
+Fixes: 01e2eaf40c9d ("drm/rockchip: Convert to using __drm_atomic_helper_crtc_reset() for reset.")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-4-jonas@kwiboo.se
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index 4bb68c058422d..e53b1ecbd7bc0 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1580,7 +1580,10 @@ static void vop_crtc_reset(struct drm_crtc *crtc)
+       if (crtc->state)
+               vop_crtc_destroy_state(crtc, crtc->state);
+-      __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
++      if (crtc_state)
++              __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
++      else
++              __drm_atomic_helper_crtc_reset(crtc, NULL);
+ }
+ #ifdef CONFIG_DRM_ANALOGIX_DP
+-- 
+2.42.0
+
diff --git a/queue-5.15/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch b/queue-5.15/drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch
new file mode 100644 (file)
index 0000000..f4b51c0
--- /dev/null
@@ -0,0 +1,42 @@
+From e3caefcd279b2e0e489933d3bf46e837aa650187 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 22:33:17 +0000
+Subject: drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 13fc28804bf10ca0b7bce3efbba95c534836d7ca ]
+
+struct rockchip_crtc_state members such as output_type, output_bpc and
+enable_afbc is always reset to zero in the atomic_duplicate_state crtc
+funcs.
+
+Fix this by using kmemdup on the subclass rockchip_crtc_state struct.
+
+Fixes: 4e257d9eee23 ("drm/rockchip: get rid of rockchip_drm_crtc_mode_config")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230621223311.2239547-2-jonas@kwiboo.se
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index cfe13b203b891..4bb68c058422d 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1554,7 +1554,8 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
+       if (WARN_ON(!crtc->state))
+               return NULL;
+-      rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
++      rockchip_state = kmemdup(to_rockchip_crtc_state(crtc->state),
++                               sizeof(*rockchip_state), GFP_KERNEL);
+       if (!rockchip_state)
+               return NULL;
+-- 
+2.42.0
+
diff --git a/queue-5.15/ext4-move-ix-sanity-check-to-corrent-position.patch b/queue-5.15/ext4-move-ix-sanity-check-to-corrent-position.patch
new file mode 100644 (file)
index 0000000..c8b570e
--- /dev/null
@@ -0,0 +1,51 @@
+From 42e0e3b8eaa789b7ac858238cfe15530b78587c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 09:33:41 +0800
+Subject: ext4: move 'ix' sanity check to corrent position
+
+From: Gou Hao <gouhao@uniontech.com>
+
+[ Upstream commit af90a8f4a09ec4a3de20142e37f37205d4687f28 ]
+
+Check 'ix' before it is used.
+
+Fixes: 80e675f906db ("ext4: optimize memmmove lengths in extent/index insertions")
+Signed-off-by: Gou Hao <gouhao@uniontech.com>
+Link: https://lore.kernel.org/r/20230906013341.7199-1-gouhao@uniontech.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/extents.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 13497bd4e14bb..592be39e3d51f 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -1004,6 +1004,11 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
+               ix = curp->p_idx;
+       }
++      if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
++              EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
++              return -EFSCORRUPTED;
++      }
++
+       len = EXT_LAST_INDEX(curp->p_hdr) - ix + 1;
+       BUG_ON(len < 0);
+       if (len > 0) {
+@@ -1013,11 +1018,6 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
+               memmove(ix + 1, ix, len * sizeof(struct ext4_extent_idx));
+       }
+-      if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
+-              EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
+-              return -EFSCORRUPTED;
+-      }
+-
+       ix->ei_block = cpu_to_le32(logical);
+       ext4_idx_store_pblock(ix, ptr);
+       le16_add_cpu(&curp->p_hdr->eh_entries, 1);
+-- 
+2.42.0
+
diff --git a/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch b/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch
new file mode 100644 (file)
index 0000000..68633c9
--- /dev/null
@@ -0,0 +1,89 @@
+From 809b2204b7fe3fa4a5a481f30f7e10fad9e2a574 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 22:04:17 +0800
+Subject: f2fs: compress: fix to avoid redundant compress extension
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 7e1b150fece033703a824df1bbc03df091ea53cc ]
+
+With below script, redundant compress extension will be parsed and added
+by parse_options(), because parse_options() doesn't check whether the
+extension is existed or not, fix it.
+
+1. mount -t f2fs -o compress_extension=so /dev/vdb /mnt/f2fs
+2. mount -t f2fs -o remount,compress_extension=so /mnt/f2fs
+3. mount|grep f2fs
+
+/dev/vdb on /mnt/f2fs type f2fs (...,compress_extension=so,compress_extension=so,...)
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Fixes: 151b1982be5d ("f2fs: compress: add nocompress extensions support")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 4b862e4a6a110..6823c09c32521 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -542,6 +542,29 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb,
+ }
+ #ifdef CONFIG_F2FS_FS_COMPRESSION
++static bool is_compress_extension_exist(struct f2fs_sb_info *sbi,
++                                      const char *new_ext, bool is_ext)
++{
++      unsigned char (*ext)[F2FS_EXTENSION_LEN];
++      int ext_cnt;
++      int i;
++
++      if (is_ext) {
++              ext = F2FS_OPTION(sbi).extensions;
++              ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
++      } else {
++              ext = F2FS_OPTION(sbi).noextensions;
++              ext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
++      }
++
++      for (i = 0; i < ext_cnt; i++) {
++              if (!strcasecmp(new_ext, ext[i]))
++                      return true;
++      }
++
++      return false;
++}
++
+ /*
+  * 1. The same extension name cannot not appear in both compress and non-compress extension
+  * at the same time.
+@@ -1156,6 +1179,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+                               return -EINVAL;
+                       }
++                      if (is_compress_extension_exist(sbi, name, true)) {
++                              kfree(name);
++                              break;
++                      }
++
+                       strcpy(ext[ext_cnt], name);
+                       F2FS_OPTION(sbi).compress_ext_cnt++;
+                       kfree(name);
+@@ -1180,6 +1208,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+                               return -EINVAL;
+                       }
++                      if (is_compress_extension_exist(sbi, name, false)) {
++                              kfree(name);
++                              break;
++                      }
++
+                       strcpy(noext[noext_cnt], name);
+                       F2FS_OPTION(sbi).nocompress_ext_cnt++;
+                       kfree(name);
+-- 
+2.42.0
+
diff --git a/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch b/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch
new file mode 100644 (file)
index 0000000..2619ab7
--- /dev/null
@@ -0,0 +1,57 @@
+From 4b3f3e8a75fee21870255ec82c982863079b7e15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 22:04:15 +0800
+Subject: f2fs: compress: fix to avoid use-after-free on dic
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit b0327c84e91a0f4f0abced8cb83ec86a7083f086 ]
+
+Call trace:
+ __memcpy+0x128/0x250
+ f2fs_read_multi_pages+0x940/0xf7c
+ f2fs_mpage_readpages+0x5a8/0x624
+ f2fs_readahead+0x5c/0x110
+ page_cache_ra_unbounded+0x1b8/0x590
+ do_sync_mmap_readahead+0x1dc/0x2e4
+ filemap_fault+0x254/0xa8c
+ f2fs_filemap_fault+0x2c/0x104
+ __do_fault+0x7c/0x238
+ do_handle_mm_fault+0x11bc/0x2d14
+ do_mem_abort+0x3a8/0x1004
+ el0_da+0x3c/0xa0
+ el0t_64_sync_handler+0xc4/0xec
+ el0t_64_sync+0x1b4/0x1b8
+
+In f2fs_read_multi_pages(), once f2fs_decompress_cluster() was called if
+we hit cached page in compress_inode's cache, dic may be released, it needs
+break the loop rather than continuing it, in order to avoid accessing
+invalid dic pointer.
+
+Fixes: 6ce19aff0b8c ("f2fs: compress: add compress_inode to cache compressed blocks")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 93c14dae4460a..7894a22c15993 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2269,8 +2269,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+               f2fs_wait_on_block_writeback(inode, blkaddr);
+               if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
+-                      if (atomic_dec_and_test(&dic->remaining_pages))
++                      if (atomic_dec_and_test(&dic->remaining_pages)) {
+                               f2fs_decompress_cluster(dic, true);
++                              break;
++                      }
+                       continue;
+               }
+-- 
+2.42.0
+
diff --git a/queue-5.15/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch b/queue-5.15/f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch
new file mode 100644 (file)
index 0000000..80bdfcc
--- /dev/null
@@ -0,0 +1,37 @@
+From 1ddef868efdb207edd5d4711d9ce2e07461e0bbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Oct 2023 15:45:52 +0800
+Subject: f2fs: fix to initialize map.m_pblk in f2fs_precache_extents()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 8b07c1fb0f1ad139373c8253f2fad8bc43fab07d ]
+
+Otherwise, it may print random physical block address in tracepoint
+of f2fs_map_blocks() as below:
+
+f2fs_map_blocks: dev = (253,16), ino = 2297, file offset = 0, start blkaddr = 0xa356c421, len = 0x0, flags = 0
+
+Fixes: c4020b2da4c9 ("f2fs: support F2FS_IOC_PRECACHE_EXTENTS")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index e1131af0396b9..58fd32db025da 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3210,6 +3210,7 @@ int f2fs_precache_extents(struct inode *inode)
+               return -EOPNOTSUPP;
+       map.m_lblk = 0;
++      map.m_pblk = 0;
+       map.m_next_pgofs = NULL;
+       map.m_next_extent = &m_next_extent;
+       map.m_seg_type = NO_CHECK_TYPE;
+-- 
+2.42.0
+
diff --git a/queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch b/queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch
new file mode 100644 (file)
index 0000000..39cddcd
--- /dev/null
@@ -0,0 +1,582 @@
+From 219e7b6fea8ca67b3a430cdbb5b53a2e98a5bad7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 12:24:37 -0700
+Subject: f2fs: handle decompress only post processing in softirq
+
+From: Daeho Jeong <daehojeong@google.com>
+
+[ Upstream commit bff139b49d9f70c1ac5384aac94554846aa834de ]
+
+Now decompression is being handled in workqueue and it makes read I/O
+latency non-deterministic, because of the non-deterministic scheduling
+nature of workqueues. So, I made it handled in softirq context only if
+possible, not in low memory devices, since this modification will
+maintain decompresion related memory a little longer.
+
+Signed-off-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: b0327c84e91a ("f2fs: compress: fix to avoid use-after-free on dic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/compress.c | 203 ++++++++++++++++++++++++++++++---------------
+ fs/f2fs/data.c     |  52 ++++++++----
+ fs/f2fs/f2fs.h     |  17 ++--
+ 3 files changed, 179 insertions(+), 93 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 455fac164fda0..3849252b1b06f 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -738,14 +738,19 @@ static int f2fs_compress_pages(struct compress_ctx *cc)
+       return ret;
+ }
+-void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
++static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
++              bool pre_alloc);
++static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,
++              bool bypass_destroy_callback, bool pre_alloc);
++
++void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task)
+ {
+       struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode);
+       struct f2fs_inode_info *fi = F2FS_I(dic->inode);
+       const struct f2fs_compress_ops *cops =
+                       f2fs_cops[fi->i_compress_algorithm];
++      bool bypass_callback = false;
+       int ret;
+-      int i;
+       trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx,
+                               dic->cluster_size, fi->i_compress_algorithm);
+@@ -755,41 +760,10 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
+               goto out_end_io;
+       }
+-      dic->tpages = page_array_alloc(dic->inode, dic->cluster_size);
+-      if (!dic->tpages) {
+-              ret = -ENOMEM;
+-              goto out_end_io;
+-      }
+-
+-      for (i = 0; i < dic->cluster_size; i++) {
+-              if (dic->rpages[i]) {
+-                      dic->tpages[i] = dic->rpages[i];
+-                      continue;
+-              }
+-
+-              dic->tpages[i] = f2fs_compress_alloc_page();
+-              if (!dic->tpages[i]) {
+-                      ret = -ENOMEM;
+-                      goto out_end_io;
+-              }
+-      }
+-
+-      if (cops->init_decompress_ctx) {
+-              ret = cops->init_decompress_ctx(dic);
+-              if (ret)
+-                      goto out_end_io;
+-      }
+-
+-      dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size);
+-      if (!dic->rbuf) {
+-              ret = -ENOMEM;
+-              goto out_destroy_decompress_ctx;
+-      }
+-
+-      dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages);
+-      if (!dic->cbuf) {
+-              ret = -ENOMEM;
+-              goto out_vunmap_rbuf;
++      ret = f2fs_prepare_decomp_mem(dic, false);
++      if (ret) {
++              bypass_callback = true;
++              goto out_release;
+       }
+       dic->clen = le32_to_cpu(dic->cbuf->clen);
+@@ -797,7 +771,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
+       if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) {
+               ret = -EFSCORRUPTED;
+-              goto out_vunmap_cbuf;
++              goto out_release;
+       }
+       ret = cops->decompress_pages(dic);
+@@ -818,17 +792,13 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
+               }
+       }
+-out_vunmap_cbuf:
+-      vm_unmap_ram(dic->cbuf, dic->nr_cpages);
+-out_vunmap_rbuf:
+-      vm_unmap_ram(dic->rbuf, dic->cluster_size);
+-out_destroy_decompress_ctx:
+-      if (cops->destroy_decompress_ctx)
+-              cops->destroy_decompress_ctx(dic);
++out_release:
++      f2fs_release_decomp_mem(dic, bypass_callback, false);
++
+ out_end_io:
+       trace_f2fs_decompress_pages_end(dic->inode, dic->cluster_idx,
+                                                       dic->clen, ret);
+-      f2fs_decompress_end_io(dic, ret);
++      f2fs_decompress_end_io(dic, ret, in_task);
+ }
+ /*
+@@ -838,7 +808,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic)
+  * (or in the case of a failure, cleans up without actually decompressing).
+  */
+ void f2fs_end_read_compressed_page(struct page *page, bool failed,
+-                                              block_t blkaddr)
++              block_t blkaddr, bool in_task)
+ {
+       struct decompress_io_ctx *dic =
+                       (struct decompress_io_ctx *)page_private(page);
+@@ -848,12 +818,12 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed,
+       if (failed)
+               WRITE_ONCE(dic->failed, true);
+-      else if (blkaddr)
++      else if (blkaddr && in_task)
+               f2fs_cache_compressed_page(sbi, page,
+                                       dic->inode->i_ino, blkaddr);
+       if (atomic_dec_and_test(&dic->remaining_pages))
+-              f2fs_decompress_cluster(dic);
++              f2fs_decompress_cluster(dic, in_task);
+ }
+ static bool is_page_in_cluster(struct compress_ctx *cc, pgoff_t index)
+@@ -1552,16 +1522,85 @@ int f2fs_write_multi_pages(struct compress_ctx *cc,
+       return err;
+ }
+-static void f2fs_free_dic(struct decompress_io_ctx *dic);
++static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi,
++              bool pre_alloc)
++{
++      return pre_alloc ^ f2fs_low_mem_mode(sbi);
++}
++
++static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic,
++              bool pre_alloc)
++{
++      const struct f2fs_compress_ops *cops =
++              f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
++      int i;
++
++      if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
++              return 0;
++
++      dic->tpages = page_array_alloc(dic->inode, dic->cluster_size);
++      if (!dic->tpages)
++              return -ENOMEM;
++
++      for (i = 0; i < dic->cluster_size; i++) {
++              if (dic->rpages[i]) {
++                      dic->tpages[i] = dic->rpages[i];
++                      continue;
++              }
++
++              dic->tpages[i] = f2fs_compress_alloc_page();
++              if (!dic->tpages[i])
++                      return -ENOMEM;
++      }
++
++      dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size);
++      if (!dic->rbuf)
++              return -ENOMEM;
++
++      dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages);
++      if (!dic->cbuf)
++              return -ENOMEM;
++
++      if (cops->init_decompress_ctx) {
++              int ret = cops->init_decompress_ctx(dic);
++
++              if (ret)
++                      return ret;
++      }
++
++      return 0;
++}
++
++static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic,
++              bool bypass_destroy_callback, bool pre_alloc)
++{
++      const struct f2fs_compress_ops *cops =
++              f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm];
++
++      if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc))
++              return;
++
++      if (!bypass_destroy_callback && cops->destroy_decompress_ctx)
++              cops->destroy_decompress_ctx(dic);
++
++      if (dic->cbuf)
++              vm_unmap_ram(dic->cbuf, dic->nr_cpages);
++
++      if (dic->rbuf)
++              vm_unmap_ram(dic->rbuf, dic->cluster_size);
++}
++
++static void f2fs_free_dic(struct decompress_io_ctx *dic,
++              bool bypass_destroy_callback);
+ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
+ {
+       struct decompress_io_ctx *dic;
+       pgoff_t start_idx = start_idx_of_cluster(cc);
+-      int i;
++      struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode);
++      int i, ret;
+-      dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO,
+-                                      false, F2FS_I_SB(cc->inode));
++      dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, false, sbi);
+       if (!dic)
+               return ERR_PTR(-ENOMEM);
+@@ -1587,32 +1626,43 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc)
+       dic->nr_rpages = cc->cluster_size;
+       dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages);
+-      if (!dic->cpages)
++      if (!dic->cpages) {
++              ret = -ENOMEM;
+               goto out_free;
++      }
+       for (i = 0; i < dic->nr_cpages; i++) {
+               struct page *page;
+               page = f2fs_compress_alloc_page();
+-              if (!page)
++              if (!page) {
++                      ret = -ENOMEM;
+                       goto out_free;
++              }
+               f2fs_set_compressed_page(page, cc->inode,
+                                       start_idx + i + 1, dic);
+               dic->cpages[i] = page;
+       }
++      ret = f2fs_prepare_decomp_mem(dic, true);
++      if (ret)
++              goto out_free;
++
+       return dic;
+ out_free:
+-      f2fs_free_dic(dic);
+-      return ERR_PTR(-ENOMEM);
++      f2fs_free_dic(dic, true);
++      return ERR_PTR(ret);
+ }
+-static void f2fs_free_dic(struct decompress_io_ctx *dic)
++static void f2fs_free_dic(struct decompress_io_ctx *dic,
++              bool bypass_destroy_callback)
+ {
+       int i;
++      f2fs_release_decomp_mem(dic, bypass_destroy_callback, true);
++
+       if (dic->tpages) {
+               for (i = 0; i < dic->cluster_size; i++) {
+                       if (dic->rpages[i])
+@@ -1637,17 +1687,33 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic)
+       kmem_cache_free(dic_entry_slab, dic);
+ }
+-static void f2fs_put_dic(struct decompress_io_ctx *dic)
++static void f2fs_late_free_dic(struct work_struct *work)
++{
++      struct decompress_io_ctx *dic =
++              container_of(work, struct decompress_io_ctx, free_work);
++
++      f2fs_free_dic(dic, false);
++}
++
++static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task)
+ {
+-      if (refcount_dec_and_test(&dic->refcnt))
+-              f2fs_free_dic(dic);
++      if (refcount_dec_and_test(&dic->refcnt)) {
++              if (in_task) {
++                      f2fs_free_dic(dic, false);
++              } else {
++                      INIT_WORK(&dic->free_work, f2fs_late_free_dic);
++                      queue_work(F2FS_I_SB(dic->inode)->post_read_wq,
++                                      &dic->free_work);
++              }
++      }
+ }
+ /*
+  * Update and unlock the cluster's pagecache pages, and release the reference to
+  * the decompress_io_ctx that was being held for I/O completion.
+  */
+-static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
++static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
++                              bool in_task)
+ {
+       int i;
+@@ -1668,7 +1734,7 @@ static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
+               unlock_page(rpage);
+       }
+-      f2fs_put_dic(dic);
++      f2fs_put_dic(dic, in_task);
+ }
+ static void f2fs_verify_cluster(struct work_struct *work)
+@@ -1685,14 +1751,15 @@ static void f2fs_verify_cluster(struct work_struct *work)
+                       SetPageError(rpage);
+       }
+-      __f2fs_decompress_end_io(dic, false);
++      __f2fs_decompress_end_io(dic, false, true);
+ }
+ /*
+  * This is called when a compressed cluster has been decompressed
+  * (or failed to be read and/or decompressed).
+  */
+-void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
++void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
++                              bool in_task)
+ {
+       if (!failed && dic->need_verity) {
+               /*
+@@ -1704,7 +1771,7 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
+               INIT_WORK(&dic->verity_work, f2fs_verify_cluster);
+               fsverity_enqueue_verify_work(&dic->verity_work);
+       } else {
+-              __f2fs_decompress_end_io(dic, failed);
++              __f2fs_decompress_end_io(dic, failed, in_task);
+       }
+ }
+@@ -1713,12 +1780,12 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed)
+  *
+  * This is called when the page is no longer needed and can be freed.
+  */
+-void f2fs_put_page_dic(struct page *page)
++void f2fs_put_page_dic(struct page *page, bool in_task)
+ {
+       struct decompress_io_ctx *dic =
+                       (struct decompress_io_ctx *)page_private(page);
+-      f2fs_put_dic(dic);
++      f2fs_put_dic(dic, in_task);
+ }
+ /*
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 3956852ad1de0..93c14dae4460a 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -120,7 +120,7 @@ struct bio_post_read_ctx {
+       block_t fs_blkaddr;
+ };
+-static void f2fs_finish_read_bio(struct bio *bio)
++static void f2fs_finish_read_bio(struct bio *bio, bool in_task)
+ {
+       struct bio_vec *bv;
+       struct bvec_iter_all iter_all;
+@@ -134,8 +134,9 @@ static void f2fs_finish_read_bio(struct bio *bio)
+               if (f2fs_is_compressed_page(page)) {
+                       if (bio->bi_status)
+-                              f2fs_end_read_compressed_page(page, true, 0);
+-                      f2fs_put_page_dic(page);
++                              f2fs_end_read_compressed_page(page, true, 0,
++                                                      in_task);
++                      f2fs_put_page_dic(page, in_task);
+                       continue;
+               }
+@@ -192,7 +193,7 @@ static void f2fs_verify_bio(struct work_struct *work)
+               fsverity_verify_bio(bio);
+       }
+-      f2fs_finish_read_bio(bio);
++      f2fs_finish_read_bio(bio, true);
+ }
+ /*
+@@ -204,7 +205,7 @@ static void f2fs_verify_bio(struct work_struct *work)
+  * can involve reading verity metadata pages from the file, and these verity
+  * metadata pages may be encrypted and/or compressed.
+  */
+-static void f2fs_verify_and_finish_bio(struct bio *bio)
++static void f2fs_verify_and_finish_bio(struct bio *bio, bool in_task)
+ {
+       struct bio_post_read_ctx *ctx = bio->bi_private;
+@@ -212,7 +213,7 @@ static void f2fs_verify_and_finish_bio(struct bio *bio)
+               INIT_WORK(&ctx->work, f2fs_verify_bio);
+               fsverity_enqueue_verify_work(&ctx->work);
+       } else {
+-              f2fs_finish_read_bio(bio);
++              f2fs_finish_read_bio(bio, in_task);
+       }
+ }
+@@ -225,7 +226,8 @@ static void f2fs_verify_and_finish_bio(struct bio *bio)
+  * that the bio includes at least one compressed page.  The actual decompression
+  * is done on a per-cluster basis, not a per-bio basis.
+  */
+-static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx)
++static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx,
++              bool in_task)
+ {
+       struct bio_vec *bv;
+       struct bvec_iter_all iter_all;
+@@ -238,7 +240,7 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx)
+               /* PG_error was set if decryption failed. */
+               if (f2fs_is_compressed_page(page))
+                       f2fs_end_read_compressed_page(page, PageError(page),
+-                                              blkaddr);
++                                              blkaddr, in_task);
+               else
+                       all_compressed = false;
+@@ -263,15 +265,16 @@ static void f2fs_post_read_work(struct work_struct *work)
+               fscrypt_decrypt_bio(ctx->bio);
+       if (ctx->enabled_steps & STEP_DECOMPRESS)
+-              f2fs_handle_step_decompress(ctx);
++              f2fs_handle_step_decompress(ctx, true);
+-      f2fs_verify_and_finish_bio(ctx->bio);
++      f2fs_verify_and_finish_bio(ctx->bio, true);
+ }
+ static void f2fs_read_end_io(struct bio *bio)
+ {
+       struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio));
+       struct bio_post_read_ctx *ctx;
++      bool intask = in_task();
+       iostat_update_and_unbind_ctx(bio, 0);
+       ctx = bio->bi_private;
+@@ -282,16 +285,29 @@ static void f2fs_read_end_io(struct bio *bio)
+       }
+       if (bio->bi_status) {
+-              f2fs_finish_read_bio(bio);
++              f2fs_finish_read_bio(bio, intask);
+               return;
+       }
+-      if (ctx && (ctx->enabled_steps & (STEP_DECRYPT | STEP_DECOMPRESS))) {
+-              INIT_WORK(&ctx->work, f2fs_post_read_work);
+-              queue_work(ctx->sbi->post_read_wq, &ctx->work);
+-      } else {
+-              f2fs_verify_and_finish_bio(bio);
++      if (ctx) {
++              unsigned int enabled_steps = ctx->enabled_steps &
++                                      (STEP_DECRYPT | STEP_DECOMPRESS);
++
++              /*
++               * If we have only decompression step between decompression and
++               * decrypt, we don't need post processing for this.
++               */
++              if (enabled_steps == STEP_DECOMPRESS &&
++                              !f2fs_low_mem_mode(sbi)) {
++                      f2fs_handle_step_decompress(ctx, intask);
++              } else if (enabled_steps) {
++                      INIT_WORK(&ctx->work, f2fs_post_read_work);
++                      queue_work(ctx->sbi->post_read_wq, &ctx->work);
++                      return;
++              }
+       }
++
++      f2fs_verify_and_finish_bio(bio, intask);
+ }
+ static void f2fs_write_end_io(struct bio *bio)
+@@ -2254,7 +2270,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+               if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
+                       if (atomic_dec_and_test(&dic->remaining_pages))
+-                              f2fs_decompress_cluster(dic);
++                              f2fs_decompress_cluster(dic, true);
+                       continue;
+               }
+@@ -2272,7 +2288,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+                                       page->index, for_write);
+                       if (IS_ERR(bio)) {
+                               ret = PTR_ERR(bio);
+-                              f2fs_decompress_end_io(dic, ret);
++                              f2fs_decompress_end_io(dic, ret, true);
+                               f2fs_put_dnode(&dn);
+                               *bio_ret = NULL;
+                               return ret;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index fb53a35f31b04..1f6b735edc4d5 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1557,6 +1557,7 @@ struct decompress_io_ctx {
+       void *private;                  /* payload buffer for specified decompression algorithm */
+       void *private2;                 /* extra payload buffer */
+       struct work_struct verity_work; /* work to verify the decompressed pages */
++      struct work_struct free_work;   /* work for late free this structure itself */
+ };
+ #define NULL_CLUSTER                  ((unsigned int)(~0))
+@@ -4058,9 +4059,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page);
+ bool f2fs_is_compress_backend_ready(struct inode *inode);
+ int f2fs_init_compress_mempool(void);
+ void f2fs_destroy_compress_mempool(void);
+-void f2fs_decompress_cluster(struct decompress_io_ctx *dic);
++void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task);
+ void f2fs_end_read_compressed_page(struct page *page, bool failed,
+-                                                      block_t blkaddr);
++                              block_t blkaddr, bool in_task);
+ bool f2fs_cluster_is_empty(struct compress_ctx *cc);
+ bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
+ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn);
+@@ -4077,8 +4078,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
+                               unsigned nr_pages, sector_t *last_block_in_bio,
+                               bool is_readahead, bool for_write);
+ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
+-void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed);
+-void f2fs_put_page_dic(struct page *page);
++void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
++                              bool in_task);
++void f2fs_put_page_dic(struct page *page, bool in_task);
+ unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn);
+ int f2fs_init_compress_ctx(struct compress_ctx *cc);
+ void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse);
+@@ -4124,13 +4126,14 @@ static inline struct page *f2fs_compress_control_page(struct page *page)
+ }
+ static inline int f2fs_init_compress_mempool(void) { return 0; }
+ static inline void f2fs_destroy_compress_mempool(void) { }
+-static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { }
++static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic,
++                              bool in_task) { }
+ static inline void f2fs_end_read_compressed_page(struct page *page,
+-                                              bool failed, block_t blkaddr)
++                              bool failed, block_t blkaddr, bool in_task)
+ {
+       WARN_ON_ONCE(1);
+ }
+-static inline void f2fs_put_page_dic(struct page *page)
++static inline void f2fs_put_page_dic(struct page *page, bool in_task)
+ {
+       WARN_ON_ONCE(1);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/f2fs-introduce-memory-mode.patch b/queue-5.15/f2fs-introduce-memory-mode.patch
new file mode 100644 (file)
index 0000000..297b88c
--- /dev/null
@@ -0,0 +1,146 @@
+From c9b88216941edab0e607dea249f4d4d0df4776c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 10:38:42 -0700
+Subject: f2fs: introduce memory mode
+
+From: Daeho Jeong <daehojeong@google.com>
+
+[ Upstream commit 7a8fc586180d8c57db5cc1e2acb32bb9986f642b ]
+
+Introduce memory mode to supports "normal" and "low" memory modes.
+"low" mode is to support low memory devices. Because of the nature of
+low memory devices, in this mode, f2fs will try to save memory sometimes
+by sacrificing performance. "normal" mode is the default mode and same
+as before.
+
+Signed-off-by: Daeho Jeong <daehojeong@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: b0327c84e91a ("f2fs: compress: fix to avoid use-after-free on dic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/filesystems/f2fs.rst |  5 +++++
+ fs/f2fs/f2fs.h                     | 13 +++++++++++++
+ fs/f2fs/super.c                    | 24 ++++++++++++++++++++++++
+ 3 files changed, 42 insertions(+)
+
+diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
+index 7fe50b0bccde9..415bba41597c3 100644
+--- a/Documentation/filesystems/f2fs.rst
++++ b/Documentation/filesystems/f2fs.rst
+@@ -323,6 +323,11 @@ discard_unit=%s            Control discard unit, the argument can be "block", "segment"
+                        default, it is helpful for large sized SMR or ZNS devices to
+                        reduce memory cost by getting rid of fs metadata supports small
+                        discard.
++memory=%s              Control memory mode. This supports "normal" and "low" modes.
++                       "low" mode is introduced to support low memory devices.
++                       Because of the nature of low memory devices, in this mode, f2fs
++                       will try to save memory sometimes by sacrificing performance.
++                       "normal" mode is the default mode and same as before.
+ ======================== ============================================================
+ Debugfs Entries
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 835ef98643bd4..fb53a35f31b04 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -142,6 +142,7 @@ struct f2fs_mount_info {
+       int fsync_mode;                 /* fsync policy */
+       int fs_mode;                    /* fs mode: LFS or ADAPTIVE */
+       int bggc_mode;                  /* bggc mode: off, on or sync */
++      int memory_mode;                /* memory mode */
+       int discard_unit;               /*
+                                        * discard command's offset/size should
+                                        * be aligned to this unit: block,
+@@ -1330,6 +1331,13 @@ enum {
+       DISCARD_UNIT_SECTION,   /* basic discard unit is section */
+ };
++enum {
++      MEMORY_MODE_NORMAL,     /* memory mode for normal devices */
++      MEMORY_MODE_LOW,        /* memory mode for low memry devices */
++};
++
++
++
+ static inline int f2fs_test_bit(unsigned int nr, char *addr);
+ static inline void f2fs_set_bit(unsigned int nr, char *addr);
+ static inline void f2fs_clear_bit(unsigned int nr, char *addr);
+@@ -4294,6 +4302,11 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
+       return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
+ }
++static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi)
++{
++      return F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW;
++}
++
+ static inline bool f2fs_may_compress(struct inode *inode)
+ {
+       if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 5c0b2b300aa1b..4b862e4a6a110 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -159,6 +159,7 @@ enum {
+       Opt_gc_merge,
+       Opt_nogc_merge,
+       Opt_discard_unit,
++      Opt_memory_mode,
+       Opt_err,
+ };
+@@ -236,6 +237,7 @@ static match_table_t f2fs_tokens = {
+       {Opt_gc_merge, "gc_merge"},
+       {Opt_nogc_merge, "nogc_merge"},
+       {Opt_discard_unit, "discard_unit=%s"},
++      {Opt_memory_mode, "memory=%s"},
+       {Opt_err, NULL},
+ };
+@@ -1241,6 +1243,22 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
+                       }
+                       kfree(name);
+                       break;
++              case Opt_memory_mode:
++                      name = match_strdup(&args[0]);
++                      if (!name)
++                              return -ENOMEM;
++                      if (!strcmp(name, "normal")) {
++                              F2FS_OPTION(sbi).memory_mode =
++                                              MEMORY_MODE_NORMAL;
++                      } else if (!strcmp(name, "low")) {
++                              F2FS_OPTION(sbi).memory_mode =
++                                              MEMORY_MODE_LOW;
++                      } else {
++                              kfree(name);
++                              return -EINVAL;
++                      }
++                      kfree(name);
++                      break;
+               default:
+                       f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value",
+                                p);
+@@ -2012,6 +2030,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
+       else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION)
+               seq_printf(seq, ",discard_unit=%s", "section");
++      if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_NORMAL)
++              seq_printf(seq, ",memory=%s", "normal");
++      else if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW)
++              seq_printf(seq, ",memory=%s", "low");
++
+       return 0;
+ }
+@@ -2034,6 +2057,7 @@ static void default_options(struct f2fs_sb_info *sbi)
+       F2FS_OPTION(sbi).compress_ext_cnt = 0;
+       F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS;
+       F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON;
++      F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL;
+       sbi->sb->s_flags &= ~SB_INLINECRYPT;
+-- 
+2.42.0
+
diff --git a/queue-5.15/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch b/queue-5.15/firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch
new file mode 100644 (file)
index 0000000..e9ee8d0
--- /dev/null
@@ -0,0 +1,70 @@
+From b9b6b78ff78fa1b883a3dda105c6ee1e6649b7a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 09:59:32 +0100
+Subject: firmware: arm_ffa: Assign the missing IDR allocation ID to the FFA
+ device
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+[ Upstream commit 7d0bc6360f17ea323ab25939a34857123d7d87e5 ]
+
+Commit 19b8766459c4 ("firmware: arm_ffa: Fix FFA device names for logical
+partitions") added an ID to the FFA device using ida_alloc() and append
+the same to "arm-ffa" to make up a unique device name. However it missed
+to stash the id value in ffa_dev to help freeing the ID later when the
+device is destroyed.
+
+Due to the missing/unassigned ID in FFA device, we get the following
+warning when the FF-A device is unregistered.
+
+  |   ida_free called for id=0 which is not allocated.
+  |   WARNING: CPU: 7 PID: 1 at lib/idr.c:525 ida_free+0x114/0x164
+  |   CPU: 7 PID: 1 Comm: swapper/0 Not tainted 6.6.0-rc4 #209
+  |   pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+  |   pc : ida_free+0x114/0x164
+  |   lr : ida_free+0x114/0x164
+  |   Call trace:
+  |    ida_free+0x114/0x164
+  |    ffa_release_device+0x24/0x3c
+  |    device_release+0x34/0x8c
+  |    kobject_put+0x94/0xf8
+  |    put_device+0x18/0x24
+  |    klist_devices_put+0x14/0x20
+  |    klist_next+0xc8/0x114
+  |    bus_for_each_dev+0xd8/0x144
+  |    arm_ffa_bus_exit+0x30/0x54
+  |    ffa_init+0x68/0x330
+  |    do_one_initcall+0xdc/0x250
+  |    do_initcall_level+0x8c/0xac
+  |    do_initcalls+0x54/0x94
+  |    do_basic_setup+0x1c/0x28
+  |    kernel_init_freeable+0x104/0x170
+  |    kernel_init+0x20/0x1a0
+  |    ret_from_fork+0x10/0x20
+
+Fix the same by actually assigning the ID in the FFA device this time
+for real.
+
+Fixes: 19b8766459c4 ("firmware: arm_ffa: Fix FFA device names for logical partitions")
+Link: https://lore.kernel.org/r/20231003085932.3553985-1-sudeep.holla@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_ffa/bus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c
+index edef31c413123..f79ba6f733ba4 100644
+--- a/drivers/firmware/arm_ffa/bus.c
++++ b/drivers/firmware/arm_ffa/bus.c
+@@ -192,6 +192,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id)
+       dev->release = ffa_release_device;
+       dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id);
++      ffa_dev->id = id;
+       ffa_dev->vm_id = vm_id;
+       uuid_copy(&ffa_dev->uuid, uuid);
+-- 
+2.42.0
+
diff --git a/queue-5.15/firmware-ti_sci-mark-driver-as-non-removable.patch b/queue-5.15/firmware-ti_sci-mark-driver-as-non-removable.patch
new file mode 100644 (file)
index 0000000..79fafdc
--- /dev/null
@@ -0,0 +1,113 @@
+From ca7ed6d47f7a09b28aa7b5cd0d0d4ab41c04591f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 14:40:26 +0530
+Subject: firmware: ti_sci: Mark driver as non removable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dhruva Gole <d-gole@ti.com>
+
+[ Upstream commit 7b7a224b1ba1703583b25a3641ad9798f34d832a ]
+
+The TI-SCI message protocol provides a way to communicate between
+various compute processors with a central system controller entity. It
+provides the fundamental device management capability and clock control
+in the SOCs that it's used in.
+
+The remove function failed to do all the necessary cleanup if
+there are registered users. Some things are freed however which
+likely results in an oops later on.
+
+Ensure that the driver isn't unbound by suppressing its bind and unbind
+sysfs attributes. As the driver is built-in there is no way to remove
+device once bound.
+
+We can also remove the ti_sci_remove call along with the
+ti_sci_debugfs_destroy as there are no callers for it any longer.
+
+Fixes: aa276781a64a ("firmware: Add basic support for TI System Control Interface (TI-SCI) protocol")
+Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Closes: https://lore.kernel.org/linux-arm-kernel/20230216083908.mvmydic5lpi3ogo7@pengutronix.de/
+Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Dhruva Gole <d-gole@ti.com>
+Link: https://lore.kernel.org/r/20230921091025.133130-1-d-gole@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/ti_sci.c | 46 +--------------------------------------
+ 1 file changed, 1 insertion(+), 45 deletions(-)
+
+diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
+index 235c7e7869aa7..c2fafe49c2e85 100644
+--- a/drivers/firmware/ti_sci.c
++++ b/drivers/firmware/ti_sci.c
+@@ -190,19 +190,6 @@ static int ti_sci_debugfs_create(struct platform_device *pdev,
+       return 0;
+ }
+-/**
+- * ti_sci_debugfs_destroy() - clean up log debug file
+- * @pdev:     platform device pointer
+- * @info:     Pointer to SCI entity information
+- */
+-static void ti_sci_debugfs_destroy(struct platform_device *pdev,
+-                                 struct ti_sci_info *info)
+-{
+-      if (IS_ERR(info->debug_region))
+-              return;
+-
+-      debugfs_remove(info->d);
+-}
+ #else /* CONFIG_DEBUG_FS */
+ static inline int ti_sci_debugfs_create(struct platform_device *dev,
+                                       struct ti_sci_info *info)
+@@ -3435,43 +3422,12 @@ static int ti_sci_probe(struct platform_device *pdev)
+       return ret;
+ }
+-static int ti_sci_remove(struct platform_device *pdev)
+-{
+-      struct ti_sci_info *info;
+-      struct device *dev = &pdev->dev;
+-      int ret = 0;
+-
+-      of_platform_depopulate(dev);
+-
+-      info = platform_get_drvdata(pdev);
+-
+-      if (info->nb.notifier_call)
+-              unregister_restart_handler(&info->nb);
+-
+-      mutex_lock(&ti_sci_list_mutex);
+-      if (info->users)
+-              ret = -EBUSY;
+-      else
+-              list_del(&info->node);
+-      mutex_unlock(&ti_sci_list_mutex);
+-
+-      if (!ret) {
+-              ti_sci_debugfs_destroy(pdev, info);
+-
+-              /* Safe to free channels since no more users */
+-              mbox_free_channel(info->chan_tx);
+-              mbox_free_channel(info->chan_rx);
+-      }
+-
+-      return ret;
+-}
+-
+ static struct platform_driver ti_sci_driver = {
+       .probe = ti_sci_probe,
+-      .remove = ti_sci_remove,
+       .driver = {
+                  .name = "ti-sci",
+                  .of_match_table = of_match_ptr(ti_sci_of_match),
++                 .suppress_bind_attrs = true,
+       },
+ };
+ module_platform_driver(ti_sci_driver);
+-- 
+2.42.0
+
diff --git a/queue-5.15/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch b/queue-5.15/futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch
new file mode 100644 (file)
index 0000000..1623136
--- /dev/null
@@ -0,0 +1,62 @@
+From 4301f30ac42a567a4911a36ab8318851b5868d00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Oct 2023 16:45:49 -0400
+Subject: futex: Don't include process MM in futex key on no-MMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+
+[ Upstream commit c73801ae4f22b390228ebf471d55668e824198b6 ]
+
+On no-MMU, all futexes are treated as private because there is no need
+to map a virtual address to physical to match the futex across
+processes. This doesn't quite work though, because private futexes
+include the current process's mm_struct as part of their key. This makes
+it impossible for one process to wake up a shared futex being waited on
+in another process.
+
+Fix this bug by excluding the mm_struct from the key. With
+a single address space, the futex address is already a unique key.
+
+Fixes: 784bdf3bb694 ("futex: Assume all mappings are private on !MMU systems")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Darren Hart <dvhart@infradead.org>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: André Almeida <andrealmeid@igalia.com>
+Link: https://lore.kernel.org/r/20231019204548.1236437-2-ben.wolsieffer@hefring.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/futex/core.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/futex/core.c b/kernel/futex/core.c
+index 764e73622b386..d42245170a7a0 100644
+--- a/kernel/futex/core.c
++++ b/kernel/futex/core.c
+@@ -570,7 +570,17 @@ static int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key,
+        *        but access_ok() should be faster than find_vma()
+        */
+       if (!fshared) {
+-              key->private.mm = mm;
++              /*
++               * On no-MMU, shared futexes are treated as private, therefore
++               * we must not include the current process in the key. Since
++               * there is only one address space, the address is a unique key
++               * on its own.
++               */
++              if (IS_ENABLED(CONFIG_MMU))
++                      key->private.mm = mm;
++              else
++                      key->private.mm = NULL;
++
+               key->private.address = address;
+               return 0;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch b/queue-5.15/genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch
new file mode 100644 (file)
index 0000000..6d0ab57
--- /dev/null
@@ -0,0 +1,73 @@
+From 6c60c61136951810bd21dc1124499ead1d83f2e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 15:25:22 +0800
+Subject: genirq/matrix: Exclude managed interrupts in irq_matrix_allocated()
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+[ Upstream commit a0b0bad10587ae2948a7c36ca4ffc206007fbcf3 ]
+
+When a CPU is about to be offlined, x86 validates that all active
+interrupts which are targeted to this CPU can be migrated to the remaining
+online CPUs. If not, the offline operation is aborted.
+
+The validation uses irq_matrix_allocated() to retrieve the number of
+vectors which are allocated on the outgoing CPU. The returned number of
+allocated vectors includes also vectors which are associated to managed
+interrupts.
+
+That's overaccounting because managed interrupts are:
+
+  - not migrated when the affinity mask of the interrupt targets only
+    the outgoing CPU
+
+  - migrated to another CPU, but in that case the vector is already
+    pre-allocated on the potential target CPUs and must not be taken into
+    account.
+
+As a consequence the check whether the remaining online CPUs have enough
+capacity for migrating the allocated vectors from the outgoing CPU might
+fail incorrectly.
+
+Let irq_matrix_allocated() return only the number of allocated non-managed
+interrupts to make this validation check correct.
+
+[ tglx: Amend changelog and fixup kernel-doc comment ]
+
+Fixes: 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator")
+Reported-by: Wendy Wang <wendy.wang@intel.com>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20231020072522.557846-1-yu.c.chen@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/matrix.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
+index bbfb26489aa1c..f9467637eab65 100644
+--- a/kernel/irq/matrix.c
++++ b/kernel/irq/matrix.c
+@@ -466,16 +466,16 @@ unsigned int irq_matrix_reserved(struct irq_matrix *m)
+ }
+ /**
+- * irq_matrix_allocated - Get the number of allocated irqs on the local cpu
++ * irq_matrix_allocated - Get the number of allocated non-managed irqs on the local CPU
+  * @m:                Pointer to the matrix to search
+  *
+- * This returns number of allocated irqs
++ * This returns number of allocated non-managed interrupts.
+  */
+ unsigned int irq_matrix_allocated(struct irq_matrix *m)
+ {
+       struct cpumap *cm = this_cpu_ptr(m->maps);
+-      return cm->allocated;
++      return cm->allocated - cm->managed_allocated;
+ }
+ #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
+-- 
+2.42.0
+
diff --git a/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch b/queue-5.15/gpio-add-helpers-to-ease-the-transition-towards-immu.patch
new file mode 100644 (file)
index 0000000..8e2045f
--- /dev/null
@@ -0,0 +1,54 @@
+From 0043afef0d43ad2bc0e3da4bc8d4b7abc4f87a19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:39 +0100
+Subject: gpio: Add helpers to ease the transition towards immutable irq_chip
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 36b78aae4bfee749bbde73be570796bfd0f56bec ]
+
+Add a couple of new helpers to make it slightly simpler to convert
+drivers to immutable irq_chip structures:
+
+- GPIOCHIP_IRQ_RESOURCE_HELPERS populates the irq_chip structure
+  with the resource management callbacks
+
+- gpio_irq_chip_set_chip() populates the gpio_irq_chip.chip
+  structure, avoiding the proliferation of ugly casts
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-4-maz@kernel.org
+Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/gpio/driver.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index b241fc23ff3a2..91f60d1e3eb31 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -599,6 +599,18 @@ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
+ int gpiochip_irq_reqres(struct irq_data *data);
+ void gpiochip_irq_relres(struct irq_data *data);
++/* Paste this in your irq_chip structure  */
++#define       GPIOCHIP_IRQ_RESOURCE_HELPERS                                   \
++              .irq_request_resources  = gpiochip_irq_reqres,          \
++              .irq_release_resources  = gpiochip_irq_relres
++
++static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq,
++                                        const struct irq_chip *chip)
++{
++      /* Yes, dropping const is ugly, but it isn't like we have a choice */
++      girq->chip = (struct irq_chip *)chip;
++}
++
+ /* Line status inquiry for drivers */
+ bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
+ bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
+-- 
+2.42.0
+
diff --git a/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch b/queue-5.15/gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch
new file mode 100644 (file)
index 0000000..5f254b4
--- /dev/null
@@ -0,0 +1,89 @@
+From 67223eb1b98579c9464871d1938a5924fe06e220 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:37 +0100
+Subject: gpio: Don't fiddle with irqchips marked as immutable
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 6c846d026d490b2383d395bc8e7b06336219667b ]
+
+In order to move away from gpiolib messing with the internals of
+unsuspecting irqchips, add a flag by which irqchips advertise
+that they are not to be messed with, and do solemnly swear that
+they correctly call into the gpiolib helpers when required.
+
+Also nudge the users into converting their drivers to the
+new model.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-2-maz@kernel.org
+Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib.c | 7 ++++++-
+ include/linux/irq.h    | 2 ++
+ kernel/irq/debugfs.c   | 1 +
+ 3 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index f9fdd117c654c..e572c30a202ad 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1483,6 +1483,11 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
+ {
+       struct irq_chip *irqchip = gc->irq.chip;
++      if (irqchip->flags & IRQCHIP_IMMUTABLE)
++              return;
++
++      chip_warn(gc, "not an immutable chip, please consider fixing it!\n");
++
+       if (!irqchip->irq_request_resources &&
+           !irqchip->irq_release_resources) {
+               irqchip->irq_request_resources = gpiochip_irq_reqres;
+@@ -1650,7 +1655,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc)
+               irq_domain_remove(gc->irq.domain);
+       }
+-      if (irqchip) {
++      if (irqchip && !(irqchip->flags & IRQCHIP_IMMUTABLE)) {
+               if (irqchip->irq_request_resources == gpiochip_irq_reqres) {
+                       irqchip->irq_request_resources = NULL;
+                       irqchip->irq_release_resources = NULL;
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index f9e6449fbbbae..296ef3b7d7afa 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -570,6 +570,7 @@ struct irq_chip {
+  * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND:  Invokes __enable_irq()/__disable_irq() for wake irqs
+  *                                    in the suspend path if they are in disabled state
+  * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
++ * IRQCHIP_IMMUTABLE:               Don't ever change anything in this chip
+  */
+ enum {
+       IRQCHIP_SET_TYPE_MASKED                 = (1 <<  0),
+@@ -583,6 +584,7 @@ enum {
+       IRQCHIP_SUPPORTS_NMI                    = (1 <<  8),
+       IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND        = (1 <<  9),
+       IRQCHIP_AFFINITY_PRE_STARTUP            = (1 << 10),
++      IRQCHIP_IMMUTABLE                       = (1 << 11),
+ };
+ #include <linux/irqdesc.h>
+diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c
+index e4cff358b437e..7ff52d94b42c0 100644
+--- a/kernel/irq/debugfs.c
++++ b/kernel/irq/debugfs.c
+@@ -58,6 +58,7 @@ static const struct irq_bit_descr irqchip_flags[] = {
+       BIT_MASK_DESCR(IRQCHIP_SUPPORTS_LEVEL_MSI),
+       BIT_MASK_DESCR(IRQCHIP_SUPPORTS_NMI),
+       BIT_MASK_DESCR(IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND),
++      BIT_MASK_DESCR(IRQCHIP_IMMUTABLE),
+ };
+ static void
+-- 
+2.42.0
+
diff --git a/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch b/queue-5.15/gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch
new file mode 100644 (file)
index 0000000..2e10a54
--- /dev/null
@@ -0,0 +1,70 @@
+From bf522c0ca975b2c9887f891c4124f72f6e7c7b27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 15:18:38 +0100
+Subject: gpio: Expose the gpiochip_irq_re[ql]res helpers
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 704f08753b6dcd0e08c1953af0b2c7f3fac87111 ]
+
+The GPIO subsystem has a couple of internal helpers to manage
+resources on behalf of the irqchip. Expose them so that GPIO
+drivers can use them directly.
+
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220419141846.598305-3-maz@kernel.org
+Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib.c      | 6 ++++--
+ include/linux/gpio/driver.h | 4 ++++
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index e572c30a202ad..57e726d65904b 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1431,19 +1431,21 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset)
+       return irq_create_mapping(domain, offset);
+ }
+-static int gpiochip_irq_reqres(struct irq_data *d)
++int gpiochip_irq_reqres(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       return gpiochip_reqres_irq(gc, d->hwirq);
+ }
++EXPORT_SYMBOL(gpiochip_irq_reqres);
+-static void gpiochip_irq_relres(struct irq_data *d)
++void gpiochip_irq_relres(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       gpiochip_relres_irq(gc, d->hwirq);
+ }
++EXPORT_SYMBOL(gpiochip_irq_relres);
+ static void gpiochip_irq_mask(struct irq_data *d)
+ {
+diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
+index 65df2ce96f0b1..b241fc23ff3a2 100644
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -595,6 +595,10 @@ void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset);
+ void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset);
+ void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
++/* irq_data versions of the above */
++int gpiochip_irq_reqres(struct irq_data *data);
++void gpiochip_irq_relres(struct irq_data *data);
++
+ /* Line status inquiry for drivers */
+ bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
+ bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
+-- 
+2.42.0
+
diff --git a/queue-5.15/gve-use-size_add-in-call-to-struct_size.patch b/queue-5.15/gve-use-size_add-in-call-to-struct_size.patch
new file mode 100644 (file)
index 0000000..fc28d2b
--- /dev/null
@@ -0,0 +1,38 @@
+From 0471a02340208d9d614db6fadd193daadaa4b742 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 12:17:49 -0600
+Subject: gve: Use size_add() in call to struct_size()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit d692873cbe861a870cdc9cbfb120eefd113c3dfd ]
+
+If, for any reason, `tx_stats_num + rx_stats_num` wraps around, the
+protection that struct_size() adds against potential integer overflows
+is defeated. Fix this by hardening call to struct_size() with size_add().
+
+Fixes: 691f4077d560 ("gve: Replace zero-length array with flexible-array member")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/google/gve/gve_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
+index c0ea1b185e1bd..4327d66878976 100644
+--- a/drivers/net/ethernet/google/gve/gve_main.c
++++ b/drivers/net/ethernet/google/gve/gve_main.c
+@@ -139,7 +139,7 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
+       rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
+                      priv->rx_cfg.num_queues;
+       priv->stats_report_len = struct_size(priv->stats_report, stats,
+-                                           tx_stats_num + rx_stats_num);
++                                           size_add(tx_stats_num, rx_stats_num));
+       priv->stats_report =
+               dma_alloc_coherent(&priv->pdev->dev, priv->stats_report_len,
+                                  &priv->stats_report_bus, GFP_KERNEL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-cp2112-fix-duplicate-workqueue-initialization.patch b/queue-5.15/hid-cp2112-fix-duplicate-workqueue-initialization.patch
new file mode 100644 (file)
index 0000000..c9ecd6e
--- /dev/null
@@ -0,0 +1,50 @@
+From de9f97b2e2f67cccc8e942bfc7652a4206f8a2fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 16:22:45 -0500
+Subject: hid: cp2112: Fix duplicate workqueue initialization
+
+From: Danny Kaehn <danny.kaehn@plexus.com>
+
+[ Upstream commit e3c2d2d144c082dd71596953193adf9891491f42 ]
+
+Previously the cp2112 driver called INIT_DELAYED_WORK within
+cp2112_gpio_irq_startup, resulting in duplicate initilizations of the
+workqueue on subsequent IRQ startups following an initial request. This
+resulted in a warning in set_work_data in workqueue.c, as well as a rare
+NULL dereference within process_one_work in workqueue.c.
+
+Initialize the workqueue within _probe instead.
+
+Fixes: 13de9cca514e ("HID: cp2112: add IRQ chip handling")
+Signed-off-by: Danny Kaehn <danny.kaehn@plexus.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-cp2112.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
+index d902fe43cb818..a683d38200267 100644
+--- a/drivers/hid/hid-cp2112.c
++++ b/drivers/hid/hid-cp2112.c
+@@ -1157,8 +1157,6 @@ static unsigned int cp2112_gpio_irq_startup(struct irq_data *d)
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct cp2112_device *dev = gpiochip_get_data(gc);
+-      INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback);
+-
+       if (!dev->gpio_poll) {
+               dev->gpio_poll = true;
+               schedule_delayed_work(&dev->gpio_poll_worker, 0);
+@@ -1354,6 +1352,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       girq->handler = handle_simple_irq;
+       girq->threaded = true;
++      INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback);
++
+       ret = gpiochip_add_data(&dev->gc, dev);
+       if (ret < 0) {
+               hid_err(hdev, "error registering gpio chip\n");
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch b/queue-5.15/hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch
new file mode 100644 (file)
index 0000000..bb3b140
--- /dev/null
@@ -0,0 +1,48 @@
+From 71e783cfea753e5f37131882afbd29500d1d365e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 13:23:17 -0500
+Subject: hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip
+
+From: Danny Kaehn <danny.kaehn@plexus.com>
+
+[ Upstream commit dc3115e6c5d9863ec1a9ff1acf004ede93c34361 ]
+
+Previously cp2112_gpio_irq_shutdown() always cancelled the
+gpio_poll_worker, even if other IRQs were still active, and did not set
+the gpio_poll flag to false. This resulted in any call to _shutdown()
+resulting in interrupts no longer functioning on the chip until a
+_remove() occurred (a.e. the cp2112 is unplugged or system rebooted).
+
+Only cancel polling if all IRQs are disabled/masked, and correctly set
+the gpio_poll flag, allowing polling to restart when an interrupt is
+next enabled.
+
+Signed-off-by: Danny Kaehn <danny.kaehn@plexus.com>
+Fixes: 13de9cca514e ("HID: cp2112: add IRQ chip handling")
+Link: https://lore.kernel.org/r/20231011182317.1053344-1-danny.kaehn@plexus.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-cp2112.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
+index 704aebb1a588f..ee983ddc7fd03 100644
+--- a/drivers/hid/hid-cp2112.c
++++ b/drivers/hid/hid-cp2112.c
+@@ -1175,7 +1175,11 @@ static void cp2112_gpio_irq_shutdown(struct irq_data *d)
+       struct cp2112_device *dev = gpiochip_get_data(gc);
+       cp2112_gpio_irq_mask(d);
+-      cancel_delayed_work_sync(&dev->gpio_poll_worker);
++
++      if (!dev->irq_mask) {
++              dev->gpio_poll = false;
++              cancel_delayed_work_sync(&dev->gpio_poll_worker);
++      }
+ }
+ static int cp2112_gpio_irq_type(struct irq_data *d, unsigned int type)
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-cp2112-make-irq_chip-immutable.patch b/queue-5.15/hid-cp2112-make-irq_chip-immutable.patch
new file mode 100644 (file)
index 0000000..8da7c53
--- /dev/null
@@ -0,0 +1,109 @@
+From 197afd0c04462b3f50de1aa00415135c7dc26f77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 21:52:13 +0300
+Subject: HID: cp2112: Make irq_chip immutable
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 3e2977c425ad2789ca18084fff913cceacae75a2 ]
+
+Since recently, the kernel is nagging about mutable irq_chips:
+
+   "not an immutable chip, please consider fixing it!"
+
+Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new
+helper functions and call the appropriate gpiolib functions.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230703185222.50554-4-andriy.shevchenko@linux.intel.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Stable-dep-of: dc3115e6c5d9 ("hid: cp2112: Fix IRQ shutdown stopping polling for all IRQs on chip")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-cp2112.c | 33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
+index a683d38200267..704aebb1a588f 100644
+--- a/drivers/hid/hid-cp2112.c
++++ b/drivers/hid/hid-cp2112.c
+@@ -161,7 +161,6 @@ struct cp2112_device {
+       atomic_t read_avail;
+       atomic_t xfer_avail;
+       struct gpio_chip gc;
+-      struct irq_chip irq;
+       u8 *in_out_buffer;
+       struct mutex lock;
+@@ -1078,16 +1077,20 @@ static void cp2112_gpio_irq_mask(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct cp2112_device *dev = gpiochip_get_data(gc);
++      irq_hw_number_t hwirq = irqd_to_hwirq(d);
+-      __clear_bit(d->hwirq, &dev->irq_mask);
++      __clear_bit(hwirq, &dev->irq_mask);
++      gpiochip_disable_irq(gc, hwirq);
+ }
+ static void cp2112_gpio_irq_unmask(struct irq_data *d)
+ {
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct cp2112_device *dev = gpiochip_get_data(gc);
++      irq_hw_number_t hwirq = irqd_to_hwirq(d);
+-      __set_bit(d->hwirq, &dev->irq_mask);
++      gpiochip_enable_irq(gc, hwirq);
++      __set_bit(hwirq, &dev->irq_mask);
+ }
+ static void cp2112_gpio_poll_callback(struct work_struct *work)
+@@ -1171,6 +1174,7 @@ static void cp2112_gpio_irq_shutdown(struct irq_data *d)
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct cp2112_device *dev = gpiochip_get_data(gc);
++      cp2112_gpio_irq_mask(d);
+       cancel_delayed_work_sync(&dev->gpio_poll_worker);
+ }
+@@ -1224,6 +1228,18 @@ static int __maybe_unused cp2112_allocate_irq(struct cp2112_device *dev,
+       return ret;
+ }
++static const struct irq_chip cp2112_gpio_irqchip = {
++      .name = "cp2112-gpio",
++      .irq_startup = cp2112_gpio_irq_startup,
++      .irq_shutdown = cp2112_gpio_irq_shutdown,
++      .irq_ack = cp2112_gpio_irq_ack,
++      .irq_mask = cp2112_gpio_irq_mask,
++      .irq_unmask = cp2112_gpio_irq_unmask,
++      .irq_set_type = cp2112_gpio_irq_type,
++      .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
++      GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
+ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ {
+       struct cp2112_device *dev;
+@@ -1333,17 +1349,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       dev->gc.can_sleep               = 1;
+       dev->gc.parent                  = &hdev->dev;
+-      dev->irq.name = "cp2112-gpio";
+-      dev->irq.irq_startup = cp2112_gpio_irq_startup;
+-      dev->irq.irq_shutdown = cp2112_gpio_irq_shutdown;
+-      dev->irq.irq_ack = cp2112_gpio_irq_ack;
+-      dev->irq.irq_mask = cp2112_gpio_irq_mask;
+-      dev->irq.irq_unmask = cp2112_gpio_irq_unmask;
+-      dev->irq.irq_set_type = cp2112_gpio_irq_type;
+-      dev->irq.flags = IRQCHIP_MASK_ON_SUSPEND;
+-
+       girq = &dev->gc.irq;
+-      girq->chip = &dev->irq;
++      gpio_irq_chip_set_chip(girq, &cp2112_gpio_irqchip);
+       /* The event comes from the outside so no parent handler */
+       girq->parent_handler = NULL;
+       girq->num_parents = 0;
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch b/queue-5.15/hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch
new file mode 100644 (file)
index 0000000..a377200
--- /dev/null
@@ -0,0 +1,119 @@
+From e320737df23de27f8e34d4a963b88d45934b31b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 12:20:18 +0200
+Subject: HID: logitech-hidpp: Don't restart IO, instead defer hid_connect()
+ only
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 11ca0322a41920df2b462d2e45b0731e47ff475b ]
+
+Restarting IO causes 2 problems:
+
+1. Some devices do not like IO being restarted this was addressed in
+   commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication
+   if not necessary"), but that change has issues of its own and needs to
+   be reverted.
+
+2. Restarting IO and specifically calling hid_device_io_stop() causes
+   received packets to be missed, which may cause connect-events to
+   get missed.
+
+Restarting IO was introduced in commit 91cf9a98ae41 ("HID: logitech-hidpp:
+make .probe usbhid capable") to allow to retrieve the device's name and
+serial number and store these in hdev->name and hdev->uniq before
+connecting any hid subdrivers (hid-input, hidraw) exporting this info
+to userspace.
+
+But this does not require restarting IO, this merely requires deferring
+calling hid_connect(). Calling hid_hw_start() with a connect-mask of
+0 makes it skip calling hid_connect(), so hidpp_probe() can simply call
+hid_connect() later without needing to restart IO.
+
+Remove the stop + restart of IO and instead just call hid_connect() later
+to avoid the issues caused by restarting IO.
+
+Now that IO is no longer stopped, hid_hw_close() must be called at the end
+of probe() to balance the hid_hw_open() done at the beginning probe().
+
+This series has been tested on the following devices:
+Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
+Logitech M720 Triathlon (bluetooth, HID++ 4.5)
+Logitech M720 Triathlon (unifying, HID++ 4.5)
+Logitech K400 Pro (unifying, HID++ 4.1)
+Logitech K270 (eQUAD nano Lite, HID++ 2.0)
+Logitech M185 (eQUAD nano Lite, HID++ 4.5)
+Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
+Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)
+
+And by bentiss:
+Logitech Touchpad T650 (unifying)
+Logitech Touchpad T651 (bluetooth)
+Logitech MX Master 3B (BLE)
+Logitech G403 (plain USB / Gaming receiver)
+
+Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary")
+Suggested-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231010102029.111003-2-hdegoede@redhat.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index a716c6f3bfb58..907f45dfef4c1 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4155,8 +4155,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+                        hdev->name);
+       /*
+-       * Plain USB connections need to actually call start and open
+-       * on the transport driver to allow incoming data.
++       * First call hid_hw_start(hdev, 0) to allow IO without connecting any
++       * hid subdrivers (hid-input, hidraw). This allows retrieving the dev's
++       * name and serial number and store these in hdev->name and hdev->uniq,
++       * before the hid-input and hidraw drivers expose these to userspace.
+        */
+       ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask);
+       if (ret) {
+@@ -4214,19 +4216,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       flush_work(&hidpp->work);
+       if (will_restart) {
+-              /* Reset the HID node state */
+-              hid_device_io_stop(hdev);
+-              hid_hw_close(hdev);
+-              hid_hw_stop(hdev);
+-
+               if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
+                       connect_mask &= ~HID_CONNECT_HIDINPUT;
+               /* Now export the actual inputs and hidraw nodes to the world */
+-              ret = hid_hw_start(hdev, connect_mask);
++              ret = hid_connect(hdev, connect_mask);
+               if (ret) {
+-                      hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
+-                      goto hid_hw_start_fail;
++                      hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret);
++                      goto hid_hw_init_fail;
+               }
+       }
+@@ -4238,6 +4235,11 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+                                ret);
+       }
++      /*
++       * This relies on logi_dj_ll_close() being a no-op so that DJ connection
++       * events will still be received.
++       */
++      hid_hw_close(hdev);
+       return ret;
+ hid_hw_init_fail:
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch b/queue-5.15/hid-logitech-hidpp-move-get_wireless_feature_index-c.patch
new file mode 100644 (file)
index 0000000..6c9a774
--- /dev/null
@@ -0,0 +1,98 @@
+From 10eaf8f72122eafdf4d0f32b633c7a2a002128ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 12:20:20 +0200
+Subject: HID: logitech-hidpp: Move get_wireless_feature_index() check to
+ hidpp_connect_event()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ba9de350509504fb748837b71e23d7e84c83d93c ]
+
+Calling get_wireless_feature_index() from probe() causes
+the wireless_feature_index to only get set for unifying devices which
+are already connected at probe() time. It does not get set for devices
+which connect later.
+
+Fix this by moving get_wireless_feature_index() to hidpp_connect_event(),
+this does not make a difference for devices connected at probe() since
+probe() will queue the hidpp_connect_event() for those at probe time.
+
+This series has been tested on the following devices:
+Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
+Logitech M720 Triathlon (bluetooth, HID++ 4.5)
+Logitech M720 Triathlon (unifying, HID++ 4.5)
+Logitech K400 Pro (unifying, HID++ 4.1)
+Logitech K270 (eQUAD nano Lite, HID++ 2.0)
+Logitech M185 (eQUAD nano Lite, HID++ 4.5)
+Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
+Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)
+
+And by bentiss:
+Logitech Touchpad T650 (unifying)
+Logitech Touchpad T651 (bluetooth)
+Logitech MX Master 3B (BLE)
+Logitech G403 (plain USB / Gaming receiver)
+
+Fixes: 0da0a63b7cba ("HID: logitech-hidpp: Support WirelessDeviceStatus connect events")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231010102029.111003-4-hdegoede@redhat.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index f7d6927f95076..fb287c4cbd5b8 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -1753,15 +1753,14 @@ static int hidpp_battery_get_property(struct power_supply *psy,
+ /* -------------------------------------------------------------------------- */
+ #define HIDPP_PAGE_WIRELESS_DEVICE_STATUS                     0x1d4b
+-static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp)
++static int hidpp_get_wireless_feature_index(struct hidpp_device *hidpp, u8 *feature_index)
+ {
+       u8 feature_type;
+       int ret;
+       ret = hidpp_root_get_feature(hidpp,
+                                    HIDPP_PAGE_WIRELESS_DEVICE_STATUS,
+-                                   &hidpp->wireless_feature_index,
+-                                   &feature_type);
++                                   feature_index, &feature_type);
+       return ret;
+ }
+@@ -3950,6 +3949,13 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
+               }
+       }
++      if (hidpp->protocol_major >= 2) {
++              u8 feature_index;
++
++              if (!hidpp_get_wireless_feature_index(hidpp, &feature_index))
++                      hidpp->wireless_feature_index = feature_index;
++      }
++
+       if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) {
+               name = hidpp_get_device_name(hidpp);
+               if (name) {
+@@ -4188,14 +4194,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+               hidpp_overwrite_name(hdev);
+       }
+-      if (connected && hidpp->protocol_major >= 2) {
+-              ret = hidpp_set_wireless_feature_index(hidpp);
+-              if (ret == -ENOENT)
+-                      hidpp->wireless_feature_index = 0;
+-              else if (ret)
+-                      goto hid_hw_init_fail;
+-      }
+-
+       if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
+               ret = wtp_get_config(hidpp);
+               if (ret)
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-logitech-hidpp-remove-hidpp_quirk_no_hidinput-qu.patch b/queue-5.15/hid-logitech-hidpp-remove-hidpp_quirk_no_hidinput-qu.patch
new file mode 100644 (file)
index 0000000..1d266b2
--- /dev/null
@@ -0,0 +1,69 @@
+From cd57c30374e05dd788412acea0c6e92ccc9aeb65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Jan 2023 13:17:23 +0100
+Subject: HID: logitech-hidpp: Remove HIDPP_QUIRK_NO_HIDINPUT quirk
+
+From: Bastien Nocera <hadess@hadess.net>
+
+[ Upstream commit d83956c8855c6c2ed4bd16cec4a5083d63df17e4 ]
+
+HIDPP_QUIRK_NO_HIDINPUT isn't used by any devices but still happens to
+work as HIDPP_QUIRK_DELAYED_INIT is defined to the same value. Remove
+HIDPP_QUIRK_NO_HIDINPUT and use HIDPP_QUIRK_DELAYED_INIT everywhere
+instead.
+
+Tested on a T650 which requires that quirk, and a number of unifying and
+Bluetooth devices that don't.
+
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Link: https://lore.kernel.org/r/20230125121723.3122-2-hadess@hadess.net
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Stable-dep-of: 11ca0322a419 ("HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 7681a3fa67dab..a716c6f3bfb58 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -63,7 +63,7 @@ MODULE_PARM_DESC(disable_tap_to_click,
+ /* bits 2..20 are reserved for classes */
+ /* #define HIDPP_QUIRK_CONNECT_EVENTS         BIT(21) disabled */
+ #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS      BIT(22)
+-#define HIDPP_QUIRK_NO_HIDINPUT                       BIT(23)
++#define HIDPP_QUIRK_DELAYED_INIT              BIT(23)
+ #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS      BIT(24)
+ #define HIDPP_QUIRK_UNIFYING                  BIT(25)
+ #define HIDPP_QUIRK_HI_RES_SCROLL_1P0         BIT(26)
+@@ -82,8 +82,6 @@ MODULE_PARM_DESC(disable_tap_to_click,
+                                        HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
+                                        HIDPP_QUIRK_HI_RES_SCROLL_X2121)
+-#define HIDPP_QUIRK_DELAYED_INIT              HIDPP_QUIRK_NO_HIDINPUT
+-
+ #define HIDPP_CAPABILITY_HIDPP10_BATTERY      BIT(0)
+ #define HIDPP_CAPABILITY_HIDPP20_BATTERY      BIT(1)
+ #define HIDPP_CAPABILITY_BATTERY_MILEAGE      BIT(2)
+@@ -3988,7 +3986,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
+       if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
+               hi_res_scroll_enable(hidpp);
+-      if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
++      if (!(hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) || hidpp->delayed_input)
+               /* if the input nodes are already created, we can stop now */
+               return;
+@@ -4221,7 +4219,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+               hid_hw_close(hdev);
+               hid_hw_stop(hdev);
+-              if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
++              if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
+                       connect_mask &= ~HID_CONNECT_HIDINPUT;
+               /* Now export the actual inputs and hidraw nodes to the world */
+-- 
+2.42.0
+
diff --git a/queue-5.15/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch b/queue-5.15/hid-logitech-hidpp-revert-don-t-restart-communicatio.patch
new file mode 100644 (file)
index 0000000..fa12975
--- /dev/null
@@ -0,0 +1,129 @@
+From 9c18aadf637a853cf129e072614cb02ec81764b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 12:20:19 +0200
+Subject: HID: logitech-hidpp: Revert "Don't restart communication if not
+ necessary"
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 55bf70362ffc4ddd7c8745e2fe880edac00e4aff ]
+
+Commit 91cf9a98ae41 ("HID: logitech-hidpp: make .probe usbhid capable")
+makes hidpp_probe() first call hid_hw_start(hdev, 0) to allow IO
+without connecting any hid subdrivers (hid-input, hidraw).
+
+This is done to allow to retrieve the device's name and serial number
+and store these in hdev->name and hdev->uniq.
+
+Then later on IO was stopped and started again with hid_hw_start(hdev,
+HID_CONNECT_DEFAULT) connecting hid-input and hidraw after the name
+and serial number have been setup.
+
+Commit 498ba2069035 ("HID: logitech-hidpp: Don't restart communication
+if not necessary") changed the probe() code to only do the start with
+a 0 connect-mask + restart later for unifying devices.
+
+But for non unifying devices hdev->name and hdev->uniq are updated too.
+So this change re-introduces the problem for which the start with
+a 0 connect-mask + restart later behavior was introduced.
+
+The previous patch in this series changes the unifying path to instead of
+restarting IO only call hid_connect() later. This avoids possible issues
+with restarting IO seen on non unifying devices.
+
+Revert the change to limit the restart behavior to unifying devices to
+fix hdev->name changing after userspace facing devices have already been
+registered.
+
+This series has been tested on the following devices:
+Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
+Logitech M720 Triathlon (bluetooth, HID++ 4.5)
+Logitech M720 Triathlon (unifying, HID++ 4.5)
+Logitech K400 Pro (unifying, HID++ 4.1)
+Logitech K270 (eQUAD nano Lite, HID++ 2.0)
+Logitech M185 (eQUAD nano Lite, HID++ 4.5)
+Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
+Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)
+
+And by bentiss:
+Logitech Touchpad T650 (unifying)
+Logitech Touchpad T651 (bluetooth)
+Logitech MX Master 3B (BLE)
+Logitech G403 (plain USB / Gaming receiver)
+
+Fixes: 498ba2069035 ("HID: logitech-hidpp: Don't restart communication if not necessary")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231010102029.111003-3-hdegoede@redhat.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 24 ++++++++----------------
+ 1 file changed, 8 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 907f45dfef4c1..f7d6927f95076 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4089,7 +4089,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       bool connected;
+       unsigned int connect_mask = HID_CONNECT_DEFAULT;
+       struct hidpp_ff_private_data data;
+-      bool will_restart = false;
+       /* report_fixup needs drvdata to be set before we call hid_parse */
+       hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
+@@ -4140,10 +4139,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+                       return ret;
+       }
+-      if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT ||
+-          hidpp->quirks & HIDPP_QUIRK_UNIFYING)
+-              will_restart = true;
+-
+       INIT_WORK(&hidpp->work, delayed_work_cb);
+       mutex_init(&hidpp->send_mutex);
+       init_waitqueue_head(&hidpp->wait);
+@@ -4160,7 +4155,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+        * name and serial number and store these in hdev->name and hdev->uniq,
+        * before the hid-input and hidraw drivers expose these to userspace.
+        */
+-      ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask);
++      ret = hid_hw_start(hdev, 0);
+       if (ret) {
+               hid_err(hdev, "hw start failed\n");
+               goto hid_hw_start_fail;
+@@ -4199,7 +4194,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+                       hidpp->wireless_feature_index = 0;
+               else if (ret)
+                       goto hid_hw_init_fail;
+-              ret = 0;
+       }
+       if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
+@@ -4215,16 +4209,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+       schedule_work(&hidpp->work);
+       flush_work(&hidpp->work);
+-      if (will_restart) {
+-              if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
+-                      connect_mask &= ~HID_CONNECT_HIDINPUT;
++      if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT)
++              connect_mask &= ~HID_CONNECT_HIDINPUT;
+-              /* Now export the actual inputs and hidraw nodes to the world */
+-              ret = hid_connect(hdev, connect_mask);
+-              if (ret) {
+-                      hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret);
+-                      goto hid_hw_init_fail;
+-              }
++      /* Now export the actual inputs and hidraw nodes to the world */
++      ret = hid_connect(hdev, connect_mask);
++      if (ret) {
++              hid_err(hdev, "%s:hid_connect returned error %d\n", __func__, ret);
++              goto hid_hw_init_fail;
+       }
+       if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch b/queue-5.15/hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch
new file mode 100644 (file)
index 0000000..314383b
--- /dev/null
@@ -0,0 +1,74 @@
+From 2df8169ee4c9d11efdb3b3b4c4a85afb921775a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Oct 2023 15:21:00 +0200
+Subject: hwmon: (axi-fan-control) Fix possible NULL pointer dereference
+
+From: Dragos Bogdan <dragos.bogdan@analog.com>
+
+[ Upstream commit 2a5b3370a1d9750eca325292e291c8c7cb8cf2e0 ]
+
+axi_fan_control_irq_handler(), dependent on the private
+axi_fan_control_data structure, might be called before the hwmon
+device is registered. That will cause an "Unable to handle kernel
+NULL pointer dereference" error.
+
+Fixes: 8412b410fa5e ("hwmon: Support ADI Fan Control IP")
+Signed-off-by: Dragos Bogdan <dragos.bogdan@analog.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20231025132100.649499-1-nuno.sa@analog.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/axi-fan-control.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hwmon/axi-fan-control.c b/drivers/hwmon/axi-fan-control.c
+index d2092c17d9935..7af18018a32ff 100644
+--- a/drivers/hwmon/axi-fan-control.c
++++ b/drivers/hwmon/axi-fan-control.c
+@@ -508,6 +508,21 @@ static int axi_fan_control_probe(struct platform_device *pdev)
+               return -ENODEV;
+       }
++      ret = axi_fan_control_init(ctl, pdev->dev.of_node);
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to initialize device\n");
++              return ret;
++      }
++
++      ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev,
++                                                       name,
++                                                       ctl,
++                                                       &axi_chip_info,
++                                                       axi_fan_control_groups);
++
++      if (IS_ERR(ctl->hdev))
++              return PTR_ERR(ctl->hdev);
++
+       ctl->irq = platform_get_irq(pdev, 0);
+       if (ctl->irq < 0)
+               return ctl->irq;
+@@ -521,19 +536,7 @@ static int axi_fan_control_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      ret = axi_fan_control_init(ctl, pdev->dev.of_node);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Failed to initialize device\n");
+-              return ret;
+-      }
+-
+-      ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev,
+-                                                       name,
+-                                                       ctl,
+-                                                       &axi_chip_info,
+-                                                       axi_fan_control_groups);
+-
+-      return PTR_ERR_OR_ZERO(ctl->hdev);
++      return 0;
+ }
+ static struct platform_driver axi_fan_control_driver = {
+-- 
+2.42.0
+
diff --git a/queue-5.15/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch b/queue-5.15/hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch
new file mode 100644 (file)
index 0000000..f72ecec
--- /dev/null
@@ -0,0 +1,59 @@
+From 5a7a3bc9892d481822a86b391bf8e981fec489a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Oct 2023 20:23:16 +0800
+Subject: hwmon: (coretemp) Fix potentially truncated sysfs attribute name
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+[ Upstream commit bbfff736d30e5283ad09e748caff979d75ddef7f ]
+
+When build with W=1 and "-Werror=format-truncation", below error is
+observed in coretemp driver,
+
+   drivers/hwmon/coretemp.c: In function 'create_core_data':
+>> drivers/hwmon/coretemp.c:393:34: error: '%s' directive output may be truncated writing likely 5 or more bytes into a region of size between 3 and 13 [-Werror=format-truncation=]
+     393 |                          "temp%d_%s", attr_no, suffixes[i]);
+         |                                  ^~
+   drivers/hwmon/coretemp.c:393:26: note: assuming directive output of 5 bytes
+     393 |                          "temp%d_%s", attr_no, suffixes[i]);
+         |                          ^~~~~~~~~~~
+   drivers/hwmon/coretemp.c:392:17: note: 'snprintf' output 7 or more bytes (assuming 22) into a destination of size 19
+     392 |                 snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH,
+         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+     393 |                          "temp%d_%s", attr_no, suffixes[i]);
+         |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+   cc1: all warnings being treated as errors
+
+Given that
+1. '%d' could take 10 charactors,
+2. '%s' could take 10 charactors ("crit_alarm"),
+3. "temp", "_" and the NULL terminator take 6 charactors,
+fix the problem by increasing CORETEMP_NAME_LENGTH to 28.
+
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Fixes: 7108b80a542b ("hwmon/coretemp: Handle large core ID value")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202310200443.iD3tUbbK-lkp@intel.com/
+Link: https://lore.kernel.org/r/20231025122316.836400-1-rui.zhang@intel.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/coretemp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index eaae5de2ab616..5b2057ce5a59d 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -41,7 +41,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
+ #define PKG_SYSFS_ATTR_NO     1       /* Sysfs attribute for package temp */
+ #define BASE_SYSFS_ATTR_NO    2       /* Sysfs Base attr no for coretemp */
+ #define NUM_REAL_CORES                128     /* Number of Real cores per cpu */
+-#define CORETEMP_NAME_LENGTH  19      /* String Length of attrs */
++#define CORETEMP_NAME_LENGTH  28      /* String Length of attrs */
+ #define MAX_CORE_ATTRS                4       /* Maximum no of basic attrs */
+ #define TOTAL_ATTRS           (MAX_CORE_ATTRS + 1)
+ #define MAX_CORE_DATA         (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
+-- 
+2.42.0
+
diff --git a/queue-5.15/hwrng-geode-fix-accessing-registers.patch b/queue-5.15/hwrng-geode-fix-accessing-registers.patch
new file mode 100644 (file)
index 0000000..598db89
--- /dev/null
@@ -0,0 +1,58 @@
+From 72cd0a15f2c92c0c6afe1967f85fcb9f935caf8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Sep 2023 10:34:17 +0200
+Subject: hwrng: geode - fix accessing registers
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+[ Upstream commit 464bd8ec2f06707f3773676a1bd2c64832a3c805 ]
+
+When the membase and pci_dev pointer were moved to a new struct in priv,
+the actual membase users were left untouched, and they started reading
+out arbitrary memory behind the struct instead of registers. This
+unfortunately turned the RNG into a constant number generator, depending
+on the content of what was at that offset.
+
+To fix this, update geode_rng_data_{read,present}() to also get the
+membase via amd_geode_priv, and properly read from the right addresses
+again.
+
+Fixes: 9f6ec8dc574e ("hwrng: geode - Fix PCI device refcount leak")
+Reported-by: Timur I. Davletshin <timur.davletshin@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217882
+Tested-by: Timur I. Davletshin <timur.davletshin@gmail.com>
+Suggested-by: Jo-Philipp Wich <jo@mein.io>
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/hw_random/geode-rng.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
+index 12fbe80918319..159baf00a8675 100644
+--- a/drivers/char/hw_random/geode-rng.c
++++ b/drivers/char/hw_random/geode-rng.c
+@@ -58,7 +58,8 @@ struct amd_geode_priv {
+ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+ {
+-      void __iomem *mem = (void __iomem *)rng->priv;
++      struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv;
++      void __iomem *mem = priv->membase;
+       *data = readl(mem + GEODE_RNG_DATA_REG);
+@@ -67,7 +68,8 @@ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+ static int geode_rng_data_present(struct hwrng *rng, int wait)
+ {
+-      void __iomem *mem = (void __iomem *)rng->priv;
++      struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv;
++      void __iomem *mem = priv->membase;
+       int data, i;
+       for (i = 0; i < 20; i++) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch b/queue-5.15/i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch
new file mode 100644 (file)
index 0000000..483f643
--- /dev/null
@@ -0,0 +1,41 @@
+From e9563cdcebb4f51aedeebcc83f88dcb5269f72c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 16:24:10 +0800
+Subject: i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit cab63f64887616e3c4e31cfd8103320be6ebc8d3 ]
+
+put_device() needs to be called on failure of device_register()
+to give up the reference initialized in it to avoid refcount leak.
+
+Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230921082410.25548-1-dinghao.liu@zju.edu.cn
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
+index dfe18dcd008d4..b6abbb0acbbd3 100644
+--- a/drivers/i3c/master.c
++++ b/drivers/i3c/master.c
+@@ -1506,9 +1506,11 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
+                       desc->dev->dev.of_node = desc->boardinfo->of_node;
+               ret = device_register(&desc->dev->dev);
+-              if (ret)
++              if (ret) {
+                       dev_err(&master->dev,
+                               "Failed to add I3C device (err = %d)\n", ret);
++                      put_device(&desc->dev->dev);
++              }
+       }
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/i40e-fix-potential-memory-leaks-in-i40e_remove.patch b/queue-5.15/i40e-fix-potential-memory-leaks-in-i40e_remove.patch
new file mode 100644 (file)
index 0000000..9dfe7e7
--- /dev/null
@@ -0,0 +1,50 @@
+From 9ccc3bc6ed5f19fc4710e77aef42458aa86e3444 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 14:42:01 +0200
+Subject: i40e: fix potential memory leaks in i40e_remove()
+
+From: Andrii Staikov <andrii.staikov@intel.com>
+
+[ Upstream commit 5ca636d927a106780451d957734f02589b972e2b ]
+
+Instead of freeing memory of a single VSI, make sure
+the memory for all VSIs is cleared before releasing VSIs.
+Add releasing of their resources in a loop with the iteration
+number equal to the number of allocated VSIs.
+
+Fixes: 41c445ff0f48 ("i40e: main driver core")
+Signed-off-by: Andrii Staikov <andrii.staikov@intel.com>
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 539bb69548f23..20e26aa5b81c8 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -16258,11 +16258,15 @@ static void i40e_remove(struct pci_dev *pdev)
+                       i40e_switch_branch_release(pf->veb[i]);
+       }
+-      /* Now we can shutdown the PF's VSI, just before we kill
++      /* Now we can shutdown the PF's VSIs, just before we kill
+        * adminq and hmc.
+        */
+-      if (pf->vsi[pf->lan_vsi])
+-              i40e_vsi_release(pf->vsi[pf->lan_vsi]);
++      for (i = pf->num_alloc_vsi; i--;)
++              if (pf->vsi[i]) {
++                      i40e_vsi_close(pf->vsi[i]);
++                      i40e_vsi_release(pf->vsi[i]);
++                      pf->vsi[i] = NULL;
++              }
+       i40e_cloud_filter_exit(pf);
+-- 
+2.42.0
+
diff --git a/queue-5.15/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch b/queue-5.15/ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch
new file mode 100644 (file)
index 0000000..b0e3fcb
--- /dev/null
@@ -0,0 +1,76 @@
+From 8123f0dfb81bf6bfa34216ef662a4f938ea8cb27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 13:41:20 +0300
+Subject: IB/mlx5: Fix rdma counter binding for RAW QP
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit c1336bb4aa5e809a622a87d74311275514086596 ]
+
+Previously when we had a RAW QP, we bound a counter to it when it moved
+to INIT state, using the counter context inside RQC.
+
+But when we try to modify that counter later in RTS state we used
+modify QP which tries to change the counter inside QPC instead of RQC.
+
+Now we correctly modify the counter set_id inside of RQC instead of QPC
+for the RAW QP.
+
+Fixes: d14133dd4161 ("IB/mlx5: Support set qp counter")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Mark Zhang <markzhang@nvidia.com>
+Link: https://lore.kernel.org/r/2e5ab6713784a8fe997d19c508187a0dfecf2dfc.1696847964.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/qp.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 1080daf3a546f..d4b5ce37c2cbd 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -3955,6 +3955,30 @@ static unsigned int get_tx_affinity(struct ib_qp *qp,
+       return tx_affinity;
+ }
++static int __mlx5_ib_qp_set_raw_qp_counter(struct mlx5_ib_qp *qp, u32 set_id,
++                                         struct mlx5_core_dev *mdev)
++{
++      struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
++      struct mlx5_ib_rq *rq = &raw_packet_qp->rq;
++      u32 in[MLX5_ST_SZ_DW(modify_rq_in)] = {};
++      void *rqc;
++
++      if (!qp->rq.wqe_cnt)
++              return 0;
++
++      MLX5_SET(modify_rq_in, in, rq_state, rq->state);
++      MLX5_SET(modify_rq_in, in, uid, to_mpd(qp->ibqp.pd)->uid);
++
++      rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
++      MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);
++
++      MLX5_SET64(modify_rq_in, in, modify_bitmask,
++                 MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID);
++      MLX5_SET(rqc, rqc, counter_set_id, set_id);
++
++      return mlx5_core_modify_rq(mdev, rq->base.mqp.qpn, in);
++}
++
+ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,
+                                   struct rdma_counter *counter)
+ {
+@@ -3970,6 +3994,9 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,
+       else
+               set_id = mlx5_ib_get_counters_id(dev, mqp->port - 1);
++      if (mqp->type == IB_QPT_RAW_PACKET)
++              return __mlx5_ib_qp_set_raw_qp_counter(mqp, set_id, dev->mdev);
++
+       base = &mqp->trans_qp.base;
+       MLX5_SET(rts2rts_qp_in, in, opcode, MLX5_CMD_OP_RTS2RTS_QP);
+       MLX5_SET(rts2rts_qp_in, in, qpn, base->mqp.qpn);
+-- 
+2.42.0
+
diff --git a/queue-5.15/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch b/queue-5.15/iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch
new file mode 100644 (file)
index 0000000..5b92934
--- /dev/null
@@ -0,0 +1,90 @@
+From e92523621671328b093c0835e5693a6f920c3f77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 13:02:59 +0100
+Subject: iov_iter, x86: Be consistent about the __user tag on
+ copy_mc_to_user()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 066baf92bed934c9fb4bcee97a193f47aa63431c ]
+
+copy_mc_to_user() has the destination marked __user on powerpc, but not on
+x86; the latter results in a sparse warning in lib/iov_iter.c.
+
+Fix this by applying the tag on x86 too.
+
+Fixes: ec6347bb4339 ("x86, powerpc: Rename memcpy_mcsafe() to copy_mc_to_{user, kernel}()")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/r/20230925120309.1731676-3-dhowells@redhat.com
+cc: Dan Williams <dan.j.williams@intel.com>
+cc: Thomas Gleixner <tglx@linutronix.de>
+cc: Ingo Molnar <mingo@redhat.com>
+cc: Borislav Petkov <bp@alien8.de>
+cc: Dave Hansen <dave.hansen@linux.intel.com>
+cc: "H. Peter Anvin" <hpa@zytor.com>
+cc: Alexander Viro <viro@zeniv.linux.org.uk>
+cc: Jens Axboe <axboe@kernel.dk>
+cc: Christoph Hellwig <hch@lst.de>
+cc: Christian Brauner <christian@brauner.io>
+cc: Matthew Wilcox <willy@infradead.org>
+cc: Linus Torvalds <torvalds@linux-foundation.org>
+cc: David Laight <David.Laight@ACULAB.COM>
+cc: x86@kernel.org
+cc: linux-block@vger.kernel.org
+cc: linux-fsdevel@vger.kernel.org
+cc: linux-mm@kvack.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/uaccess.h | 2 +-
+ arch/x86/lib/copy_mc.c         | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
+index ab5e577373093..3616fd4ba3953 100644
+--- a/arch/x86/include/asm/uaccess.h
++++ b/arch/x86/include/asm/uaccess.h
+@@ -543,7 +543,7 @@ copy_mc_to_kernel(void *to, const void *from, unsigned len);
+ #define copy_mc_to_kernel copy_mc_to_kernel
+ unsigned long __must_check
+-copy_mc_to_user(void *to, const void *from, unsigned len);
++copy_mc_to_user(void __user *to, const void *from, unsigned len);
+ #endif
+ /*
+diff --git a/arch/x86/lib/copy_mc.c b/arch/x86/lib/copy_mc.c
+index 80efd45a77617..6e8b7e600def5 100644
+--- a/arch/x86/lib/copy_mc.c
++++ b/arch/x86/lib/copy_mc.c
+@@ -70,23 +70,23 @@ unsigned long __must_check copy_mc_to_kernel(void *dst, const void *src, unsigne
+ }
+ EXPORT_SYMBOL_GPL(copy_mc_to_kernel);
+-unsigned long __must_check copy_mc_to_user(void *dst, const void *src, unsigned len)
++unsigned long __must_check copy_mc_to_user(void __user *dst, const void *src, unsigned len)
+ {
+       unsigned long ret;
+       if (copy_mc_fragile_enabled) {
+               __uaccess_begin();
+-              ret = copy_mc_fragile(dst, src, len);
++              ret = copy_mc_fragile((__force void *)dst, src, len);
+               __uaccess_end();
+               return ret;
+       }
+       if (static_cpu_has(X86_FEATURE_ERMS)) {
+               __uaccess_begin();
+-              ret = copy_mc_enhanced_fast_string(dst, src, len);
++              ret = copy_mc_enhanced_fast_string((__force void *)dst, src, len);
+               __uaccess_end();
+               return ret;
+       }
+-      return copy_user_generic(dst, src, len);
++      return copy_user_generic((__force void *)dst, src, len);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/ipv6-avoid-atomic-fragment-on-gso-packets.patch b/queue-5.15/ipv6-avoid-atomic-fragment-on-gso-packets.patch
new file mode 100644 (file)
index 0000000..7a11937
--- /dev/null
@@ -0,0 +1,54 @@
+From b1b2a0fb684cbeeca74f27767135240a722cccba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 07:26:40 -0700
+Subject: ipv6: avoid atomic fragment on GSO packets
+
+From: Yan Zhai <yan@cloudflare.com>
+
+[ Upstream commit 03d6c848bfb406e9ef6d9846d759e97beaeea113 ]
+
+When the ipv6 stack output a GSO packet, if its gso_size is larger than
+dst MTU, then all segments would be fragmented. However, it is possible
+for a GSO packet to have a trailing segment with smaller actual size
+than both gso_size as well as the MTU, which leads to an "atomic
+fragment". Atomic fragments are considered harmful in RFC-8021. An
+Existing report from APNIC also shows that atomic fragments are more
+likely to be dropped even it is equivalent to a no-op [1].
+
+Add an extra check in the GSO slow output path. For each segment from
+the original over-sized packet, if it fits with the path MTU, then avoid
+generating an atomic fragment.
+
+Link: https://www.potaroo.net/presentations/2022-03-01-ipv6-frag.pdf [1]
+Fixes: b210de4f8c97 ("net: ipv6: Validate GSO SKB before finish IPv6 processing")
+Reported-by: David Wragg <dwragg@cloudflare.com>
+Signed-off-by: Yan Zhai <yan@cloudflare.com>
+Link: https://lore.kernel.org/r/90912e3503a242dca0bc36958b11ed03a2696e5e.1698156966.git.yan@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_output.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 2207acd7108c1..5045b479c2a95 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -159,7 +159,13 @@ ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk,
+               int err;
+               skb_mark_not_on_list(segs);
+-              err = ip6_fragment(net, sk, segs, ip6_finish_output2);
++              /* Last GSO segment can be smaller than gso_size (and MTU).
++               * Adding a fragment header would produce an "atomic fragment",
++               * which is considered harmful (RFC-8021). Avoid that.
++               */
++              err = segs->len > mtu ?
++                      ip6_fragment(net, sk, segs, ip6_finish_output2) :
++                      ip6_finish_output2(net, sk, segs);
+               if (err && ret == 0)
+                       ret = err;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/ipvlan-properly-track-tx_errors.patch b/queue-5.15/ipvlan-properly-track-tx_errors.patch
new file mode 100644 (file)
index 0000000..8d7503e
--- /dev/null
@@ -0,0 +1,81 @@
+From a9eb562c8273dd550a00f55bca46a57141fab486 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 13:14:46 +0000
+Subject: ipvlan: properly track tx_errors
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ff672b9ffeb3f82135488ac16c5c5eb4b992999b ]
+
+Both ipvlan_process_v4_outbound() and ipvlan_process_v6_outbound()
+increment dev->stats.tx_errors in case of errors.
+
+Unfortunately there are two issues :
+
+1) ipvlan_get_stats64() does not propagate dev->stats.tx_errors to user.
+
+2) Increments are not atomic. KCSAN would complain eventually.
+
+Use DEV_STATS_INC() to not miss an update, and change ipvlan_get_stats64()
+to copy the value back to user.
+
+Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Mahesh Bandewar <maheshb@google.com>
+Link: https://lore.kernel.org/r/20231026131446.3933175-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ipvlan/ipvlan_core.c | 8 ++++----
+ drivers/net/ipvlan/ipvlan_main.c | 1 +
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
+index e10cb98b0f4f5..905542df3b682 100644
+--- a/drivers/net/ipvlan/ipvlan_core.c
++++ b/drivers/net/ipvlan/ipvlan_core.c
+@@ -442,12 +442,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
+       err = ip_local_out(net, skb->sk, skb);
+       if (unlikely(net_xmit_eval(err)))
+-              dev->stats.tx_errors++;
++              DEV_STATS_INC(dev, tx_errors);
+       else
+               ret = NET_XMIT_SUCCESS;
+       goto out;
+ err:
+-      dev->stats.tx_errors++;
++      DEV_STATS_INC(dev, tx_errors);
+       kfree_skb(skb);
+ out:
+       return ret;
+@@ -483,12 +483,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
+       err = ip6_local_out(net, skb->sk, skb);
+       if (unlikely(net_xmit_eval(err)))
+-              dev->stats.tx_errors++;
++              DEV_STATS_INC(dev, tx_errors);
+       else
+               ret = NET_XMIT_SUCCESS;
+       goto out;
+ err:
+-      dev->stats.tx_errors++;
++      DEV_STATS_INC(dev, tx_errors);
+       kfree_skb(skb);
+ out:
+       return ret;
+diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
+index c199f0b465cd0..8660d452f642b 100644
+--- a/drivers/net/ipvlan/ipvlan_main.c
++++ b/drivers/net/ipvlan/ipvlan_main.c
+@@ -324,6 +324,7 @@ static void ipvlan_get_stats64(struct net_device *dev,
+               s->rx_dropped = rx_errs;
+               s->tx_dropped = tx_drps;
+       }
++      s->tx_errors = DEV_STATS_READ(dev, tx_errors);
+ }
+ static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
+-- 
+2.42.0
+
diff --git a/queue-5.15/iwlwifi-pcie-adjust-to-bz-completion-descriptor.patch b/queue-5.15/iwlwifi-pcie-adjust-to-bz-completion-descriptor.patch
new file mode 100644 (file)
index 0000000..2588a4b
--- /dev/null
@@ -0,0 +1,193 @@
+From f93cdbebdd96bfbffd89a9a8437af95f66acc337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 12:25:04 +0200
+Subject: iwlwifi: pcie: adjust to Bz completion descriptor
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 5d19e2087fea28651eff7eadf4510fa1564688a2 ]
+
+The Bz devices got a new completion descriptor again since
+we only ever really used 4 out of 32 bytes anyway. Adjust
+the code to deal with that. Note that the intention was to
+reduce the size, but the hardware was implemented wrongly.
+
+While at it, do some cleanups and remove the union to simplify
+the code, clean up iwl_pcie_free_bd_size() to no longer need
+an argument and add iwl_pcie_used_bd_size() with the logic to
+selct completion descriptor size.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20220204122220.bef461a04110.I90c8885550fa54eb0aaa4363d322f50e301175a6@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Stable-dep-of: 37fb29bd1f90 ("wifi: iwlwifi: pcie: synchronize IRQs before NAPI")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/intel/iwlwifi/pcie/internal.h    | 20 +++++--
+ drivers/net/wireless/intel/iwlwifi/pcie/rx.c  | 56 ++++++++++++-------
+ 2 files changed, 51 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+index 6dce36d326935..775ee03e5b128 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+ /*
+- * Copyright (C) 2003-2015, 2018-2021 Intel Corporation
++ * Copyright (C) 2003-2015, 2018-2022 Intel Corporation
+  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+  * Copyright (C) 2016-2017 Intel Deutschland GmbH
+  */
+@@ -103,6 +103,18 @@ struct iwl_rx_completion_desc {
+       u8 reserved2[25];
+ } __packed;
++/**
++ * struct iwl_rx_completion_desc_bz - Bz completion descriptor
++ * @rbid: unique tag of the received buffer
++ * @flags: flags (0: fragmented, all others: reserved)
++ * @reserved: reserved
++ */
++struct iwl_rx_completion_desc_bz {
++      __le16 rbid;
++      u8 flags;
++      u8 reserved[1];
++} __packed;
++
+ /**
+  * struct iwl_rxq - Rx queue
+  * @id: queue index
+@@ -133,11 +145,7 @@ struct iwl_rxq {
+       int id;
+       void *bd;
+       dma_addr_t bd_dma;
+-      union {
+-              void *used_bd;
+-              __le32 *bd_32;
+-              struct iwl_rx_completion_desc *cd;
+-      };
++      void *used_bd;
+       dma_addr_t used_bd_dma;
+       u32 read;
+       u32 write;
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+index f82fb17450165..74b4280221e0f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2003-2014, 2018-2021 Intel Corporation
++ * Copyright (C) 2003-2014, 2018-2022 Intel Corporation
+  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+  * Copyright (C) 2016-2017 Intel Deutschland GmbH
+  */
+@@ -652,23 +652,30 @@ void iwl_pcie_rx_allocator_work(struct work_struct *data)
+       iwl_pcie_rx_allocator(trans_pcie->trans);
+ }
+-static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td)
++static int iwl_pcie_free_bd_size(struct iwl_trans *trans)
+ {
+-      struct iwl_rx_transfer_desc *rx_td;
++      if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
++              return sizeof(struct iwl_rx_transfer_desc);
+-      if (use_rx_td)
+-              return sizeof(*rx_td);
+-      else
+-              return trans->trans_cfg->mq_rx_supported ? sizeof(__le64) :
+-                      sizeof(__le32);
++      return trans->trans_cfg->mq_rx_supported ?
++                      sizeof(__le64) : sizeof(__le32);
++}
++
++static int iwl_pcie_used_bd_size(struct iwl_trans *trans)
++{
++      if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
++              return sizeof(struct iwl_rx_completion_desc_bz);
++
++      if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
++              return sizeof(struct iwl_rx_completion_desc);
++
++      return sizeof(__le32);
+ }
+ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
+                                 struct iwl_rxq *rxq)
+ {
+-      bool use_rx_td = (trans->trans_cfg->device_family >=
+-                        IWL_DEVICE_FAMILY_AX210);
+-      int free_size = iwl_pcie_free_bd_size(trans, use_rx_td);
++      int free_size = iwl_pcie_free_bd_size(trans);
+       if (rxq->bd)
+               dma_free_coherent(trans->dev,
+@@ -682,8 +689,8 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
+       if (rxq->used_bd)
+               dma_free_coherent(trans->dev,
+-                                (use_rx_td ? sizeof(*rxq->cd) :
+-                                 sizeof(__le32)) * rxq->queue_size,
++                                iwl_pcie_used_bd_size(trans) *
++                                      rxq->queue_size,
+                                 rxq->used_bd, rxq->used_bd_dma);
+       rxq->used_bd_dma = 0;
+       rxq->used_bd = NULL;
+@@ -707,7 +714,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
+       else
+               rxq->queue_size = RX_QUEUE_SIZE;
+-      free_size = iwl_pcie_free_bd_size(trans, use_rx_td);
++      free_size = iwl_pcie_free_bd_size(trans);
+       /*
+        * Allocate the circular buffer of Read Buffer Descriptors
+@@ -720,7 +727,8 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
+       if (trans->trans_cfg->mq_rx_supported) {
+               rxq->used_bd = dma_alloc_coherent(dev,
+-                                                (use_rx_td ? sizeof(*rxq->cd) : sizeof(__le32)) * rxq->queue_size,
++                                                iwl_pcie_used_bd_size(trans) *
++                                                      rxq->queue_size,
+                                                 &rxq->used_bd_dma,
+                                                 GFP_KERNEL);
+               if (!rxq->used_bd)
+@@ -1419,6 +1427,7 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
+       u16 vid;
+       BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32);
++      BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc_bz) != 4);
+       if (!trans->trans_cfg->mq_rx_supported) {
+               rxb = rxq->queue[i];
+@@ -1426,11 +1435,20 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
+               return rxb;
+       }
+-      if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+-              vid = le16_to_cpu(rxq->cd[i].rbid);
+-              *join = rxq->cd[i].flags & IWL_RX_CD_FLAGS_FRAGMENTED;
++      if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
++              struct iwl_rx_completion_desc_bz *cd = rxq->used_bd;
++
++              vid = le16_to_cpu(cd[i].rbid);
++              *join = cd[i].flags & IWL_RX_CD_FLAGS_FRAGMENTED;
++      } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
++              struct iwl_rx_completion_desc *cd = rxq->used_bd;
++
++              vid = le16_to_cpu(cd[i].rbid);
++              *join = cd[i].flags & IWL_RX_CD_FLAGS_FRAGMENTED;
+       } else {
+-              vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; /* 12-bit VID */
++              __le32 *cd = rxq->used_bd;
++
++              vid = le32_to_cpu(cd[i]) & 0x0FFF; /* 12-bit VID */
+       }
+       if (!vid || vid > RX_POOL_SIZE(trans_pcie->num_rx_bufs))
+-- 
+2.42.0
+
diff --git a/queue-5.15/iwlwifi-remove-contact-information.patch b/queue-5.15/iwlwifi-remove-contact-information.patch
new file mode 100644 (file)
index 0000000..58fa33d
--- /dev/null
@@ -0,0 +1,613 @@
+From 03f60855381d9fc05d24e477a589cfa386d00da9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Oct 2021 11:43:48 +0300
+Subject: iwlwifi: remove contact information
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 854fe828e58ceafbab92d408ad344a168ea41555 ]
+
+The list address is going away, and the postal address isn't
+useful, remove all the contact information.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/iwlwifi.20211017113927.f73e3b6384cb.I967fd394995461277eafa149bb25cefd1673751e@changeid
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Stable-dep-of: 658939fc68d3 ("wifi: iwlwifi: empty overflow queue during flush")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/cfg/1000.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/cfg/2000.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/cfg/5000.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/cfg/6000.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c          | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/dev.h              | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/devices.c          | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/led.c              | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/led.h              | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/lib.c              | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c         | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/main.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/power.c            | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/power.h            | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/rs.c               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/rs.h               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/rx.c               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/rxon.c             | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/scan.c             | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/sta.c              | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/tt.c               | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/tt.h               | 4 ----
+ drivers/net/wireless/intel/iwlwifi/dvm/tx.c               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/dvm/ucode.c            | 5 -----
+ drivers/net/wireless/intel/iwlwifi/fw/img.c               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-debug.h            | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h    | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h      | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h     | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h   | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c         | 5 -----
+ drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h         | 5 -----
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.c               | 5 -----
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.h               | 5 -----
+ 35 files changed, 169 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+index 44c4fe9753901..116defb15afbd 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+index df6ac00340b26..ab2038a3fbe21 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+index 6cdd7d983bdae..e2e23d2bc1fe5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+index 541a3ec857770..20929e59c2f4d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
++++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2018 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+index 9110492018387..b246dbd371b35 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+@@ -3,10 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2018 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+ #include <linux/slab.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
+index 4bd792c06ff6e..bbd5740912012 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2003 - 2014, 2020 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ /*
+  * Please use this file (dev.h) for driver implementation definitions.
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
+index c3e25885d1943..39e40901fa464 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/units.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
+index e8a4d604b9106..71f67a019cf60 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.h b/drivers/net/wireless/intel/iwlwifi/dvm/led.h
+index 6fe20180dc87c..5038fc378a1f7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/led.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #ifndef __iwl_leds_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
+index 3b937a7dd4032..40d790b36d85b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/etherdevice.h>
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+index 90fe4adca4926..e8bd4f0e3d2dc 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+@@ -6,11 +6,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+index cc7b69fd14d37..353f660a84928 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+@@ -6,11 +6,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
+index 93ef023905c96..6d16a7105656c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
+@@ -6,10 +6,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.h b/drivers/net/wireless/intel/iwlwifi/dvm/power.h
+index 3f8db1fc4b590..f38201ce1e991 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/power.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.h
+@@ -5,10 +5,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+ #ifndef __iwl_power_setting_h__
+ #define __iwl_power_setting_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
+index 548540dd0c0f7..b7c8b209bfea4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2019 - 2020 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/skbuff.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
+index 68a840d739e83..0b47f1993c5db 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #ifndef __iwl_agn_rs_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+index 3cd7b423c588d..db0c41bbeb0e1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+@@ -7,11 +7,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portionhelp of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/etherdevice.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
+index 12a3d464ae640..70338bc7bb540 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2015 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- * Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/etherdevice.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+index c4ecf6ed21860..2d38227dfdd20 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+@@ -3,10 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2018        Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+ #include <linux/slab.h>
+ #include <linux/types.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+index 7c3168145e58a..03ceb0615368b 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c
+@@ -5,11 +5,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/etherdevice.h>
+ #include <net/mac80211.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
+index 2684a924ba574..43e8d04d5a8b2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c
+@@ -6,10 +6,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
+index 3b0ff458a158b..7ace052fc78a4 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h
+@@ -5,10 +5,6 @@
+  *
+  * Portions of this file are derived from the ipw3945 project, as well
+  * as portions of the ieee80211 subsystem header files.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+  *****************************************************************************/
+ #ifndef __iwl_tt_setting_h__
+ #define __iwl_tt_setting_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+index 847b8e07f81c5..60a7b61d59aa3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2019 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
+index 24194c7912181..4b27a53d0bb4a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2015 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/kernel.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.c b/drivers/net/wireless/intel/iwlwifi/fw/img.c
+index c2a4e60518bc7..5755e179066ae 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/img.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/img.c
+@@ -18,11 +18,6 @@
+  *
+  * The full GNU General Public License is included in this distribution
+  * in the file called COPYING.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  * BSD LICENSE
+  *
+  * Copyright(c) 2019 - 2020 Intel Corporation
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
+index 528eba441926d..8db7aeddfd057 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
+@@ -5,11 +5,6 @@
+  * Copyright(c) 2018 - 2020 Intel Corporation
+  *
+  * Portions of this file are derived from the ipw3945 project.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #ifndef __iwl_debug_h__
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+index 1bc6ecc321404..347fd95c4e3a5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+@@ -4,11 +4,6 @@
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2015        Intel Deutschland GmbH
+  * Copyright(c) 2018 - 2019 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
+index a57019241a780..0af9d8362c5b8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(c) 2016-2017 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #if !defined(__IWLWIFI_DEVICE_TRACE_IO) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+index 72ca882daed5e..46ed723f138a6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+@@ -5,11 +5,6 @@
+  * Copyright(c) 2015 Intel Mobile Communications GmbH
+  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+  * Copyright(c) 2018        Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+index d0467da5af034..7dd70011fd1ef 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #if !defined(__IWLWIFI_DEVICE_TRACE_MSG) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
+index 2228faefffbca..3ec0205ac9f90 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h
+@@ -2,11 +2,6 @@
+ /******************************************************************************
+  *
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #if !defined(__IWLWIFI_DEVICE_TRACE_UCODE) || defined(TRACE_HEADER_MULTI_READ)
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+index b5037db0c3817..999b7c652289d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c
+@@ -3,11 +3,6 @@
+  *
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2018 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/module.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+index fc8bc212ee847..1455b578358bf 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+@@ -4,11 +4,6 @@
+  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
+  * Copyright(C) 2016        Intel Deutschland GmbH
+  * Copyright(c) 2018        Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #ifndef __IWLWIFI_DEVICE_TRACE
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+index b97708cb869d5..c66aa61b4ba31 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+@@ -4,11 +4,6 @@
+  * Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved.
+  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/skbuff.h>
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+index 32104c9f8f5ee..3e206df57347c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+@@ -5,11 +5,6 @@
+  * Copyright(c) 2015 Intel Mobile Communications GmbH
+  * Copyright(c) 2017 Intel Deutschland GmbH
+  * Copyright(c) 2018 - 2019 Intel Corporation
+- *
+- * Contact Information:
+- *  Intel Linux Wireless <linuxwifi@intel.com>
+- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+- *
+  *****************************************************************************/
+ #ifndef __rs_h__
+-- 
+2.42.0
+
diff --git a/queue-5.15/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch b/queue-5.15/leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch
new file mode 100644 (file)
index 0000000..c9e6555
--- /dev/null
@@ -0,0 +1,53 @@
+From 5b33040c9dd2e8f375c80bc63cde7c7141a6957c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 21:28:34 +0200
+Subject: leds: pwm: Don't disable the PWM when the LED should be off
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 76fe464c8e64e71b2e4af11edeef0e5d85eeb6aa ]
+
+Disabling a PWM (i.e. calling pwm_apply_state with .enabled = false)
+gives no guarantees what the PWM output does. It might freeze where it
+currently is, or go in a High-Z state or drive the active or inactive
+state, it might even continue to toggle.
+
+To ensure that the LED gets really disabled, don't disable the PWM even
+when .duty_cycle is zero.
+
+This fixes disabling a leds-pwm LED on i.MX28. The PWM on this SoC is
+one of those that freezes its output on disable, so if you disable an
+LED that is full on, it stays on. If you disable a LED with half
+brightness it goes off in 50% of the cases and full on in the other 50%.
+
+Fixes: 41c42ff5dbe2 ("leds: simple driver for pwm driven LEDs")
+Reported-by: Rogan Dawes <rogan@dawes.za.net>
+Reported-by: Fabio Estevam <festevam@denx.de>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Fabio Estevam <festevam@denx.de>
+Link: https://lore.kernel.org/r/20230922192834.1695727-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-pwm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index cc892ecd52408..6d3e33e8b5f91 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -53,7 +53,7 @@ static int led_pwm_set(struct led_classdev *led_cdev,
+               duty = led_dat->pwmstate.period - duty;
+       led_dat->pwmstate.duty_cycle = duty;
+-      led_dat->pwmstate.enabled = duty > 0;
++      led_dat->pwmstate.enabled = true;
+       return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch b/queue-5.15/leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch
new file mode 100644 (file)
index 0000000..64d1430
--- /dev/null
@@ -0,0 +1,63 @@
+From cd739f47f7fac08a46e75d1aab0cd73eb18763b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Sep 2023 09:15:38 +0200
+Subject: leds: trigger: ledtrig-cpu:: Fix 'output may be truncated' issue for
+ 'cpu'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ff50f53276131a3059e8307d11293af388ed2bcd ]
+
+In order to teach the compiler that 'trig->name' will never be truncated,
+we need to tell it that 'cpu' is not negative.
+
+When building with W=1, this fixes the following warnings:
+
+  drivers/leds/trigger/ledtrig-cpu.c: In function ‘ledtrig_cpu_init’:
+  drivers/leds/trigger/ledtrig-cpu.c:155:56: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 5 [-Werror=format-truncation=]
+    155 |                 snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
+        |                                                        ^~
+  drivers/leds/trigger/ledtrig-cpu.c:155:52: note: directive argument in the range [-2147483648, 7]
+    155 |                 snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
+        |                                                    ^~~~~~~
+  drivers/leds/trigger/ledtrig-cpu.c:155:17: note: ‘snprintf’ output between 5 and 15 bytes into a destination of size 8
+    155 |                 snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
+        |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fixes: 8f88731d052d ("led-triggers: create a trigger for CPU activity")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/3f4be7a99933cf8566e630da54f6ab913caac432.1695453322.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/trigger/ledtrig-cpu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c
+index 8af4f9bb9cde8..05848a2fecff6 100644
+--- a/drivers/leds/trigger/ledtrig-cpu.c
++++ b/drivers/leds/trigger/ledtrig-cpu.c
+@@ -130,7 +130,7 @@ static int ledtrig_prepare_down_cpu(unsigned int cpu)
+ static int __init ledtrig_cpu_init(void)
+ {
+-      int cpu;
++      unsigned int cpu;
+       int ret;
+       /* Supports up to 9999 cpu cores */
+@@ -152,7 +152,7 @@ static int __init ledtrig_cpu_init(void)
+               if (cpu >= 8)
+                       continue;
+-              snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
++              snprintf(trig->name, MAX_NAME_LEN, "cpu%u", cpu);
+               led_trigger_register_simple(trig->name, &trig->_trig);
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/leds-turris-omnia-do-not-use-smbus-calls.patch b/queue-5.15/leds-turris-omnia-do-not-use-smbus-calls.patch
new file mode 100644 (file)
index 0000000..b39a488
--- /dev/null
@@ -0,0 +1,155 @@
+From 6782733af78201d9e6cd0fd38d22a6037748f07e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 18:11:01 +0200
+Subject: leds: turris-omnia: Do not use SMBUS calls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 6de283b96b31b4890e3ee8c86caca2a3a30d1011 ]
+
+The leds-turris-omnia driver uses three function for I2C access:
+- i2c_smbus_write_byte_data() and i2c_smbus_read_byte_data(), which
+  cause an emulated SMBUS transfer,
+- i2c_master_send(), which causes an ordinary I2C transfer.
+
+The Turris Omnia MCU LED controller is not semantically SMBUS, it
+operates as a simple I2C bus. It does not implement any of the SMBUS
+specific features, like PEC, or procedure calls, or anything. Moreover
+the I2C controller driver also does not implement SMBUS, and so the
+emulated SMBUS procedure from drivers/i2c/i2c-core-smbus.c is used for
+the SMBUS calls, which gives an unnecessary overhead.
+
+When I first wrote the driver, I was unaware of these facts, and I
+simply used the first function that worked.
+
+Drop the I2C SMBUS calls and instead use simple I2C transfers.
+
+Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20230918161104.20860-2-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-turris-omnia.c | 54 +++++++++++++++++++++++++-------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c
+index c9e7c467e5acd..ebc6cf3ce3cad 100644
+--- a/drivers/leds/leds-turris-omnia.c
++++ b/drivers/leds/leds-turris-omnia.c
+@@ -2,7 +2,7 @@
+ /*
+  * CZ.NIC's Turris Omnia LEDs driver
+  *
+- * 2020 by Marek Behún <kabel@kernel.org>
++ * 2020, 2023 by Marek Behún <kabel@kernel.org>
+  */
+ #include <linux/i2c.h>
+@@ -41,6 +41,37 @@ struct omnia_leds {
+       struct omnia_led leds[];
+ };
++static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
++{
++      u8 buf[2] = { cmd, val };
++
++      return i2c_master_send(client, buf, sizeof(buf));
++}
++
++static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
++{
++      struct i2c_msg msgs[2];
++      u8 reply;
++      int ret;
++
++      msgs[0].addr = client->addr;
++      msgs[0].flags = 0;
++      msgs[0].len = 1;
++      msgs[0].buf = &cmd;
++      msgs[1].addr = client->addr;
++      msgs[1].flags = I2C_M_RD;
++      msgs[1].len = 1;
++      msgs[1].buf = &reply;
++
++      ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++      if (likely(ret == ARRAY_SIZE(msgs)))
++              return reply;
++      else if (ret < 0)
++              return ret;
++      else
++              return -EIO;
++}
++
+ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
+                                            enum led_brightness brightness)
+ {
+@@ -64,7 +95,7 @@ static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
+       if (buf[2] || buf[3] || buf[4])
+               state |= CMD_LED_STATE_ON;
+-      ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state);
++      ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
+       if (ret >= 0 && (state & CMD_LED_STATE_ON))
+               ret = i2c_master_send(leds->client, buf, 5);
+@@ -114,9 +145,9 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
+       cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
+       /* put the LED into software mode */
+-      ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
+-                                      CMD_LED_MODE_LED(led->reg) |
+-                                      CMD_LED_MODE_USER);
++      ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
++                               CMD_LED_MODE_LED(led->reg) |
++                               CMD_LED_MODE_USER);
+       if (ret < 0) {
+               dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
+                       ret);
+@@ -124,8 +155,8 @@ static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
+       }
+       /* disable the LED */
+-      ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE,
+-                                      CMD_LED_STATE_LED(led->reg));
++      ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
++                               CMD_LED_STATE_LED(led->reg));
+       if (ret < 0) {
+               dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
+               return ret;
+@@ -158,7 +189,7 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a,
+       struct i2c_client *client = to_i2c_client(dev);
+       int ret;
+-      ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS);
++      ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS);
+       if (ret < 0)
+               return ret;
+@@ -179,8 +210,7 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
+       if (brightness > 100)
+               return -EINVAL;
+-      ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS,
+-                                      (u8)brightness);
++      ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
+       return ret < 0 ? ret : count;
+ }
+@@ -241,8 +271,8 @@ static int omnia_leds_remove(struct i2c_client *client)
+       u8 buf[5];
+       /* put all LEDs into default (HW triggered) mode */
+-      i2c_smbus_write_byte_data(client, CMD_LED_MODE,
+-                                CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
++      omnia_cmd_write_u8(client, CMD_LED_MODE,
++                         CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
+       /* set all LEDs color to [255, 255, 255] */
+       buf[0] = CMD_LED_COLOR;
+-- 
+2.42.0
+
diff --git a/queue-5.15/leds-turris-omnia-drop-unnecessary-mutex-locking.patch b/queue-5.15/leds-turris-omnia-drop-unnecessary-mutex-locking.patch
new file mode 100644 (file)
index 0000000..78a8141
--- /dev/null
@@ -0,0 +1,75 @@
+From 30bb182d004bb1cd904b708d1ac76eea8a4463c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 18:07:43 +0200
+Subject: leds: turris-omnia: Drop unnecessary mutex locking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit 760b6b7925bf09491aafa4727eef74fc6bf738b0 ]
+
+Do not lock driver mutex in the global LED panel brightness sysfs
+accessors brightness_show() and brightness_store().
+
+The mutex locking is unnecessary here. The I2C transfers are guarded by
+I2C core locking mechanism, and the LED commands itself do not interfere
+with other commands.
+
+Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230802160748.11208-2-kabel@kernel.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Stable-dep-of: 6de283b96b31 ("leds: turris-omnia: Do not use SMBUS calls")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-turris-omnia.c | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c
+index 1adfed1c0619b..c9e7c467e5acd 100644
+--- a/drivers/leds/leds-turris-omnia.c
++++ b/drivers/leds/leds-turris-omnia.c
+@@ -156,12 +156,9 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a,
+                              char *buf)
+ {
+       struct i2c_client *client = to_i2c_client(dev);
+-      struct omnia_leds *leds = i2c_get_clientdata(client);
+       int ret;
+-      mutex_lock(&leds->lock);
+       ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS);
+-      mutex_unlock(&leds->lock);
+       if (ret < 0)
+               return ret;
+@@ -173,7 +170,6 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
+                               const char *buf, size_t count)
+ {
+       struct i2c_client *client = to_i2c_client(dev);
+-      struct omnia_leds *leds = i2c_get_clientdata(client);
+       unsigned long brightness;
+       int ret;
+@@ -183,15 +179,10 @@ static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
+       if (brightness > 100)
+               return -EINVAL;
+-      mutex_lock(&leds->lock);
+       ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS,
+                                       (u8)brightness);
+-      mutex_unlock(&leds->lock);
+-
+-      if (ret < 0)
+-              return ret;
+-      return count;
++      return ret < 0 ? ret : count;
+ }
+ static DEVICE_ATTR_RW(brightness);
+-- 
+2.42.0
+
diff --git a/queue-5.15/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch b/queue-5.15/libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch
new file mode 100644 (file)
index 0000000..1d20e19
--- /dev/null
@@ -0,0 +1,45 @@
+From 0c207427730935626e4b9b576d692b1596208030 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 07:03:27 +0000
+Subject: libnvdimm/of_pmem: Use devm_kstrdup instead of kstrdup and check its
+ return value
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit 6fd4ebfc4d61e3097b595ab2725d513e3bbd6739 ]
+
+Use devm_kstrdup() instead of kstrdup() and check its return value to
+avoid memory leak.
+
+Fixes: 49bddc73d15c ("libnvdimm/of_pmem: Provide a unique name for bus provider")
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/of_pmem.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c
+index 10dbdcdfb9ce9..0243789ba914b 100644
+--- a/drivers/nvdimm/of_pmem.c
++++ b/drivers/nvdimm/of_pmem.c
+@@ -30,7 +30,13 @@ static int of_pmem_region_probe(struct platform_device *pdev)
+       if (!priv)
+               return -ENOMEM;
+-      priv->bus_desc.provider_name = kstrdup(pdev->name, GFP_KERNEL);
++      priv->bus_desc.provider_name = devm_kstrdup(&pdev->dev, pdev->name,
++                                                      GFP_KERNEL);
++      if (!priv->bus_desc.provider_name) {
++              kfree(priv);
++              return -ENOMEM;
++      }
++
+       priv->bus_desc.module = THIS_MODULE;
+       priv->bus_desc.of_node = np;
+-- 
+2.42.0
+
diff --git a/queue-5.15/livepatch-fix-missing-newline-character-in-klp_resol.patch b/queue-5.15/livepatch-fix-missing-newline-character-in-klp_resol.patch
new file mode 100644 (file)
index 0000000..a206f13
--- /dev/null
@@ -0,0 +1,38 @@
+From b2eb747a35f3a70092ea2b14feaca991b6e9e631 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 15:26:44 +0800
+Subject: livepatch: Fix missing newline character in klp_resolve_symbols()
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit 67e18e132f0fd738f8c8cac3aa1420312073f795 ]
+
+Without the newline character, the log may not be printed immediately
+after the error occurs.
+
+Fixes: ca376a937486 ("livepatch: Prevent module-specific KLP rela sections from referencing vmlinux symbols")
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20230914072644.4098857-1-zhengyejian1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/livepatch/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
+index c0789383807b9..147ed154ebc77 100644
+--- a/kernel/livepatch/core.c
++++ b/kernel/livepatch/core.c
+@@ -244,7 +244,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
+                * symbols are exported and normal relas can be used instead.
+                */
+               if (!sec_vmlinux && sym_vmlinux) {
+-                      pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section",
++                      pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section\n",
+                              sym_name);
+                       return -EINVAL;
+               }
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch b/queue-5.15/media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch
new file mode 100644 (file)
index 0000000..bd07c0f
--- /dev/null
@@ -0,0 +1,52 @@
+From dd2954050ae6d0c26c2eae1ab5fb30b2e678c543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 11:49:42 +0800
+Subject: media: bttv: fix use after free error due to btv->timeout timer
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit bd5b50b329e850d467e7bcc07b2b6bde3752fbda ]
+
+There may be some a race condition between timer function
+bttv_irq_timeout and bttv_remove. The timer is setup in
+probe and there is no timer_delete operation in remove
+function. When it hit kfree btv, the function might still be
+invoked, which will cause use after free bug.
+
+This bug is found by static analysis, it may be false positive.
+
+Fix it by adding del_timer_sync invoking to the remove function.
+
+cpu0                cpu1
+                  bttv_probe
+                    ->timer_setup
+                      ->bttv_set_dma
+                        ->mod_timer;
+bttv_remove
+  ->kfree(btv);
+                  ->bttv_irq_timeout
+                    ->USE btv
+
+Fixes: 162e6376ac58 ("media: pci: Convert timers to use timer_setup()")
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/bt8xx/bttv-driver.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
+index 661ebfa7bf3f5..c4bf7b7109ce4 100644
+--- a/drivers/media/pci/bt8xx/bttv-driver.c
++++ b/drivers/media/pci/bt8xx/bttv-driver.c
+@@ -4250,6 +4250,7 @@ static void bttv_remove(struct pci_dev *pci_dev)
+       /* free resources */
+       free_irq(btv->c.pci->irq,btv);
++      del_timer_sync(&btv->timeout);
+       iounmap(btv->bt848_mmio);
+       release_mem_region(pci_resource_start(btv->c.pci,0),
+                          pci_resource_len(btv->c.pci,0));
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch b/queue-5.15/media-cadence-csi2rx-unregister-v4l2-async-notifier.patch
new file mode 100644 (file)
index 0000000..58b348c
--- /dev/null
@@ -0,0 +1,67 @@
+From 3ac4667d6c72e2927cb3a9ed1b9a963481b47e76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 18:39:29 +0530
+Subject: media: cadence: csi2rx: Unregister v4l2 async notifier
+
+From: Pratyush Yadav <p.yadav@ti.com>
+
+[ Upstream commit b2701715301a49b53d05c7d43f3fedc3b8743bfc ]
+
+The notifier is added to the global notifier list when registered. When
+the module is removed, the struct csi2rx_priv in which the notifier is
+embedded, is destroyed. As a result the notifier list has a reference to
+a notifier that no longer exists. This causes invalid memory accesses
+when the list is iterated over. Similar for when the probe fails.
+Unregister and clean up the notifier to avoid this.
+
+Fixes: 1fc3b37f34f6 ("media: v4l: cadence: Add Cadence MIPI-CSI2 RX driver")
+
+Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
+Tested-by: Julien Massot <julien.massot@collabora.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Jai Luthra <j-luthra@ti.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/cadence/cdns-csi2rx.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
+index 7b44ab2b8c9ad..292044588ae2c 100644
+--- a/drivers/media/platform/cadence/cdns-csi2rx.c
++++ b/drivers/media/platform/cadence/cdns-csi2rx.c
+@@ -406,8 +406,10 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
+       asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
+                                             struct v4l2_async_subdev);
+       of_node_put(ep);
+-      if (IS_ERR(asd))
++      if (IS_ERR(asd)) {
++              v4l2_async_nf_cleanup(&csi2rx->notifier);
+               return PTR_ERR(asd);
++      }
+       csi2rx->notifier.ops = &csi2rx_notifier_ops;
+@@ -469,6 +471,7 @@ static int csi2rx_probe(struct platform_device *pdev)
+       return 0;
+ err_cleanup:
++      v4l2_async_nf_unregister(&csi2rx->notifier);
+       v4l2_async_nf_cleanup(&csi2rx->notifier);
+ err_free_priv:
+       kfree(csi2rx);
+@@ -479,6 +482,8 @@ static int csi2rx_remove(struct platform_device *pdev)
+ {
+       struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev);
++      v4l2_async_nf_unregister(&csi2rx->notifier);
++      v4l2_async_nf_cleanup(&csi2rx->notifier);
+       v4l2_async_unregister_subdev(&csi2rx->subdev);
+       kfree(csi2rx);
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-cedrus-fix-clock-reset-sequence.patch b/queue-5.15/media-cedrus-fix-clock-reset-sequence.patch
new file mode 100644 (file)
index 0000000..c2af941
--- /dev/null
@@ -0,0 +1,87 @@
+From e90bf6d3fed2e9da1cac2e745647e0db1c9ce2b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 20:46:12 +0200
+Subject: media: cedrus: Fix clock/reset sequence
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 36fe515c1a3cd5eac148e8a591a82108d92d5522 ]
+
+According to H6 user manual, resets should always be de-asserted before
+clocks are enabled. This is also consistent with vendor driver.
+
+Fixes: d5aecd289bab ("media: cedrus: Implement runtime PM")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/sunxi/cedrus/cedrus_hw.c    | 24 +++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
+index e2f2ff609c7e6..0904aea782b1e 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
+@@ -147,12 +147,12 @@ int cedrus_hw_suspend(struct device *device)
+ {
+       struct cedrus_dev *dev = dev_get_drvdata(device);
+-      reset_control_assert(dev->rstc);
+-
+       clk_disable_unprepare(dev->ram_clk);
+       clk_disable_unprepare(dev->mod_clk);
+       clk_disable_unprepare(dev->ahb_clk);
++      reset_control_assert(dev->rstc);
++
+       return 0;
+ }
+@@ -161,11 +161,18 @@ int cedrus_hw_resume(struct device *device)
+       struct cedrus_dev *dev = dev_get_drvdata(device);
+       int ret;
++      ret = reset_control_reset(dev->rstc);
++      if (ret) {
++              dev_err(dev->dev, "Failed to apply reset\n");
++
++              return ret;
++      }
++
+       ret = clk_prepare_enable(dev->ahb_clk);
+       if (ret) {
+               dev_err(dev->dev, "Failed to enable AHB clock\n");
+-              return ret;
++              goto err_rst;
+       }
+       ret = clk_prepare_enable(dev->mod_clk);
+@@ -182,21 +189,14 @@ int cedrus_hw_resume(struct device *device)
+               goto err_mod_clk;
+       }
+-      ret = reset_control_reset(dev->rstc);
+-      if (ret) {
+-              dev_err(dev->dev, "Failed to apply reset\n");
+-
+-              goto err_ram_clk;
+-      }
+-
+       return 0;
+-err_ram_clk:
+-      clk_disable_unprepare(dev->ram_clk);
+ err_mod_clk:
+       clk_disable_unprepare(dev->mod_clk);
+ err_ahb_clk:
+       clk_disable_unprepare(dev->ahb_clk);
++err_rst:
++      reset_control_assert(dev->rstc);
+       return ret;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-dvb-usb-v2-af9035-fix-missing-unlock.patch b/queue-5.15/media-dvb-usb-v2-af9035-fix-missing-unlock.patch
new file mode 100644 (file)
index 0000000..5fa7099
--- /dev/null
@@ -0,0 +1,67 @@
+From ee7502625d7ea83a5c24cf2ce73e95920438f523 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Oct 2023 12:08:45 +0200
+Subject: media: dvb-usb-v2: af9035: fix missing unlock
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit f31b2cb85f0ee165d78e1c43f6d69f82cc3b2145 ]
+
+Instead of returning an error, goto the mutex unlock at
+the end of the function.
+
+Fixes smatch warning:
+
+drivers/media/usb/dvb-usb-v2/af9035.c:467 af9035_i2c_master_xfer() warn: inconsistent returns '&d->i2c_mutex'.
+  Locked on  : 326,387
+  Unlocked on: 465,467
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: 7bf744f2de0a ("media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer")
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/af9035.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
+index 56bb507fca214..dabfe9b332226 100644
+--- a/drivers/media/usb/dvb-usb-v2/af9035.c
++++ b/drivers/media/usb/dvb-usb-v2/af9035.c
+@@ -323,8 +323,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+                       ret = -EOPNOTSUPP;
+               } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
+                          (msg[0].addr == state->af9033_i2c_addr[1])) {
+-                      if (msg[0].len < 3 || msg[1].len < 1)
+-                              return -EOPNOTSUPP;
++                      if (msg[0].len < 3 || msg[1].len < 1) {
++                              ret = -EOPNOTSUPP;
++                              goto unlock;
++                      }
+                       /* demod access via firmware interface */
+                       reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+@@ -384,8 +386,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+                       ret = -EOPNOTSUPP;
+               } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
+                          (msg[0].addr == state->af9033_i2c_addr[1])) {
+-                      if (msg[0].len < 3)
+-                              return -EOPNOTSUPP;
++                      if (msg[0].len < 3) {
++                              ret = -EOPNOTSUPP;
++                              goto unlock;
++                      }
+                       /* demod access via firmware interface */
+                       reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+                                       msg[0].buf[2];
+@@ -460,6 +464,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+               ret = -EOPNOTSUPP;
+       }
++unlock:
+       mutex_unlock(&d->i2c_mutex);
+       if (ret < 0)
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch b/queue-5.15/media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch
new file mode 100644 (file)
index 0000000..665b244
--- /dev/null
@@ -0,0 +1,50 @@
+From deea8c3040538bca1beb03eb5437b57920548192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Aug 2023 00:13:40 +0200
+Subject: media: i2c: max9286: Fix some redundant of_node_put() calls
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 0822315e46b400f611cba1193456ee6a5dc3e41d ]
+
+This is odd to have a of_node_put() just after a for_each_child_of_node()
+or a for_each_endpoint_of_node() loop. It should already be called
+during the last iteration.
+
+Remove these calls.
+
+Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/max9286.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
+index 404a03f48b976..1b9beaee6bea7 100644
+--- a/drivers/media/i2c/max9286.c
++++ b/drivers/media/i2c/max9286.c
+@@ -1231,7 +1231,6 @@ static int max9286_parse_dt(struct max9286_priv *priv)
+               i2c_mux_mask |= BIT(id);
+       }
+-      of_node_put(node);
+       of_node_put(i2c_mux);
+       /* Parse the endpoints */
+@@ -1295,7 +1294,6 @@ static int max9286_parse_dt(struct max9286_priv *priv)
+               priv->source_mask |= BIT(ep.port);
+               priv->nsources++;
+       }
+-      of_node_put(node);
+       /*
+        * Parse the initial value of the reverse channel amplitude from
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch b/queue-5.15/media-rcar-vin-improve-async-notifier-cleanup-paths.patch
new file mode 100644 (file)
index 0000000..3d4b971
--- /dev/null
@@ -0,0 +1,130 @@
+From cd2471ec6c14b24a75e2abe01c1a9bb97e8d7f3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jul 2021 16:25:52 +0200
+Subject: media: rcar-vin: Improve async notifier cleanup paths
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+
+[ Upstream commit 6df3057792911c59032327886599d9625534958a ]
+
+The cleanup code for the async notifiers can be refactored to own
+functions to reduce code duplication and improve readability. While at
+it rename the CSI-2 initialization function _csi2_ instead of _mc_ to
+match.
+
+Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/rcar-vin/rcar-core.c | 51 ++++++++++++---------
+ 1 file changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index 6ea561fcd7a39..93a32be692e9a 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -383,6 +383,16 @@ static void rvin_group_put(struct rvin_dev *vin)
+       kref_put(&group->refcount, rvin_group_release);
+ }
++static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
++{
++      mutex_lock(&vin->group->lock);
++      if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
++              v4l2_async_notifier_unregister(&vin->group->notifier);
++              v4l2_async_notifier_cleanup(&vin->group->notifier);
++      }
++      mutex_unlock(&vin->group->lock);
++}
++
+ /* -----------------------------------------------------------------------------
+  * Controls
+  */
+@@ -676,6 +686,12 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin)
+       return ret;
+ }
++static void rvin_parallel_cleanup(struct rvin_dev *vin)
++{
++      v4l2_async_notifier_unregister(&vin->notifier);
++      v4l2_async_notifier_cleanup(&vin->notifier);
++}
++
+ static int rvin_parallel_init(struct rvin_dev *vin)
+ {
+       int ret;
+@@ -937,7 +953,16 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
+       return 0;
+ }
+-static int rvin_mc_init(struct rvin_dev *vin)
++static void rvin_csi2_cleanup(struct rvin_dev *vin)
++{
++      if (!vin->info->use_mc)
++              return;
++
++      rvin_group_notifier_cleanup(vin);
++      rvin_group_put(vin);
++}
++
++static int rvin_csi2_init(struct rvin_dev *vin)
+ {
+       int ret;
+@@ -1443,7 +1468,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, vin);
+       if (vin->info->use_mc) {
+-              ret = rvin_mc_init(vin);
++              ret = rvin_csi2_init(vin);
+               if (ret)
+                       goto error_dma_unregister;
+       }
+@@ -1456,20 +1481,9 @@ static int rcar_vin_probe(struct platform_device *pdev)
+       pm_runtime_enable(&pdev->dev);
+       return 0;
+-
+ error_group_unregister:
+       rvin_free_controls(vin);
+-
+-      if (vin->info->use_mc) {
+-              mutex_lock(&vin->group->lock);
+-              if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
+-                      v4l2_async_notifier_unregister(&vin->group->notifier);
+-                      v4l2_async_notifier_cleanup(&vin->group->notifier);
+-              }
+-              mutex_unlock(&vin->group->lock);
+-              rvin_group_put(vin);
+-      }
+-
++      rvin_csi2_cleanup(vin);
+ error_dma_unregister:
+       rvin_dma_unregister(vin);
+@@ -1484,14 +1498,9 @@ static int rcar_vin_remove(struct platform_device *pdev)
+       rvin_v4l2_unregister(vin);
+-      v4l2_async_notifier_unregister(&vin->notifier);
+-      v4l2_async_notifier_cleanup(&vin->notifier);
++      rvin_parallel_cleanup(vin);
+-      if (vin->info->use_mc) {
+-              v4l2_async_notifier_unregister(&vin->group->notifier);
+-              v4l2_async_notifier_cleanup(&vin->group->notifier);
+-              rvin_group_put(vin);
+-      }
++      rvin_csi2_cleanup(vin);
+       rvin_free_controls(vin);
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-rcar-vin-move-group-async-notifier.patch b/queue-5.15/media-rcar-vin-move-group-async-notifier.patch
new file mode 100644 (file)
index 0000000..fd31ed8
--- /dev/null
@@ -0,0 +1,520 @@
+From 51d1516951f0775a766867ae7a06e55ebd0eed68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jul 2021 16:25:55 +0200
+Subject: media: rcar-vin: Move group async notifier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+
+[ Upstream commit 2070893aed113338f80350bd76e5956c9a8cf07f ]
+
+The VIN group notifier code is intertwined with the media graph layout
+code for R-Car CSI-2 subdevices, this makes it hard to extend the group
+to also support the R-Car ISP channel selector.
+
+Before breaking the two concepts apart and extending it move the group
+code to its final location. There is no functional change and all
+functions are moved verbatim.
+
+Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/rcar-vin/rcar-core.c | 460 ++++++++++----------
+ 1 file changed, 230 insertions(+), 230 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index 867d8fd7a77d3..5a280d8ff7dd0 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -383,6 +383,176 @@ static void rvin_group_put(struct rvin_dev *vin)
+       kref_put(&group->refcount, rvin_group_release);
+ }
++static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
++{
++      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
++      const struct rvin_group_route *route;
++      unsigned int i;
++      int ret;
++
++      ret = media_device_register(&vin->group->mdev);
++      if (ret)
++              return ret;
++
++      ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
++      if (ret) {
++              vin_err(vin, "Failed to register subdev nodes\n");
++              return ret;
++      }
++
++      /* Register all video nodes for the group. */
++      for (i = 0; i < RCAR_VIN_NUM; i++) {
++              if (vin->group->vin[i] &&
++                  !video_is_registered(&vin->group->vin[i]->vdev)) {
++                      ret = rvin_v4l2_register(vin->group->vin[i]);
++                      if (ret)
++                              return ret;
++              }
++      }
++
++      /* Create all media device links between VINs and CSI-2's. */
++      mutex_lock(&vin->group->lock);
++      for (route = vin->info->routes; route->mask; route++) {
++              struct media_pad *source_pad, *sink_pad;
++              struct media_entity *source, *sink;
++              unsigned int source_idx;
++
++              /* Check that VIN is part of the group. */
++              if (!vin->group->vin[route->vin])
++                      continue;
++
++              /* Check that VIN' master is part of the group. */
++              if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
++                      continue;
++
++              /* Check that CSI-2 is part of the group. */
++              if (!vin->group->remotes[route->csi].subdev)
++                      continue;
++
++              source = &vin->group->remotes[route->csi].subdev->entity;
++              source_idx = rvin_group_csi_channel_to_pad(route->channel);
++              source_pad = &source->pads[source_idx];
++
++              sink = &vin->group->vin[route->vin]->vdev.entity;
++              sink_pad = &sink->pads[0];
++
++              /* Skip if link already exists. */
++              if (media_entity_find_link(source_pad, sink_pad))
++                      continue;
++
++              ret = media_create_pad_link(source, source_idx, sink, 0, 0);
++              if (ret) {
++                      vin_err(vin, "Error adding link from %s to %s\n",
++                              source->name, sink->name);
++                      break;
++              }
++      }
++      mutex_unlock(&vin->group->lock);
++
++      return ret;
++}
++
++static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
++                                   struct v4l2_subdev *subdev,
++                                   struct v4l2_async_subdev *asd)
++{
++      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
++      unsigned int i;
++
++      for (i = 0; i < RCAR_VIN_NUM; i++)
++              if (vin->group->vin[i])
++                      rvin_v4l2_unregister(vin->group->vin[i]);
++
++      mutex_lock(&vin->group->lock);
++
++      for (i = 0; i < RVIN_CSI_MAX; i++) {
++              if (vin->group->remotes[i].asd != asd)
++                      continue;
++              vin->group->remotes[i].subdev = NULL;
++              vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
++              break;
++      }
++
++      mutex_unlock(&vin->group->lock);
++
++      media_device_unregister(&vin->group->mdev);
++}
++
++static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
++                                 struct v4l2_subdev *subdev,
++                                 struct v4l2_async_subdev *asd)
++{
++      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
++      unsigned int i;
++
++      mutex_lock(&vin->group->lock);
++
++      for (i = 0; i < RVIN_CSI_MAX; i++) {
++              if (vin->group->remotes[i].asd != asd)
++                      continue;
++              vin->group->remotes[i].subdev = subdev;
++              vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
++              break;
++      }
++
++      mutex_unlock(&vin->group->lock);
++
++      return 0;
++}
++
++static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
++      .bound = rvin_group_notify_bound,
++      .unbind = rvin_group_notify_unbind,
++      .complete = rvin_group_notify_complete,
++};
++
++static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id)
++{
++      struct fwnode_handle *ep, *fwnode;
++      struct v4l2_fwnode_endpoint vep = {
++              .bus_type = V4L2_MBUS_CSI2_DPHY,
++      };
++      struct v4l2_async_subdev *asd;
++      int ret;
++
++      ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 1, id, 0);
++      if (!ep)
++              return 0;
++
++      fwnode = fwnode_graph_get_remote_endpoint(ep);
++      ret = v4l2_fwnode_endpoint_parse(ep, &vep);
++      fwnode_handle_put(ep);
++      if (ret) {
++              vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
++              ret = -EINVAL;
++              goto out;
++      }
++
++      if (!of_device_is_available(to_of_node(fwnode))) {
++              vin_dbg(vin, "OF device %pOF disabled, ignoring\n",
++                      to_of_node(fwnode));
++              ret = -ENOTCONN;
++              goto out;
++      }
++
++      asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier,
++                                                  fwnode,
++                                                  struct v4l2_async_subdev);
++      if (IS_ERR(asd)) {
++              ret = PTR_ERR(asd);
++              goto out;
++      }
++
++      vin->group->remotes[vep.base.id].asd = asd;
++
++      vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
++              to_of_node(fwnode), vep.base.id);
++out:
++      fwnode_handle_put(fwnode);
++
++      return ret;
++}
++
+ static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
+ {
+       mutex_lock(&vin->group->lock);
+@@ -393,6 +563,65 @@ static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
+       mutex_unlock(&vin->group->lock);
+ }
++static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
++{
++      unsigned int count = 0, vin_mask = 0;
++      unsigned int i, id;
++      int ret;
++
++      mutex_lock(&vin->group->lock);
++
++      /* If not all VIN's are registered don't register the notifier. */
++      for (i = 0; i < RCAR_VIN_NUM; i++) {
++              if (vin->group->vin[i]) {
++                      count++;
++                      vin_mask |= BIT(i);
++              }
++      }
++
++      if (vin->group->count != count) {
++              mutex_unlock(&vin->group->lock);
++              return 0;
++      }
++
++      mutex_unlock(&vin->group->lock);
++
++      v4l2_async_notifier_init(&vin->group->notifier);
++
++      /*
++       * Have all VIN's look for CSI-2 subdevices. Some subdevices will
++       * overlap but the parser function can handle it, so each subdevice
++       * will only be registered once with the group notifier.
++       */
++      for (i = 0; i < RCAR_VIN_NUM; i++) {
++              if (!(vin_mask & BIT(i)))
++                      continue;
++
++              for (id = 0; id < RVIN_CSI_MAX; id++) {
++                      if (vin->group->remotes[id].asd)
++                              continue;
++
++                      ret = rvin_mc_parse_of(vin->group->vin[i], id);
++                      if (ret)
++                              return ret;
++              }
++      }
++
++      if (list_empty(&vin->group->notifier.asd_list))
++              return 0;
++
++      vin->group->notifier.ops = &rvin_group_notify_ops;
++      ret = v4l2_async_notifier_register(&vin->v4l2_dev,
++                                         &vin->group->notifier);
++      if (ret < 0) {
++              vin_err(vin, "Notifier registration failed\n");
++              v4l2_async_notifier_cleanup(&vin->group->notifier);
++              return ret;
++      }
++
++      return 0;
++}
++
+ /* -----------------------------------------------------------------------------
+  * Controls
+  */
+@@ -721,238 +950,9 @@ static int rvin_parallel_init(struct rvin_dev *vin)
+ }
+ /* -----------------------------------------------------------------------------
+- * Group async notifier
++ * CSI-2
+  */
+-static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
+-{
+-      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
+-      const struct rvin_group_route *route;
+-      unsigned int i;
+-      int ret;
+-
+-      ret = media_device_register(&vin->group->mdev);
+-      if (ret)
+-              return ret;
+-
+-      ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
+-      if (ret) {
+-              vin_err(vin, "Failed to register subdev nodes\n");
+-              return ret;
+-      }
+-
+-      /* Register all video nodes for the group. */
+-      for (i = 0; i < RCAR_VIN_NUM; i++) {
+-              if (vin->group->vin[i] &&
+-                  !video_is_registered(&vin->group->vin[i]->vdev)) {
+-                      ret = rvin_v4l2_register(vin->group->vin[i]);
+-                      if (ret)
+-                              return ret;
+-              }
+-      }
+-
+-      /* Create all media device links between VINs and CSI-2's. */
+-      mutex_lock(&vin->group->lock);
+-      for (route = vin->info->routes; route->mask; route++) {
+-              struct media_pad *source_pad, *sink_pad;
+-              struct media_entity *source, *sink;
+-              unsigned int source_idx;
+-
+-              /* Check that VIN is part of the group. */
+-              if (!vin->group->vin[route->vin])
+-                      continue;
+-
+-              /* Check that VIN' master is part of the group. */
+-              if (!vin->group->vin[rvin_group_id_to_master(route->vin)])
+-                      continue;
+-
+-              /* Check that CSI-2 is part of the group. */
+-              if (!vin->group->remotes[route->csi].subdev)
+-                      continue;
+-
+-              source = &vin->group->remotes[route->csi].subdev->entity;
+-              source_idx = rvin_group_csi_channel_to_pad(route->channel);
+-              source_pad = &source->pads[source_idx];
+-
+-              sink = &vin->group->vin[route->vin]->vdev.entity;
+-              sink_pad = &sink->pads[0];
+-
+-              /* Skip if link already exists. */
+-              if (media_entity_find_link(source_pad, sink_pad))
+-                      continue;
+-
+-              ret = media_create_pad_link(source, source_idx, sink, 0, 0);
+-              if (ret) {
+-                      vin_err(vin, "Error adding link from %s to %s\n",
+-                              source->name, sink->name);
+-                      break;
+-              }
+-      }
+-      mutex_unlock(&vin->group->lock);
+-
+-      return ret;
+-}
+-
+-static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
+-                                   struct v4l2_subdev *subdev,
+-                                   struct v4l2_async_subdev *asd)
+-{
+-      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
+-      unsigned int i;
+-
+-      for (i = 0; i < RCAR_VIN_NUM; i++)
+-              if (vin->group->vin[i])
+-                      rvin_v4l2_unregister(vin->group->vin[i]);
+-
+-      mutex_lock(&vin->group->lock);
+-
+-      for (i = 0; i < RVIN_CSI_MAX; i++) {
+-              if (vin->group->remotes[i].asd != asd)
+-                      continue;
+-              vin->group->remotes[i].subdev = NULL;
+-              vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
+-              break;
+-      }
+-
+-      mutex_unlock(&vin->group->lock);
+-
+-      media_device_unregister(&vin->group->mdev);
+-}
+-
+-static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
+-                                 struct v4l2_subdev *subdev,
+-                                 struct v4l2_async_subdev *asd)
+-{
+-      struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
+-      unsigned int i;
+-
+-      mutex_lock(&vin->group->lock);
+-
+-      for (i = 0; i < RVIN_CSI_MAX; i++) {
+-              if (vin->group->remotes[i].asd != asd)
+-                      continue;
+-              vin->group->remotes[i].subdev = subdev;
+-              vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
+-              break;
+-      }
+-
+-      mutex_unlock(&vin->group->lock);
+-
+-      return 0;
+-}
+-
+-static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
+-      .bound = rvin_group_notify_bound,
+-      .unbind = rvin_group_notify_unbind,
+-      .complete = rvin_group_notify_complete,
+-};
+-
+-static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id)
+-{
+-      struct fwnode_handle *ep, *fwnode;
+-      struct v4l2_fwnode_endpoint vep = {
+-              .bus_type = V4L2_MBUS_CSI2_DPHY,
+-      };
+-      struct v4l2_async_subdev *asd;
+-      int ret;
+-
+-      ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 1, id, 0);
+-      if (!ep)
+-              return 0;
+-
+-      fwnode = fwnode_graph_get_remote_endpoint(ep);
+-      ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+-      fwnode_handle_put(ep);
+-      if (ret) {
+-              vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
+-              ret = -EINVAL;
+-              goto out;
+-      }
+-
+-      if (!of_device_is_available(to_of_node(fwnode))) {
+-              vin_dbg(vin, "OF device %pOF disabled, ignoring\n",
+-                      to_of_node(fwnode));
+-              ret = -ENOTCONN;
+-              goto out;
+-      }
+-
+-      asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier,
+-                                                  fwnode,
+-                                                  struct v4l2_async_subdev);
+-      if (IS_ERR(asd)) {
+-              ret = PTR_ERR(asd);
+-              goto out;
+-      }
+-
+-      vin->group->remotes[vep.base.id].asd = asd;
+-
+-      vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
+-              to_of_node(fwnode), vep.base.id);
+-out:
+-      fwnode_handle_put(fwnode);
+-
+-      return ret;
+-}
+-
+-static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
+-{
+-      unsigned int count = 0, vin_mask = 0;
+-      unsigned int i, id;
+-      int ret;
+-
+-      mutex_lock(&vin->group->lock);
+-
+-      /* If not all VIN's are registered don't register the notifier. */
+-      for (i = 0; i < RCAR_VIN_NUM; i++) {
+-              if (vin->group->vin[i]) {
+-                      count++;
+-                      vin_mask |= BIT(i);
+-              }
+-      }
+-
+-      if (vin->group->count != count) {
+-              mutex_unlock(&vin->group->lock);
+-              return 0;
+-      }
+-
+-      mutex_unlock(&vin->group->lock);
+-
+-      v4l2_async_notifier_init(&vin->group->notifier);
+-
+-      /*
+-       * Have all VIN's look for CSI-2 subdevices. Some subdevices will
+-       * overlap but the parser function can handle it, so each subdevice
+-       * will only be registered once with the group notifier.
+-       */
+-      for (i = 0; i < RCAR_VIN_NUM; i++) {
+-              if (!(vin_mask & BIT(i)))
+-                      continue;
+-
+-              for (id = 0; id < RVIN_CSI_MAX; id++) {
+-                      if (vin->group->remotes[id].asd)
+-                              continue;
+-
+-                      ret = rvin_mc_parse_of(vin->group->vin[i], id);
+-                      if (ret)
+-                              return ret;
+-              }
+-      }
+-
+-      if (list_empty(&vin->group->notifier.asd_list))
+-              return 0;
+-
+-      vin->group->notifier.ops = &rvin_group_notify_ops;
+-      ret = v4l2_async_notifier_register(&vin->v4l2_dev,
+-                                         &vin->group->notifier);
+-      if (ret < 0) {
+-              vin_err(vin, "Notifier registration failed\n");
+-              v4l2_async_notifier_cleanup(&vin->group->notifier);
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+ static void rvin_csi2_cleanup(struct rvin_dev *vin)
+ {
+       if (!vin->info->use_mc)
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch b/queue-5.15/media-rcar-vin-refactor-controls-creation-for-video-.patch
new file mode 100644 (file)
index 0000000..82b5d3a
--- /dev/null
@@ -0,0 +1,164 @@
+From 74d2f9b2f92e12a66216f4cad650e2731d3d8540 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jul 2021 16:25:50 +0200
+Subject: media: rcar-vin: Refactor controls creation for video device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+
+[ Upstream commit b2dc5680aeb418deeacbe9628697fa0b0f2dc54a ]
+
+The controls for the video device are created in different code paths
+depending on if the driver is using the media graph centric model (Gen3)
+or the device centric model (Gen2 and earlier). This have lead to code
+duplication that can be consolidated.
+
+Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/rcar-vin/rcar-core.c | 82 +++++++++++----------
+ 1 file changed, 45 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index 33957cc9118ca..6ea561fcd7a39 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -405,6 +405,45 @@ static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
+       .s_ctrl = rvin_s_ctrl,
+ };
++static void rvin_free_controls(struct rvin_dev *vin)
++{
++      v4l2_ctrl_handler_free(&vin->ctrl_handler);
++      vin->vdev.ctrl_handler = NULL;
++}
++
++static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
++{
++      int ret;
++
++      ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
++      if (ret < 0)
++              return ret;
++
++      /* The VIN directly deals with alpha component. */
++      v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
++                        V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
++
++      if (vin->ctrl_handler.error) {
++              ret = vin->ctrl_handler.error;
++              rvin_free_controls(vin);
++              return ret;
++      }
++
++      /* For the non-MC mode add controls from the subdevice. */
++      if (subdev) {
++              ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
++                                          subdev->ctrl_handler, NULL, true);
++              if (ret < 0) {
++                      rvin_free_controls(vin);
++                      return ret;
++              }
++      }
++
++      vin->vdev.ctrl_handler = &vin->ctrl_handler;
++
++      return 0;
++}
++
+ /* -----------------------------------------------------------------------------
+  * Async notifier
+  */
+@@ -490,28 +529,10 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
+               return ret;
+       /* Add the controls */
+-      ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
++      ret = rvin_create_controls(vin, subdev);
+       if (ret < 0)
+               return ret;
+-      v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
+-                        V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
+-
+-      if (vin->ctrl_handler.error) {
+-              ret = vin->ctrl_handler.error;
+-              v4l2_ctrl_handler_free(&vin->ctrl_handler);
+-              return ret;
+-      }
+-
+-      ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
+-                                  NULL, true);
+-      if (ret < 0) {
+-              v4l2_ctrl_handler_free(&vin->ctrl_handler);
+-              return ret;
+-      }
+-
+-      vin->vdev.ctrl_handler = &vin->ctrl_handler;
+-
+       vin->parallel.subdev = subdev;
+       return 0;
+@@ -522,10 +543,8 @@ static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
+       rvin_v4l2_unregister(vin);
+       vin->parallel.subdev = NULL;
+-      if (!vin->info->use_mc) {
+-              v4l2_ctrl_handler_free(&vin->ctrl_handler);
+-              vin->vdev.ctrl_handler = NULL;
+-      }
++      if (!vin->info->use_mc)
++              rvin_free_controls(vin);
+ }
+ static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
+@@ -935,21 +954,10 @@ static int rvin_mc_init(struct rvin_dev *vin)
+       if (ret)
+               rvin_group_put(vin);
+-      ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
++      ret = rvin_create_controls(vin, NULL);
+       if (ret < 0)
+               return ret;
+-      v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
+-                        V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
+-
+-      if (vin->ctrl_handler.error) {
+-              ret = vin->ctrl_handler.error;
+-              v4l2_ctrl_handler_free(&vin->ctrl_handler);
+-              return ret;
+-      }
+-
+-      vin->vdev.ctrl_handler = &vin->ctrl_handler;
+-
+       return ret;
+ }
+@@ -1450,7 +1458,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+       return 0;
+ error_group_unregister:
+-      v4l2_ctrl_handler_free(&vin->ctrl_handler);
++      rvin_free_controls(vin);
+       if (vin->info->use_mc) {
+               mutex_lock(&vin->group->lock);
+@@ -1485,7 +1493,7 @@ static int rcar_vin_remove(struct platform_device *pdev)
+               rvin_group_put(vin);
+       }
+-      v4l2_ctrl_handler_free(&vin->ctrl_handler);
++      rvin_free_controls(vin);
+       rvin_dma_unregister(vin);
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch b/queue-5.15/media-rcar-vin-rename-array-storing-subdevice-inform.patch
new file mode 100644 (file)
index 0000000..93f7092
--- /dev/null
@@ -0,0 +1,165 @@
+From e97f8defd2cb0817e26dcab2e9e5ae1b8c2abd3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jul 2021 16:25:54 +0200
+Subject: media: rcar-vin: Rename array storing subdevice information
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+
+[ Upstream commit 161b56a82dba29c70fd92c5eb1a8502731a0c832 ]
+
+The VIN group have always been connected to CSI-2 receivers and this
+have spilled over to the naming of the array storing the subdevice
+information. In preparation for connecting other types of subdevices
+rename the array to remotes.
+
+Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/rcar-vin/rcar-core.c | 32 ++++++++++-----------
+ drivers/media/platform/rcar-vin/rcar-vin.h  |  8 ++++--
+ 2 files changed, 21 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index 93a32be692e9a..867d8fd7a77d3 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -49,16 +49,16 @@
+  */
+ /* group lock should be held when calling this function. */
+-static int rvin_group_entity_to_csi_id(struct rvin_group *group,
+-                                     struct media_entity *entity)
++static int rvin_group_entity_to_remote_id(struct rvin_group *group,
++                                        struct media_entity *entity)
+ {
+       struct v4l2_subdev *sd;
+       unsigned int i;
+       sd = media_entity_to_v4l2_subdev(entity);
+-      for (i = 0; i < RVIN_CSI_MAX; i++)
+-              if (group->csi[i].subdev == sd)
++      for (i = 0; i < RVIN_REMOTES_MAX; i++)
++              if (group->remotes[i].subdev == sd)
+                       return i;
+       return -ENODEV;
+@@ -163,14 +163,14 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags,
+               if (!csi_pad)
+                       continue;
+-              csi_id = rvin_group_entity_to_csi_id(group, csi_pad->entity);
++              csi_id = rvin_group_entity_to_remote_id(group, csi_pad->entity);
+               channel = rvin_group_csi_pad_to_channel(csi_pad->index);
+               mask &= rvin_group_get_mask(group->vin[i], csi_id, channel);
+       }
+       /* Add the new link to the existing mask and check if it works. */
+-      csi_id = rvin_group_entity_to_csi_id(group, link->source->entity);
++      csi_id = rvin_group_entity_to_remote_id(group, link->source->entity);
+       if (csi_id == -ENODEV) {
+               struct v4l2_subdev *sd;
+@@ -767,10 +767,10 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier)
+                       continue;
+               /* Check that CSI-2 is part of the group. */
+-              if (!vin->group->csi[route->csi].subdev)
++              if (!vin->group->remotes[route->csi].subdev)
+                       continue;
+-              source = &vin->group->csi[route->csi].subdev->entity;
++              source = &vin->group->remotes[route->csi].subdev->entity;
+               source_idx = rvin_group_csi_channel_to_pad(route->channel);
+               source_pad = &source->pads[source_idx];
+@@ -807,10 +807,10 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
+       mutex_lock(&vin->group->lock);
+       for (i = 0; i < RVIN_CSI_MAX; i++) {
+-              if (vin->group->csi[i].asd != asd)
++              if (vin->group->remotes[i].asd != asd)
+                       continue;
+-              vin->group->csi[i].subdev = NULL;
+-              vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i);
++              vin->group->remotes[i].subdev = NULL;
++              vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
+               break;
+       }
+@@ -829,10 +829,10 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
+       mutex_lock(&vin->group->lock);
+       for (i = 0; i < RVIN_CSI_MAX; i++) {
+-              if (vin->group->csi[i].asd != asd)
++              if (vin->group->remotes[i].asd != asd)
+                       continue;
+-              vin->group->csi[i].subdev = subdev;
+-              vin_dbg(vin, "Bound CSI-2 %s to slot %u\n", subdev->name, i);
++              vin->group->remotes[i].subdev = subdev;
++              vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
+               break;
+       }
+@@ -884,7 +884,7 @@ static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id)
+               goto out;
+       }
+-      vin->group->csi[vep.base.id].asd = asd;
++      vin->group->remotes[vep.base.id].asd = asd;
+       vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
+               to_of_node(fwnode), vep.base.id);
+@@ -929,7 +929,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
+                       continue;
+               for (id = 0; id < RVIN_CSI_MAX; id++) {
+-                      if (vin->group->csi[id].asd)
++                      if (vin->group->remotes[id].asd)
+                               continue;
+                       ret = rvin_mc_parse_of(vin->group->vin[i], id);
+diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
+index b263ead4db2bf..39207aaf39ef9 100644
+--- a/drivers/media/platform/rcar-vin/rcar-vin.h
++++ b/drivers/media/platform/rcar-vin/rcar-vin.h
+@@ -48,6 +48,8 @@ enum rvin_csi_id {
+       RVIN_CSI_MAX,
+ };
++#define RVIN_REMOTES_MAX RVIN_CSI_MAX
++
+ /**
+  * enum rvin_dma_state - DMA states
+  * @STOPPED:   No operation in progress
+@@ -267,8 +269,8 @@ struct rvin_dev {
+  * @count:            number of enabled VIN instances found in DT
+  * @notifier:         group notifier for CSI-2 async subdevices
+  * @vin:              VIN instances which are part of the group
+- * @csi:              array of pairs of fwnode and subdev pointers
+- *                    to all CSI-2 subdevices.
++ * @remotes:          array of pairs of fwnode and subdev pointers
++ *                    to all remote subdevices.
+  */
+ struct rvin_group {
+       struct kref refcount;
+@@ -283,7 +285,7 @@ struct rvin_group {
+       struct {
+               struct v4l2_async_subdev *asd;
+               struct v4l2_subdev *subdev;
+-      } csi[RVIN_CSI_MAX];
++      } remotes[RVIN_REMOTES_MAX];
+ };
+ int rvin_dma_register(struct rvin_dev *vin, int irq);
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-s3c-camif-avoid-inappropriate-kfree.patch b/queue-5.15/media-s3c-camif-avoid-inappropriate-kfree.patch
new file mode 100644 (file)
index 0000000..30fa8a4
--- /dev/null
@@ -0,0 +1,54 @@
+From 11146f33ed2d6ba7198dc674e9a438cbf03abdec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 14:55:06 +0300
+Subject: media: s3c-camif: Avoid inappropriate kfree()
+
+From: Katya Orlova <e.orlova@ispras.ru>
+
+[ Upstream commit 61334819aca018c3416ee6c330a08a49c1524fc3 ]
+
+s3c_camif_register_video_node() works with video_device structure stored
+as a field of camif_vp, so it should not be kfreed.
+But there is video_device_release() on error path that do it.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: babde1c243b2 ("[media] V4L: Add driver for S3C24XX/S3C64XX SoC series camera interface")
+Signed-off-by: Katya Orlova <e.orlova@ispras.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s3c-camif/camif-capture.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
+index 140854ab4dd8c..d6b7fbd49a5cc 100644
+--- a/drivers/media/platform/s3c-camif/camif-capture.c
++++ b/drivers/media/platform/s3c-camif/camif-capture.c
+@@ -1132,12 +1132,12 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
+       ret = vb2_queue_init(q);
+       if (ret)
+-              goto err_vd_rel;
++              return ret;
+       vp->pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad);
+       if (ret)
+-              goto err_vd_rel;
++              return ret;
+       video_set_drvdata(vfd, vp);
+@@ -1170,8 +1170,6 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
+       v4l2_ctrl_handler_free(&vp->ctrl_handler);
+ err_me_cleanup:
+       media_entity_cleanup(&vfd->entity);
+-err_vd_rel:
+-      video_device_release(vfd);
+       return ret;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch b/queue-5.15/media-v4l-async-rename-async-nf-functions-clean-up-l.patch
new file mode 100644 (file)
index 0000000..d1d52f8
--- /dev/null
@@ -0,0 +1,2923 @@
+From 9da6daba0739fbf48b32eaa2695cd30c7d12b1de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Mar 2021 18:13:12 +0100
+Subject: media: v4l: async: Rename async nf functions, clean up long lines
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit 3c8c153914812a98eaa0b5a6cf09c511a06aafbe ]
+
+Rename V4L2 async notifier functions, replacing "notifier" with "nf" and
+removing "_subdev" at the end of the function names adding subdevs as you
+can only add subdevs to a notifier. Also wrap and otherwise clean up long
+lines.
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
+Reviewed-by: Rui Miguel Silva <rmfrfs@gmail.com> (imx7)
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: b2701715301a ("media: cadence: csi2rx: Unregister v4l2 async notifier")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../driver-api/media/v4l2-subdev.rst          |  14 +-
+ drivers/media/i2c/max9286.c                   |  17 +-
+ drivers/media/i2c/st-mipid02.c                |  22 ++-
+ drivers/media/pci/intel/ipu3/ipu3-cio2-main.c |  17 +-
+ drivers/media/platform/am437x/am437x-vpfe.c   |  19 +-
+ drivers/media/platform/atmel/atmel-isc-base.c |   4 +-
+ drivers/media/platform/atmel/atmel-isi.c      |  17 +-
+ .../media/platform/atmel/atmel-sama5d2-isc.c  |  15 +-
+ .../media/platform/atmel/atmel-sama7g5-isc.c  |  15 +-
+ drivers/media/platform/cadence/cdns-csi2rx.c  |  14 +-
+ drivers/media/platform/davinci/vpif_capture.c |  21 +--
+ drivers/media/platform/exynos4-is/media-dev.c |  20 +--
+ .../media/platform/marvell-ccic/cafe-driver.c |   9 +-
+ .../media/platform/marvell-ccic/mcam-core.c   |  10 +-
+ .../media/platform/marvell-ccic/mmp-driver.c  |   6 +-
+ drivers/media/platform/omap3isp/isp.c         |  21 ++-
+ drivers/media/platform/pxa_camera.c           |  26 ++-
+ drivers/media/platform/qcom/camss/camss.c     |  18 +-
+ drivers/media/platform/rcar-vin/rcar-core.c   |  30 ++--
+ drivers/media/platform/rcar-vin/rcar-csi2.c   |  19 +-
+ drivers/media/platform/rcar_drif.c            |  14 +-
+ drivers/media/platform/renesas-ceu.c          |  29 ++-
+ .../platform/rockchip/rkisp1/rkisp1-dev.c     |  17 +-
+ drivers/media/platform/stm32/stm32-dcmi.c     |  18 +-
+ .../platform/sunxi/sun4i-csi/sun4i_csi.c      |  12 +-
+ .../platform/sunxi/sun6i-csi/sun6i_csi.c      |  19 +-
+ drivers/media/platform/ti-vpe/cal.c           |  16 +-
+ drivers/media/platform/video-mux.c            |  17 +-
+ drivers/media/platform/xilinx/xilinx-vipp.c   |  17 +-
+ drivers/media/v4l2-core/v4l2-async.c          | 168 +++++++++---------
+ drivers/media/v4l2-core/v4l2-fwnode.c         |  74 ++++----
+ drivers/staging/media/imx/imx-media-csi.c     |  17 +-
+ .../staging/media/imx/imx-media-dev-common.c  |   7 +-
+ drivers/staging/media/imx/imx-media-dev.c     |   6 +-
+ drivers/staging/media/imx/imx-media-of.c      |   6 +-
+ drivers/staging/media/imx/imx6-mipi-csi2.c    |  17 +-
+ drivers/staging/media/imx/imx7-media-csi.c    |  24 +--
+ drivers/staging/media/imx/imx7-mipi-csis.c    |  16 +-
+ drivers/staging/media/imx/imx8mq-mipi-csi2.c  |  16 +-
+ drivers/staging/media/tegra-video/vi.c        |  17 +-
+ include/media/v4l2-async.h                    | 105 ++++++-----
+ include/media/v4l2-fwnode.h                   |  12 +-
+ 42 files changed, 479 insertions(+), 499 deletions(-)
+
+diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
+index 7736da077fb87..08ea2673b19e3 100644
+--- a/Documentation/driver-api/media/v4l2-subdev.rst
++++ b/Documentation/driver-api/media/v4l2-subdev.rst
+@@ -191,21 +191,21 @@ registered this way are stored in a global list of subdevices, ready to be
+ picked up by bridge drivers.
+ Bridge drivers in turn have to register a notifier object. This is
+-performed using the :c:func:`v4l2_async_notifier_register` call. To
++performed using the :c:func:`v4l2_async_nf_register` call. To
+ unregister the notifier the driver has to call
+-:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
++:c:func:`v4l2_async_nf_unregister`. The former of the two functions
+ takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
+ pointer to struct :c:type:`v4l2_async_notifier`.
+ Before registering the notifier, bridge drivers must do two things: first, the
+-notifier must be initialized using the :c:func:`v4l2_async_notifier_init`.
++notifier must be initialized using the :c:func:`v4l2_async_nf_init`.
+ Second, bridge drivers can then begin to form a list of subdevice descriptors
+ that the bridge device needs for its operation. Several functions are available
+ to add subdevice descriptors to a notifier, depending on the type of device and
+ the needs of the driver.
+-:c:func:`v4l2_async_notifier_add_fwnode_remote_subdev` and
+-:c:func:`v4l2_async_notifier_add_i2c_subdev` are for bridge and ISP drivers for
++:c:func:`v4l2_async_nf_add_fwnode_remote` and
++:c:func:`v4l2_async_nf_add_i2c` are for bridge and ISP drivers for
+ registering their async sub-devices with the notifier.
+ :c:func:`v4l2_async_register_subdev_sensor` is a helper function for
+@@ -230,8 +230,8 @@ These functions allocate an async sub-device descriptor which is of type struct
+       ...
+-      my_asd = v4l2_async_notifier_add_fwnode_remote_subdev(&notifier, ep,
+-                                                            struct my_async_subdev);
++      my_asd = v4l2_async_nf_add_fwnode_remote(&notifier, ep,
++                                               struct my_async_subdev);
+       fwnode_handle_put(ep);
+       if (IS_ERR(asd))
+diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
+index 1b9beaee6bea7..b5fed8a52c44b 100644
+--- a/drivers/media/i2c/max9286.c
++++ b/drivers/media/i2c/max9286.c
+@@ -609,19 +609,18 @@ static int max9286_v4l2_notifier_register(struct max9286_priv *priv)
+       if (!priv->nsources)
+               return 0;
+-      v4l2_async_notifier_init(&priv->notifier);
++      v4l2_async_nf_init(&priv->notifier);
+       for_each_source(priv, source) {
+               unsigned int i = to_index(priv, source);
+               struct max9286_asd *mas;
+-              mas = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier,
+-                                                          source->fwnode,
+-                                                          struct max9286_asd);
++              mas = v4l2_async_nf_add_fwnode(&priv->notifier, source->fwnode,
++                                             struct max9286_asd);
+               if (IS_ERR(mas)) {
+                       dev_err(dev, "Failed to add subdev for source %u: %ld",
+                               i, PTR_ERR(mas));
+-                      v4l2_async_notifier_cleanup(&priv->notifier);
++                      v4l2_async_nf_cleanup(&priv->notifier);
+                       return PTR_ERR(mas);
+               }
+@@ -630,10 +629,10 @@ static int max9286_v4l2_notifier_register(struct max9286_priv *priv)
+       priv->notifier.ops = &max9286_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&priv->sd, &priv->notifier);
++      ret = v4l2_async_subdev_nf_register(&priv->sd, &priv->notifier);
+       if (ret) {
+               dev_err(dev, "Failed to register subdev_notifier");
+-              v4l2_async_notifier_cleanup(&priv->notifier);
++              v4l2_async_nf_cleanup(&priv->notifier);
+               return ret;
+       }
+@@ -645,8 +644,8 @@ static void max9286_v4l2_notifier_unregister(struct max9286_priv *priv)
+       if (!priv->nsources)
+               return;
+-      v4l2_async_notifier_unregister(&priv->notifier);
+-      v4l2_async_notifier_cleanup(&priv->notifier);
++      v4l2_async_nf_unregister(&priv->notifier);
++      v4l2_async_nf_cleanup(&priv->notifier);
+ }
+ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
+diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
+index cf55c57a79707..f8615d95b4826 100644
+--- a/drivers/media/i2c/st-mipid02.c
++++ b/drivers/media/i2c/st-mipid02.c
+@@ -881,11 +881,10 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
+       bridge->rx = ep;
+       /* register async notifier so we get noticed when sensor is connected */
+-      v4l2_async_notifier_init(&bridge->notifier);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                                      &bridge->notifier,
+-                                      of_fwnode_handle(ep_node),
+-                                      struct v4l2_async_subdev);
++      v4l2_async_nf_init(&bridge->notifier);
++      asd = v4l2_async_nf_add_fwnode_remote(&bridge->notifier,
++                                            of_fwnode_handle(ep_node),
++                                            struct v4l2_async_subdev);
+       of_node_put(ep_node);
+       if (IS_ERR(asd)) {
+@@ -895,10 +894,9 @@ static int mipid02_parse_rx_ep(struct mipid02_dev *bridge)
+       }
+       bridge->notifier.ops = &mipid02_notifier_ops;
+-      ret = v4l2_async_subdev_notifier_register(&bridge->sd,
+-                                                &bridge->notifier);
++      ret = v4l2_async_subdev_nf_register(&bridge->sd, &bridge->notifier);
+       if (ret)
+-              v4l2_async_notifier_cleanup(&bridge->notifier);
++              v4l2_async_nf_cleanup(&bridge->notifier);
+       return ret;
+@@ -1036,8 +1034,8 @@ static int mipid02_probe(struct i2c_client *client)
+       return 0;
+ unregister_notifier:
+-      v4l2_async_notifier_unregister(&bridge->notifier);
+-      v4l2_async_notifier_cleanup(&bridge->notifier);
++      v4l2_async_nf_unregister(&bridge->notifier);
++      v4l2_async_nf_cleanup(&bridge->notifier);
+ power_off:
+       mipid02_set_power_off(bridge);
+ entity_cleanup:
+@@ -1053,8 +1051,8 @@ static int mipid02_remove(struct i2c_client *client)
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct mipid02_dev *bridge = to_mipid02_dev(sd);
+-      v4l2_async_notifier_unregister(&bridge->notifier);
+-      v4l2_async_notifier_cleanup(&bridge->notifier);
++      v4l2_async_nf_unregister(&bridge->notifier);
++      v4l2_async_nf_cleanup(&bridge->notifier);
+       v4l2_async_unregister_subdev(&bridge->sd);
+       mipid02_set_power_off(bridge);
+       media_entity_cleanup(&bridge->sd.entity);
+diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+index 162ab089124f3..00e2225f1ea3d 100644
+--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+@@ -1478,8 +1478,9 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
+               if (ret)
+                       goto err_parse;
+-              s_asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                              &cio2->notifier, ep, struct sensor_async_subdev);
++              s_asd = v4l2_async_nf_add_fwnode_remote(&cio2->notifier, ep,
++                                                      struct
++                                                      sensor_async_subdev);
+               if (IS_ERR(s_asd)) {
+                       ret = PTR_ERR(s_asd);
+                       goto err_parse;
+@@ -1502,7 +1503,7 @@ static int cio2_parse_firmware(struct cio2_device *cio2)
+        * suspend.
+        */
+       cio2->notifier.ops = &cio2_async_ops;
+-      ret = v4l2_async_notifier_register(&cio2->v4l2_dev, &cio2->notifier);
++      ret = v4l2_async_nf_register(&cio2->v4l2_dev, &cio2->notifier);
+       if (ret)
+               dev_err(&cio2->pci_dev->dev,
+                       "failed to register async notifier : %d\n", ret);
+@@ -1804,7 +1805,7 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
+       if (r)
+               goto fail_v4l2_device_unregister;
+-      v4l2_async_notifier_init(&cio2->notifier);
++      v4l2_async_nf_init(&cio2->notifier);
+       /* Register notifier for subdevices we care */
+       r = cio2_parse_firmware(cio2);
+@@ -1824,8 +1825,8 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
+       return 0;
+ fail_clean_notifier:
+-      v4l2_async_notifier_unregister(&cio2->notifier);
+-      v4l2_async_notifier_cleanup(&cio2->notifier);
++      v4l2_async_nf_unregister(&cio2->notifier);
++      v4l2_async_nf_cleanup(&cio2->notifier);
+       cio2_queues_exit(cio2);
+ fail_v4l2_device_unregister:
+       v4l2_device_unregister(&cio2->v4l2_dev);
+@@ -1844,8 +1845,8 @@ static void cio2_pci_remove(struct pci_dev *pci_dev)
+       struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+       media_device_unregister(&cio2->media_dev);
+-      v4l2_async_notifier_unregister(&cio2->notifier);
+-      v4l2_async_notifier_cleanup(&cio2->notifier);
++      v4l2_async_nf_unregister(&cio2->notifier);
++      v4l2_async_nf_cleanup(&cio2->notifier);
+       cio2_queues_exit(cio2);
+       cio2_fbpt_exit_dummy(cio2);
+       v4l2_device_unregister(&cio2->v4l2_dev);
+diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
+index c1ce93efc6559..38fe7f67d51e5 100644
+--- a/drivers/media/platform/am437x/am437x-vpfe.c
++++ b/drivers/media/platform/am437x/am437x-vpfe.c
+@@ -2298,7 +2298,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe)
+       dev_dbg(dev, "vpfe_get_pdata\n");
+-      v4l2_async_notifier_init(&vpfe->notifier);
++      v4l2_async_nf_init(&vpfe->notifier);
+       if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
+               return dev->platform_data;
+@@ -2366,9 +2366,10 @@ vpfe_get_pdata(struct vpfe_device *vpfe)
+                       goto cleanup;
+               }
+-              pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
+-                      &vpfe->notifier, of_fwnode_handle(rem),
+-                      struct v4l2_async_subdev);
++              pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpfe->notifier,
++                                                       of_fwnode_handle(rem),
++                                                       struct
++                                                       v4l2_async_subdev);
+               of_node_put(rem);
+               if (IS_ERR(pdata->asd[i]))
+                       goto cleanup;
+@@ -2378,7 +2379,7 @@ vpfe_get_pdata(struct vpfe_device *vpfe)
+       return pdata;
+ cleanup:
+-      v4l2_async_notifier_cleanup(&vpfe->notifier);
++      v4l2_async_nf_cleanup(&vpfe->notifier);
+       of_node_put(endpoint);
+       return NULL;
+ }
+@@ -2466,7 +2467,7 @@ static int vpfe_probe(struct platform_device *pdev)
+       }
+       vpfe->notifier.ops = &vpfe_async_ops;
+-      ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, &vpfe->notifier);
++      ret = v4l2_async_nf_register(&vpfe->v4l2_dev, &vpfe->notifier);
+       if (ret) {
+               vpfe_err(vpfe, "Error registering async notifier\n");
+               ret = -EINVAL;
+@@ -2478,7 +2479,7 @@ static int vpfe_probe(struct platform_device *pdev)
+ probe_out_v4l2_unregister:
+       v4l2_device_unregister(&vpfe->v4l2_dev);
+ probe_out_cleanup:
+-      v4l2_async_notifier_cleanup(&vpfe->notifier);
++      v4l2_async_nf_cleanup(&vpfe->notifier);
+       return ret;
+ }
+@@ -2491,8 +2492,8 @@ static int vpfe_remove(struct platform_device *pdev)
+       pm_runtime_disable(&pdev->dev);
+-      v4l2_async_notifier_unregister(&vpfe->notifier);
+-      v4l2_async_notifier_cleanup(&vpfe->notifier);
++      v4l2_async_nf_unregister(&vpfe->notifier);
++      v4l2_async_nf_cleanup(&vpfe->notifier);
+       v4l2_device_unregister(&vpfe->v4l2_dev);
+       video_unregister_device(&vpfe->video_dev);
+diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
+index f768be3c40595..24807782c9e50 100644
+--- a/drivers/media/platform/atmel/atmel-isc-base.c
++++ b/drivers/media/platform/atmel/atmel-isc-base.c
+@@ -2217,8 +2217,8 @@ void isc_subdev_cleanup(struct isc_device *isc)
+       struct isc_subdev_entity *subdev_entity;
+       list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
+-              v4l2_async_notifier_unregister(&subdev_entity->notifier);
+-              v4l2_async_notifier_cleanup(&subdev_entity->notifier);
++              v4l2_async_nf_unregister(&subdev_entity->notifier);
++              v4l2_async_nf_cleanup(&subdev_entity->notifier);
+       }
+       INIT_LIST_HEAD(&isc->subdev_entities);
+diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
+index 095d80c4f59e7..4d15814e4481c 100644
+--- a/drivers/media/platform/atmel/atmel-isi.c
++++ b/drivers/media/platform/atmel/atmel-isi.c
+@@ -1159,12 +1159,11 @@ static int isi_graph_init(struct atmel_isi *isi)
+       if (!ep)
+               return -EINVAL;
+-      v4l2_async_notifier_init(&isi->notifier);
++      v4l2_async_nf_init(&isi->notifier);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                                              &isi->notifier,
+-                                              of_fwnode_handle(ep),
+-                                              struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&isi->notifier,
++                                            of_fwnode_handle(ep),
++                                            struct v4l2_async_subdev);
+       of_node_put(ep);
+       if (IS_ERR(asd))
+@@ -1172,10 +1171,10 @@ static int isi_graph_init(struct atmel_isi *isi)
+       isi->notifier.ops = &isi_graph_notify_ops;
+-      ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
++      ret = v4l2_async_nf_register(&isi->v4l2_dev, &isi->notifier);
+       if (ret < 0) {
+               dev_err(isi->dev, "Notifier registration failed\n");
+-              v4l2_async_notifier_cleanup(&isi->notifier);
++              v4l2_async_nf_cleanup(&isi->notifier);
+               return ret;
+       }
+@@ -1327,8 +1326,8 @@ static int atmel_isi_remove(struct platform_device *pdev)
+                       isi->p_fb_descriptors,
+                       isi->fb_descriptors_phys);
+       pm_runtime_disable(&pdev->dev);
+-      v4l2_async_notifier_unregister(&isi->notifier);
+-      v4l2_async_notifier_cleanup(&isi->notifier);
++      v4l2_async_nf_unregister(&isi->notifier);
++      v4l2_async_nf_cleanup(&isi->notifier);
+       v4l2_device_unregister(&isi->v4l2_dev);
+       return 0;
+diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+index 7421bc51709c4..a1fd240c6aeb8 100644
+--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+@@ -499,13 +499,14 @@ static int atmel_isc_probe(struct platform_device *pdev)
+       list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
+               struct v4l2_async_subdev *asd;
++              struct fwnode_handle *fwnode =
++                      of_fwnode_handle(subdev_entity->epn);
+-              v4l2_async_notifier_init(&subdev_entity->notifier);
++              v4l2_async_nf_init(&subdev_entity->notifier);
+-              asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                                      &subdev_entity->notifier,
+-                                      of_fwnode_handle(subdev_entity->epn),
+-                                      struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier,
++                                                    fwnode,
++                                                    struct v4l2_async_subdev);
+               of_node_put(subdev_entity->epn);
+               subdev_entity->epn = NULL;
+@@ -517,8 +518,8 @@ static int atmel_isc_probe(struct platform_device *pdev)
+               subdev_entity->notifier.ops = &isc_async_ops;
+-              ret = v4l2_async_notifier_register(&isc->v4l2_dev,
+-                                                 &subdev_entity->notifier);
++              ret = v4l2_async_nf_register(&isc->v4l2_dev,
++                                           &subdev_entity->notifier);
+               if (ret) {
+                       dev_err(dev, "fail to register async notifier\n");
+                       goto cleanup_subdev;
+diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+index a4defc30cf412..366f2afcda193 100644
+--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
++++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+@@ -493,13 +493,14 @@ static int microchip_xisc_probe(struct platform_device *pdev)
+       list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
+               struct v4l2_async_subdev *asd;
++              struct fwnode_handle *fwnode =
++                      of_fwnode_handle(subdev_entity->epn);
+-              v4l2_async_notifier_init(&subdev_entity->notifier);
++              v4l2_async_nf_init(&subdev_entity->notifier);
+-              asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                                      &subdev_entity->notifier,
+-                                      of_fwnode_handle(subdev_entity->epn),
+-                                      struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier,
++                                                    fwnode,
++                                                    struct v4l2_async_subdev);
+               of_node_put(subdev_entity->epn);
+               subdev_entity->epn = NULL;
+@@ -511,8 +512,8 @@ static int microchip_xisc_probe(struct platform_device *pdev)
+               subdev_entity->notifier.ops = &isc_async_ops;
+-              ret = v4l2_async_notifier_register(&isc->v4l2_dev,
+-                                                 &subdev_entity->notifier);
++              ret = v4l2_async_nf_register(&isc->v4l2_dev,
++                                           &subdev_entity->notifier);
+               if (ret) {
+                       dev_err(dev, "fail to register async notifier\n");
+                       goto cleanup_subdev;
+diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
+index f2b4ddd31177b..7b44ab2b8c9ad 100644
+--- a/drivers/media/platform/cadence/cdns-csi2rx.c
++++ b/drivers/media/platform/cadence/cdns-csi2rx.c
+@@ -401,21 +401,19 @@ static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
+               return -EINVAL;
+       }
+-      v4l2_async_notifier_init(&csi2rx->notifier);
++      v4l2_async_nf_init(&csi2rx->notifier);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi2rx->notifier,
+-                                                         fwh,
+-                                                         struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
++                                            struct v4l2_async_subdev);
+       of_node_put(ep);
+       if (IS_ERR(asd))
+               return PTR_ERR(asd);
+       csi2rx->notifier.ops = &csi2rx_notifier_ops;
+-      ret = v4l2_async_subdev_notifier_register(&csi2rx->subdev,
+-                                                &csi2rx->notifier);
++      ret = v4l2_async_subdev_nf_register(&csi2rx->subdev, &csi2rx->notifier);
+       if (ret)
+-              v4l2_async_notifier_cleanup(&csi2rx->notifier);
++              v4l2_async_nf_cleanup(&csi2rx->notifier);
+       return ret;
+ }
+@@ -471,7 +469,7 @@ static int csi2rx_probe(struct platform_device *pdev)
+       return 0;
+ err_cleanup:
+-      v4l2_async_notifier_cleanup(&csi2rx->notifier);
++      v4l2_async_nf_cleanup(&csi2rx->notifier);
+ err_free_priv:
+       kfree(csi2rx);
+       return ret;
+diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
+index c034e25dd9aae..ae92e2c206d04 100644
+--- a/drivers/media/platform/davinci/vpif_capture.c
++++ b/drivers/media/platform/davinci/vpif_capture.c
+@@ -1506,7 +1506,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
+       struct vpif_capture_chan_config *chan;
+       unsigned int i;
+-      v4l2_async_notifier_init(&vpif_obj.notifier);
++      v4l2_async_nf_init(&vpif_obj.notifier);
+       /*
+        * DT boot: OF node from parent device contains
+@@ -1582,9 +1582,10 @@ vpif_capture_get_pdata(struct platform_device *pdev)
+               dev_dbg(&pdev->dev, "Remote device %pOF found\n", rem);
+               sdinfo->name = rem->full_name;
+-              pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
+-                      &vpif_obj.notifier, of_fwnode_handle(rem),
+-                      struct v4l2_async_subdev);
++              pdata->asd[i] = v4l2_async_nf_add_fwnode(&vpif_obj.notifier,
++                                                       of_fwnode_handle(rem),
++                                                       struct
++                                                       v4l2_async_subdev);
+               if (IS_ERR(pdata->asd[i]))
+                       goto err_cleanup;
+@@ -1602,7 +1603,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
+ err_cleanup:
+       of_node_put(rem);
+       of_node_put(endpoint);
+-      v4l2_async_notifier_cleanup(&vpif_obj.notifier);
++      v4l2_async_nf_cleanup(&vpif_obj.notifier);
+       return NULL;
+ }
+@@ -1692,8 +1693,8 @@ static __init int vpif_probe(struct platform_device *pdev)
+                       goto probe_subdev_out;
+       } else {
+               vpif_obj.notifier.ops = &vpif_async_ops;
+-              err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev,
+-                                                 &vpif_obj.notifier);
++              err = v4l2_async_nf_register(&vpif_obj.v4l2_dev,
++                                           &vpif_obj.notifier);
+               if (err) {
+                       vpif_err("Error registering async notifier\n");
+                       err = -EINVAL;
+@@ -1711,7 +1712,7 @@ static __init int vpif_probe(struct platform_device *pdev)
+ vpif_free:
+       free_vpif_objs();
+ cleanup:
+-      v4l2_async_notifier_cleanup(&vpif_obj.notifier);
++      v4l2_async_nf_cleanup(&vpif_obj.notifier);
+       return err;
+ }
+@@ -1727,8 +1728,8 @@ static int vpif_remove(struct platform_device *device)
+       struct channel_obj *ch;
+       int i;
+-      v4l2_async_notifier_unregister(&vpif_obj.notifier);
+-      v4l2_async_notifier_cleanup(&vpif_obj.notifier);
++      v4l2_async_nf_unregister(&vpif_obj.notifier);
++      v4l2_async_nf_cleanup(&vpif_obj.notifier);
+       v4l2_device_unregister(&vpif_obj.v4l2_dev);
+       kfree(vpif_obj.sd);
+diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
+index b19d7c8ddc06b..b2d8b2c0ab4d6 100644
+--- a/drivers/media/platform/exynos4-is/media-dev.c
++++ b/drivers/media/platform/exynos4-is/media-dev.c
+@@ -464,9 +464,9 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
+               return -EINVAL;
+       }
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-              &fmd->subdev_notifier, of_fwnode_handle(ep),
+-              struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&fmd->subdev_notifier,
++                                            of_fwnode_handle(ep),
++                                            struct v4l2_async_subdev);
+       of_node_put(ep);
+@@ -557,7 +557,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
+ cleanup:
+       of_node_put(ports);
+-      v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
++      v4l2_async_nf_cleanup(&fmd->subdev_notifier);
+       pm_runtime_put(fmd->pmf);
+       return ret;
+ }
+@@ -1479,7 +1479,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, fmd);
+-      v4l2_async_notifier_init(&fmd->subdev_notifier);
++      v4l2_async_nf_init(&fmd->subdev_notifier);
+       ret = fimc_md_register_platform_entities(fmd, dev->of_node);
+       if (ret)
+@@ -1507,8 +1507,8 @@ static int fimc_md_probe(struct platform_device *pdev)
+               fmd->subdev_notifier.ops = &subdev_notifier_ops;
+               fmd->num_sensors = 0;
+-              ret = v4l2_async_notifier_register(&fmd->v4l2_dev,
+-                                              &fmd->subdev_notifier);
++              ret = v4l2_async_nf_register(&fmd->v4l2_dev,
++                                           &fmd->subdev_notifier);
+               if (ret)
+                       goto err_clk_p;
+       }
+@@ -1520,7 +1520,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+ err_attr:
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+ err_cleanup:
+-      v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
++      v4l2_async_nf_cleanup(&fmd->subdev_notifier);
+ err_m_ent:
+       fimc_md_unregister_entities(fmd);
+ err_clk:
+@@ -1540,8 +1540,8 @@ static int fimc_md_remove(struct platform_device *pdev)
+               return 0;
+       fimc_md_unregister_clk_provider(fmd);
+-      v4l2_async_notifier_unregister(&fmd->subdev_notifier);
+-      v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
++      v4l2_async_nf_unregister(&fmd->subdev_notifier);
++      v4l2_async_nf_cleanup(&fmd->subdev_notifier);
+       v4l2_device_unregister(&fmd->v4l2_dev);
+       device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
+diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
+index 9aa374fa8b364..b61b9d9551af5 100644
+--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
++++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
+@@ -544,12 +544,11 @@ static int cafe_pci_probe(struct pci_dev *pdev,
+       if (ret)
+               goto out_pdown;
+-      v4l2_async_notifier_init(&mcam->notifier);
++      v4l2_async_nf_init(&mcam->notifier);
+-      asd = v4l2_async_notifier_add_i2c_subdev(&mcam->notifier,
+-                                      i2c_adapter_id(cam->i2c_adapter),
+-                                      ov7670_info.addr,
+-                                      struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_i2c(&mcam->notifier,
++                                  i2c_adapter_id(cam->i2c_adapter),
++                                  ov7670_info.addr, struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto out_smbus_shutdown;
+diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
+index 58f9463f3b8ce..ad4a7922d0d74 100644
+--- a/drivers/media/platform/marvell-ccic/mcam-core.c
++++ b/drivers/media/platform/marvell-ccic/mcam-core.c
+@@ -1877,7 +1877,7 @@ int mccic_register(struct mcam_camera *cam)
+       cam->mbus_code = mcam_def_mbus_code;
+       cam->notifier.ops = &mccic_notify_ops;
+-      ret = v4l2_async_notifier_register(&cam->v4l2_dev, &cam->notifier);
++      ret = v4l2_async_nf_register(&cam->v4l2_dev, &cam->notifier);
+       if (ret < 0) {
+               cam_warn(cam, "failed to register a sensor notifier");
+               goto out;
+@@ -1914,9 +1914,9 @@ int mccic_register(struct mcam_camera *cam)
+       return 0;
+ out:
+-      v4l2_async_notifier_unregister(&cam->notifier);
++      v4l2_async_nf_unregister(&cam->notifier);
+       v4l2_device_unregister(&cam->v4l2_dev);
+-      v4l2_async_notifier_cleanup(&cam->notifier);
++      v4l2_async_nf_cleanup(&cam->notifier);
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(mccic_register);
+@@ -1936,9 +1936,9 @@ void mccic_shutdown(struct mcam_camera *cam)
+       if (cam->buffer_mode == B_vmalloc)
+               mcam_free_dma_bufs(cam);
+       v4l2_ctrl_handler_free(&cam->ctrl_handler);
+-      v4l2_async_notifier_unregister(&cam->notifier);
++      v4l2_async_nf_unregister(&cam->notifier);
+       v4l2_device_unregister(&cam->v4l2_dev);
+-      v4l2_async_notifier_cleanup(&cam->notifier);
++      v4l2_async_nf_cleanup(&cam->notifier);
+ }
+ EXPORT_SYMBOL_GPL(mccic_shutdown);
+diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
+index f2f09cea751d8..343ab4f7d807b 100644
+--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
++++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
+@@ -239,10 +239,10 @@ static int mmpcam_probe(struct platform_device *pdev)
+       if (!ep)
+               return -ENODEV;
+-      v4l2_async_notifier_init(&mcam->notifier);
++      v4l2_async_nf_init(&mcam->notifier);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(&mcam->notifier, ep,
+-                                                         struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&mcam->notifier, ep,
++                                            struct v4l2_async_subdev);
+       fwnode_handle_put(ep);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
+index 3222c98b83630..beafe85f28cca 100644
+--- a/drivers/media/platform/omap3isp/isp.c
++++ b/drivers/media/platform/omap3isp/isp.c
+@@ -2003,7 +2003,7 @@ static int isp_remove(struct platform_device *pdev)
+ {
+       struct isp_device *isp = platform_get_drvdata(pdev);
+-      v4l2_async_notifier_unregister(&isp->notifier);
++      v4l2_async_nf_unregister(&isp->notifier);
+       isp_unregister_entities(isp);
+       isp_cleanup_modules(isp);
+       isp_xclk_cleanup(isp);
+@@ -2013,7 +2013,7 @@ static int isp_remove(struct platform_device *pdev)
+       __omap3isp_put(isp, false);
+       media_entity_enum_cleanup(&isp->crashed);
+-      v4l2_async_notifier_cleanup(&isp->notifier);
++      v4l2_async_nf_cleanup(&isp->notifier);
+       kfree(isp);
+@@ -2172,8 +2172,9 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
+               ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+               if (!ret) {
+-                      isd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                              &isp->notifier, ep, struct isp_async_subdev);
++                      isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier,
++                                                            ep, struct
++                                                            isp_async_subdev);
+                       if (!IS_ERR(isd))
+                               isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus);
+               }
+@@ -2211,8 +2212,10 @@ static int isp_parse_of_endpoints(struct isp_device *isp)
+               }
+               if (!ret) {
+-                      isd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                              &isp->notifier, ep, struct isp_async_subdev);
++                      isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier,
++                                                            ep,
++                                                            struct
++                                                            isp_async_subdev);
+                       if (!IS_ERR(isd)) {
+                               switch (vep.bus_type) {
+@@ -2289,7 +2292,7 @@ static int isp_probe(struct platform_device *pdev)
+       mutex_init(&isp->isp_mutex);
+       spin_lock_init(&isp->stat_lock);
+-      v4l2_async_notifier_init(&isp->notifier);
++      v4l2_async_nf_init(&isp->notifier);
+       isp->dev = &pdev->dev;
+       ret = isp_parse_of_endpoints(isp);
+@@ -2427,7 +2430,7 @@ static int isp_probe(struct platform_device *pdev)
+       isp->notifier.ops = &isp_subdev_notifier_ops;
+-      ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier);
++      ret = v4l2_async_nf_register(&isp->v4l2_dev, &isp->notifier);
+       if (ret)
+               goto error_register_entities;
+@@ -2446,7 +2449,7 @@ static int isp_probe(struct platform_device *pdev)
+       isp_xclk_cleanup(isp);
+       __omap3isp_put(isp, false);
+ error:
+-      v4l2_async_notifier_cleanup(&isp->notifier);
++      v4l2_async_nf_cleanup(&isp->notifier);
+       mutex_destroy(&isp->isp_mutex);
+ error_release_isp:
+       kfree(isp);
+diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
+index ec4c010644cae..3ba00b0f93200 100644
+--- a/drivers/media/platform/pxa_camera.c
++++ b/drivers/media/platform/pxa_camera.c
+@@ -2249,10 +2249,9 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
+       if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+               pcdev->platform_flags |= PXA_CAMERA_PCLK_EN;
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                              &pcdev->notifier,
+-                              of_fwnode_handle(np),
+-                              struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&pcdev->notifier,
++                                            of_fwnode_handle(np),
++                                            struct v4l2_async_subdev);
+       if (IS_ERR(asd))
+               err = PTR_ERR(asd);
+ out:
+@@ -2289,7 +2288,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
+       if (IS_ERR(pcdev->clk))
+               return PTR_ERR(pcdev->clk);
+-      v4l2_async_notifier_init(&pcdev->notifier);
++      v4l2_async_nf_init(&pcdev->notifier);
+       pcdev->res = res;
+       pcdev->pdata = pdev->dev.platform_data;
+       if (pcdev->pdata) {
+@@ -2297,11 +2296,10 @@ static int pxa_camera_probe(struct platform_device *pdev)
+               pcdev->platform_flags = pcdev->pdata->flags;
+               pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
+-              asd = v4l2_async_notifier_add_i2c_subdev(
+-                              &pcdev->notifier,
+-                              pcdev->pdata->sensor_i2c_adapter_id,
+-                              pcdev->pdata->sensor_i2c_address,
+-                              struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_i2c(&pcdev->notifier,
++                                          pcdev->pdata->sensor_i2c_adapter_id,
++                                          pcdev->pdata->sensor_i2c_address,
++                                          struct v4l2_async_subdev);
+               if (IS_ERR(asd))
+                       err = PTR_ERR(asd);
+       } else if (pdev->dev.of_node) {
+@@ -2402,13 +2400,13 @@ static int pxa_camera_probe(struct platform_device *pdev)
+               goto exit_notifier_cleanup;
+       pcdev->notifier.ops = &pxa_camera_sensor_ops;
+-      err = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier);
++      err = v4l2_async_nf_register(&pcdev->v4l2_dev, &pcdev->notifier);
+       if (err)
+               goto exit_notifier_cleanup;
+       return 0;
+ exit_notifier_cleanup:
+-      v4l2_async_notifier_cleanup(&pcdev->notifier);
++      v4l2_async_nf_cleanup(&pcdev->notifier);
+       v4l2_device_unregister(&pcdev->v4l2_dev);
+ exit_deactivate:
+       pxa_camera_deactivate(pcdev);
+@@ -2432,8 +2430,8 @@ static int pxa_camera_remove(struct platform_device *pdev)
+       dma_release_channel(pcdev->dma_chans[1]);
+       dma_release_channel(pcdev->dma_chans[2]);
+-      v4l2_async_notifier_unregister(&pcdev->notifier);
+-      v4l2_async_notifier_cleanup(&pcdev->notifier);
++      v4l2_async_nf_unregister(&pcdev->notifier);
++      v4l2_async_nf_cleanup(&pcdev->notifier);
+       v4l2_device_unregister(&pcdev->v4l2_dev);
+diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
+index ef100d5f77636..be091c50a3c0c 100644
+--- a/drivers/media/platform/qcom/camss/camss.c
++++ b/drivers/media/platform/qcom/camss/camss.c
+@@ -886,9 +886,9 @@ static int camss_of_parse_ports(struct camss *camss)
+                       goto err_cleanup;
+               }
+-              csd = v4l2_async_notifier_add_fwnode_subdev(
+-                      &camss->notifier, of_fwnode_handle(remote),
+-                      struct camss_async_subdev);
++              csd = v4l2_async_nf_add_fwnode(&camss->notifier,
++                                             of_fwnode_handle(remote),
++                                             struct camss_async_subdev);
+               of_node_put(remote);
+               if (IS_ERR(csd)) {
+                       ret = PTR_ERR(csd);
+@@ -1361,7 +1361,7 @@ static int camss_probe(struct platform_device *pdev)
+               goto err_free;
+       }
+-      v4l2_async_notifier_init(&camss->notifier);
++      v4l2_async_nf_init(&camss->notifier);
+       num_subdevs = camss_of_parse_ports(camss);
+       if (num_subdevs < 0) {
+@@ -1397,8 +1397,8 @@ static int camss_probe(struct platform_device *pdev)
+       if (num_subdevs) {
+               camss->notifier.ops = &camss_subdev_notifier_ops;
+-              ret = v4l2_async_notifier_register(&camss->v4l2_dev,
+-                                                 &camss->notifier);
++              ret = v4l2_async_nf_register(&camss->v4l2_dev,
++                                           &camss->notifier);
+               if (ret) {
+                       dev_err(dev,
+                               "Failed to register async subdev nodes: %d\n",
+@@ -1436,7 +1436,7 @@ static int camss_probe(struct platform_device *pdev)
+ err_register_entities:
+       v4l2_device_unregister(&camss->v4l2_dev);
+ err_cleanup:
+-      v4l2_async_notifier_cleanup(&camss->notifier);
++      v4l2_async_nf_cleanup(&camss->notifier);
+ err_free:
+       kfree(camss);
+@@ -1478,8 +1478,8 @@ static int camss_remove(struct platform_device *pdev)
+ {
+       struct camss *camss = platform_get_drvdata(pdev);
+-      v4l2_async_notifier_unregister(&camss->notifier);
+-      v4l2_async_notifier_cleanup(&camss->notifier);
++      v4l2_async_nf_unregister(&camss->notifier);
++      v4l2_async_nf_cleanup(&camss->notifier);
+       camss_unregister_entities(camss);
+       if (atomic_read(&camss->ref_count) == 0)
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index 5a280d8ff7dd0..d1786aa8a7ecd 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -535,9 +535,8 @@ static int rvin_mc_parse_of(struct rvin_dev *vin, unsigned int id)
+               goto out;
+       }
+-      asd = v4l2_async_notifier_add_fwnode_subdev(&vin->group->notifier,
+-                                                  fwnode,
+-                                                  struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode,
++                                     struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto out;
+@@ -557,8 +556,8 @@ static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
+ {
+       mutex_lock(&vin->group->lock);
+       if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
+-              v4l2_async_notifier_unregister(&vin->group->notifier);
+-              v4l2_async_notifier_cleanup(&vin->group->notifier);
++              v4l2_async_nf_unregister(&vin->group->notifier);
++              v4l2_async_nf_cleanup(&vin->group->notifier);
+       }
+       mutex_unlock(&vin->group->lock);
+ }
+@@ -586,7 +585,7 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
+       mutex_unlock(&vin->group->lock);
+-      v4l2_async_notifier_init(&vin->group->notifier);
++      v4l2_async_nf_init(&vin->group->notifier);
+       /*
+        * Have all VIN's look for CSI-2 subdevices. Some subdevices will
+@@ -611,11 +610,10 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
+               return 0;
+       vin->group->notifier.ops = &rvin_group_notify_ops;
+-      ret = v4l2_async_notifier_register(&vin->v4l2_dev,
+-                                         &vin->group->notifier);
++      ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier);
+       if (ret < 0) {
+               vin_err(vin, "Notifier registration failed\n");
+-              v4l2_async_notifier_cleanup(&vin->group->notifier);
++              v4l2_async_nf_cleanup(&vin->group->notifier);
+               return ret;
+       }
+@@ -899,8 +897,8 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin)
+               goto out;
+       }
+-      asd = v4l2_async_notifier_add_fwnode_subdev(&vin->notifier, fwnode,
+-                                                  struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode,
++                                     struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto out;
+@@ -917,15 +915,15 @@ static int rvin_parallel_parse_of(struct rvin_dev *vin)
+ static void rvin_parallel_cleanup(struct rvin_dev *vin)
+ {
+-      v4l2_async_notifier_unregister(&vin->notifier);
+-      v4l2_async_notifier_cleanup(&vin->notifier);
++      v4l2_async_nf_unregister(&vin->notifier);
++      v4l2_async_nf_cleanup(&vin->notifier);
+ }
+ static int rvin_parallel_init(struct rvin_dev *vin)
+ {
+       int ret;
+-      v4l2_async_notifier_init(&vin->notifier);
++      v4l2_async_nf_init(&vin->notifier);
+       ret = rvin_parallel_parse_of(vin);
+       if (ret)
+@@ -939,10 +937,10 @@ static int rvin_parallel_init(struct rvin_dev *vin)
+               to_of_node(vin->parallel.asd->match.fwnode));
+       vin->notifier.ops = &rvin_parallel_notify_ops;
+-      ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
++      ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier);
+       if (ret < 0) {
+               vin_err(vin, "Notifier registration failed\n");
+-              v4l2_async_notifier_cleanup(&vin->notifier);
++              v4l2_async_nf_cleanup(&vin->notifier);
+               return ret;
+       }
+diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
+index 0c5e2f7e04beb..5e9cb72676e39 100644
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
+@@ -926,19 +926,18 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv)
+       dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(fwnode));
+-      v4l2_async_notifier_init(&priv->notifier);
++      v4l2_async_nf_init(&priv->notifier);
+       priv->notifier.ops = &rcar_csi2_notify_ops;
+-      asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, fwnode,
+-                                                  struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode(&priv->notifier, fwnode,
++                                     struct v4l2_async_subdev);
+       fwnode_handle_put(fwnode);
+       if (IS_ERR(asd))
+               return PTR_ERR(asd);
+-      ret = v4l2_async_subdev_notifier_register(&priv->subdev,
+-                                                &priv->notifier);
++      ret = v4l2_async_subdev_nf_register(&priv->subdev, &priv->notifier);
+       if (ret)
+-              v4l2_async_notifier_cleanup(&priv->notifier);
++              v4l2_async_nf_cleanup(&priv->notifier);
+       return ret;
+ }
+@@ -1301,8 +1300,8 @@ static int rcsi2_probe(struct platform_device *pdev)
+       return 0;
+ error:
+-      v4l2_async_notifier_unregister(&priv->notifier);
+-      v4l2_async_notifier_cleanup(&priv->notifier);
++      v4l2_async_nf_unregister(&priv->notifier);
++      v4l2_async_nf_cleanup(&priv->notifier);
+       return ret;
+ }
+@@ -1311,8 +1310,8 @@ static int rcsi2_remove(struct platform_device *pdev)
+ {
+       struct rcar_csi2 *priv = platform_get_drvdata(pdev);
+-      v4l2_async_notifier_unregister(&priv->notifier);
+-      v4l2_async_notifier_cleanup(&priv->notifier);
++      v4l2_async_nf_unregister(&priv->notifier);
++      v4l2_async_nf_cleanup(&priv->notifier);
+       v4l2_async_unregister_subdev(&priv->subdev);
+       pm_runtime_disable(&pdev->dev);
+diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c
+index 1e3b68a8743af..a505d991548bb 100644
+--- a/drivers/media/platform/rcar_drif.c
++++ b/drivers/media/platform/rcar_drif.c
+@@ -1212,7 +1212,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
+       struct fwnode_handle *fwnode, *ep;
+       struct v4l2_async_subdev *asd;
+-      v4l2_async_notifier_init(notifier);
++      v4l2_async_nf_init(notifier);
+       ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node),
+                                           NULL);
+@@ -1229,8 +1229,8 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
+               return -EINVAL;
+       }
+-      asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
+-                                                  struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode(notifier, fwnode,
++                                     struct v4l2_async_subdev);
+       fwnode_handle_put(fwnode);
+       if (IS_ERR(asd))
+               return PTR_ERR(asd);
+@@ -1346,7 +1346,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr)
+       sdr->notifier.ops = &rcar_drif_notify_ops;
+       /* Register notifier */
+-      ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier);
++      ret = v4l2_async_nf_register(&sdr->v4l2_dev, &sdr->notifier);
+       if (ret < 0) {
+               dev_err(sdr->dev, "failed: notifier register ret %d\n", ret);
+               goto cleanup;
+@@ -1355,7 +1355,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr)
+       return ret;
+ cleanup:
+-      v4l2_async_notifier_cleanup(&sdr->notifier);
++      v4l2_async_nf_cleanup(&sdr->notifier);
+ error:
+       v4l2_device_unregister(&sdr->v4l2_dev);
+@@ -1365,8 +1365,8 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr)
+ /* V4L2 SDR device remove */
+ static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr)
+ {
+-      v4l2_async_notifier_unregister(&sdr->notifier);
+-      v4l2_async_notifier_cleanup(&sdr->notifier);
++      v4l2_async_nf_unregister(&sdr->notifier);
++      v4l2_async_nf_cleanup(&sdr->notifier);
+       v4l2_device_unregister(&sdr->v4l2_dev);
+ }
+diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c
+index f432032c7084f..9376eb363748b 100644
+--- a/drivers/media/platform/renesas-ceu.c
++++ b/drivers/media/platform/renesas-ceu.c
+@@ -1513,12 +1513,12 @@ static int ceu_parse_platform_data(struct ceu_device *ceudev,
+               /* Setup the ceu subdevice and the async subdevice. */
+               async_sd = &pdata->subdevs[i];
+-              ceu_sd = v4l2_async_notifier_add_i2c_subdev(&ceudev->notifier,
+-                              async_sd->i2c_adapter_id,
+-                              async_sd->i2c_address,
+-                              struct ceu_subdev);
++              ceu_sd = v4l2_async_nf_add_i2c(&ceudev->notifier,
++                                             async_sd->i2c_adapter_id,
++                                             async_sd->i2c_address,
++                                             struct ceu_subdev);
+               if (IS_ERR(ceu_sd)) {
+-                      v4l2_async_notifier_cleanup(&ceudev->notifier);
++                      v4l2_async_nf_cleanup(&ceudev->notifier);
+                       return PTR_ERR(ceu_sd);
+               }
+               ceu_sd->mbus_flags = async_sd->flags;
+@@ -1576,9 +1576,9 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
+               }
+               /* Setup the ceu subdevice and the async subdevice. */
+-              ceu_sd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                              &ceudev->notifier, of_fwnode_handle(ep),
+-                              struct ceu_subdev);
++              ceu_sd = v4l2_async_nf_add_fwnode_remote(&ceudev->notifier,
++                                                       of_fwnode_handle(ep),
++                                                       struct ceu_subdev);
+               if (IS_ERR(ceu_sd)) {
+                       ret = PTR_ERR(ceu_sd);
+                       goto error_cleanup;
+@@ -1592,7 +1592,7 @@ static int ceu_parse_dt(struct ceu_device *ceudev)
+       return num_ep;
+ error_cleanup:
+-      v4l2_async_notifier_cleanup(&ceudev->notifier);
++      v4l2_async_nf_cleanup(&ceudev->notifier);
+       of_node_put(ep);
+       return ret;
+ }
+@@ -1669,7 +1669,7 @@ static int ceu_probe(struct platform_device *pdev)
+       if (ret)
+               goto error_pm_disable;
+-      v4l2_async_notifier_init(&ceudev->notifier);
++      v4l2_async_nf_init(&ceudev->notifier);
+       if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+               ceu_data = of_device_get_match_data(dev);
+@@ -1691,8 +1691,7 @@ static int ceu_probe(struct platform_device *pdev)
+       ceudev->notifier.v4l2_dev       = &ceudev->v4l2_dev;
+       ceudev->notifier.ops            = &ceu_notify_ops;
+-      ret = v4l2_async_notifier_register(&ceudev->v4l2_dev,
+-                                         &ceudev->notifier);
++      ret = v4l2_async_nf_register(&ceudev->v4l2_dev, &ceudev->notifier);
+       if (ret)
+               goto error_cleanup;
+@@ -1701,7 +1700,7 @@ static int ceu_probe(struct platform_device *pdev)
+       return 0;
+ error_cleanup:
+-      v4l2_async_notifier_cleanup(&ceudev->notifier);
++      v4l2_async_nf_cleanup(&ceudev->notifier);
+ error_v4l2_unregister:
+       v4l2_device_unregister(&ceudev->v4l2_dev);
+ error_pm_disable:
+@@ -1718,9 +1717,9 @@ static int ceu_remove(struct platform_device *pdev)
+       pm_runtime_disable(ceudev->dev);
+-      v4l2_async_notifier_unregister(&ceudev->notifier);
++      v4l2_async_nf_unregister(&ceudev->notifier);
+-      v4l2_async_notifier_cleanup(&ceudev->notifier);
++      v4l2_async_nf_cleanup(&ceudev->notifier);
+       v4l2_device_unregister(&ceudev->v4l2_dev);
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+index 560f928c37520..b6a4522c2970d 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+@@ -246,7 +246,7 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
+       unsigned int next_id = 0;
+       int ret;
+-      v4l2_async_notifier_init(ntf);
++      v4l2_async_nf_init(ntf);
+       while (1) {
+               struct v4l2_fwnode_endpoint vep = {
+@@ -265,8 +265,9 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
+               if (ret)
+                       goto err_parse;
+-              rk_asd = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
+-                                                      struct rkisp1_sensor_async);
++              rk_asd = v4l2_async_nf_add_fwnode_remote(ntf, ep,
++                                                       struct
++                                                       rkisp1_sensor_async);
+               if (IS_ERR(rk_asd)) {
+                       ret = PTR_ERR(rk_asd);
+                       goto err_parse;
+@@ -286,16 +287,16 @@ static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
+               continue;
+ err_parse:
+               fwnode_handle_put(ep);
+-              v4l2_async_notifier_cleanup(ntf);
++              v4l2_async_nf_cleanup(ntf);
+               return ret;
+       }
+       if (next_id == 0)
+               dev_dbg(rkisp1->dev, "no remote subdevice found\n");
+       ntf->ops = &rkisp1_subdev_notifier_ops;
+-      ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf);
++      ret = v4l2_async_nf_register(&rkisp1->v4l2_dev, ntf);
+       if (ret) {
+-              v4l2_async_notifier_cleanup(ntf);
++              v4l2_async_nf_cleanup(ntf);
+               return ret;
+       }
+       return 0;
+@@ -542,8 +543,8 @@ static int rkisp1_remove(struct platform_device *pdev)
+ {
+       struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
+-      v4l2_async_notifier_unregister(&rkisp1->notifier);
+-      v4l2_async_notifier_cleanup(&rkisp1->notifier);
++      v4l2_async_nf_unregister(&rkisp1->notifier);
++      v4l2_async_nf_cleanup(&rkisp1->notifier);
+       rkisp1_params_unregister(rkisp1);
+       rkisp1_stats_unregister(rkisp1);
+diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
+index 6110718645a4f..e1b17c05229cf 100644
+--- a/drivers/media/platform/stm32/stm32-dcmi.c
++++ b/drivers/media/platform/stm32/stm32-dcmi.c
+@@ -1833,11 +1833,11 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
+               return -EINVAL;
+       }
+-      v4l2_async_notifier_init(&dcmi->notifier);
++      v4l2_async_nf_init(&dcmi->notifier);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-              &dcmi->notifier, of_fwnode_handle(ep),
+-              struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&dcmi->notifier,
++                                            of_fwnode_handle(ep),
++                                            struct v4l2_async_subdev);
+       of_node_put(ep);
+@@ -1848,10 +1848,10 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
+       dcmi->notifier.ops = &dcmi_graph_notify_ops;
+-      ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier);
++      ret = v4l2_async_nf_register(&dcmi->v4l2_dev, &dcmi->notifier);
+       if (ret < 0) {
+               dev_err(dcmi->dev, "Failed to register notifier\n");
+-              v4l2_async_notifier_cleanup(&dcmi->notifier);
++              v4l2_async_nf_cleanup(&dcmi->notifier);
+               return ret;
+       }
+@@ -2063,7 +2063,7 @@ static int dcmi_probe(struct platform_device *pdev)
+       return 0;
+ err_cleanup:
+-      v4l2_async_notifier_cleanup(&dcmi->notifier);
++      v4l2_async_nf_cleanup(&dcmi->notifier);
+ err_media_entity_cleanup:
+       media_entity_cleanup(&dcmi->vdev->entity);
+ err_device_release:
+@@ -2083,8 +2083,8 @@ static int dcmi_remove(struct platform_device *pdev)
+       pm_runtime_disable(&pdev->dev);
+-      v4l2_async_notifier_unregister(&dcmi->notifier);
+-      v4l2_async_notifier_cleanup(&dcmi->notifier);
++      v4l2_async_nf_unregister(&dcmi->notifier);
++      v4l2_async_nf_cleanup(&dcmi->notifier);
+       media_entity_cleanup(&dcmi->vdev->entity);
+       v4l2_device_unregister(&dcmi->v4l2_dev);
+       media_device_cleanup(&dcmi->mdev);
+diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+index 8d40a7acba9c4..94e98e470aff7 100644
+--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
++++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+@@ -122,7 +122,7 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
+       struct fwnode_handle *ep;
+       int ret;
+-      v4l2_async_notifier_init(&csi->notifier);
++      v4l2_async_nf_init(&csi->notifier);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+@@ -135,8 +135,8 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
+       csi->bus = vep.bus.parallel;
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, ep,
+-                                                         struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
++                                            struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto out;
+@@ -244,7 +244,7 @@ static int sun4i_csi_probe(struct platform_device *pdev)
+       if (ret)
+               goto err_unregister_media;
+-      ret = v4l2_async_notifier_register(&csi->v4l, &csi->notifier);
++      ret = v4l2_async_nf_register(&csi->v4l, &csi->notifier);
+       if (ret) {
+               dev_err(csi->dev, "Couldn't register our notifier.\n");
+               goto err_unregister_media;
+@@ -268,8 +268,8 @@ static int sun4i_csi_remove(struct platform_device *pdev)
+ {
+       struct sun4i_csi *csi = platform_get_drvdata(pdev);
+-      v4l2_async_notifier_unregister(&csi->notifier);
+-      v4l2_async_notifier_cleanup(&csi->notifier);
++      v4l2_async_nf_unregister(&csi->notifier);
++      v4l2_async_nf_cleanup(&csi->notifier);
+       vb2_video_unregister_device(&csi->vdev);
+       media_device_unregister(&csi->mdev);
+       sun4i_csi_dma_unregister(csi);
+diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+index 27935f1e9555e..08df0c833423b 100644
+--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
++++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+@@ -717,8 +717,8 @@ static int sun6i_csi_fwnode_parse(struct device *dev,
+ static void sun6i_csi_v4l2_cleanup(struct sun6i_csi *csi)
+ {
+       media_device_unregister(&csi->media_dev);
+-      v4l2_async_notifier_unregister(&csi->notifier);
+-      v4l2_async_notifier_cleanup(&csi->notifier);
++      v4l2_async_nf_unregister(&csi->notifier);
++      v4l2_async_nf_cleanup(&csi->notifier);
+       sun6i_video_cleanup(&csi->video);
+       v4l2_device_unregister(&csi->v4l2_dev);
+       v4l2_ctrl_handler_free(&csi->ctrl_handler);
+@@ -737,7 +737,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi)
+                "platform:%s", dev_name(csi->dev));
+       media_device_init(&csi->media_dev);
+-      v4l2_async_notifier_init(&csi->notifier);
++      v4l2_async_nf_init(&csi->notifier);
+       ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 0);
+       if (ret) {
+@@ -759,16 +759,17 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi)
+       if (ret)
+               goto unreg_v4l2;
+-      ret = v4l2_async_notifier_parse_fwnode_endpoints(csi->dev,
+-                                                       &csi->notifier,
+-                                                       sizeof(struct v4l2_async_subdev),
+-                                                       sun6i_csi_fwnode_parse);
++      ret = v4l2_async_nf_parse_fwnode_endpoints(csi->dev,
++                                                 &csi->notifier,
++                                                 sizeof(struct
++                                                        v4l2_async_subdev),
++                                                 sun6i_csi_fwnode_parse);
+       if (ret)
+               goto clean_video;
+       csi->notifier.ops = &sun6i_csi_async_ops;
+-      ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier);
++      ret = v4l2_async_nf_register(&csi->v4l2_dev, &csi->notifier);
+       if (ret) {
+               dev_err(csi->dev, "notifier registration failed\n");
+               goto clean_video;
+@@ -783,7 +784,7 @@ static int sun6i_csi_v4l2_init(struct sun6i_csi *csi)
+ free_ctrl:
+       v4l2_ctrl_handler_free(&csi->ctrl_handler);
+ clean_media:
+-      v4l2_async_notifier_cleanup(&csi->notifier);
++      v4l2_async_nf_cleanup(&csi->notifier);
+       media_device_cleanup(&csi->media_dev);
+       return ret;
+diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
+index 35d62eb1321fb..0e583120266ff 100644
+--- a/drivers/media/platform/ti-vpe/cal.c
++++ b/drivers/media/platform/ti-vpe/cal.c
+@@ -781,7 +781,7 @@ static int cal_async_notifier_register(struct cal_dev *cal)
+       unsigned int i;
+       int ret;
+-      v4l2_async_notifier_init(&cal->notifier);
++      v4l2_async_nf_init(&cal->notifier);
+       cal->notifier.ops = &cal_async_notifier_ops;
+       for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+@@ -793,9 +793,9 @@ static int cal_async_notifier_register(struct cal_dev *cal)
+                       continue;
+               fwnode = of_fwnode_handle(phy->source_node);
+-              casd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
+-                                                           fwnode,
+-                                                           struct cal_v4l2_async_subdev);
++              casd = v4l2_async_nf_add_fwnode(&cal->notifier,
++                                              fwnode,
++                                              struct cal_v4l2_async_subdev);
+               if (IS_ERR(casd)) {
+                       phy_err(phy, "Failed to add subdev to notifier\n");
+                       ret = PTR_ERR(casd);
+@@ -805,7 +805,7 @@ static int cal_async_notifier_register(struct cal_dev *cal)
+               casd->phy = phy;
+       }
+-      ret = v4l2_async_notifier_register(&cal->v4l2_dev, &cal->notifier);
++      ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier);
+       if (ret) {
+               cal_err(cal, "Error registering async notifier\n");
+               goto error;
+@@ -814,14 +814,14 @@ static int cal_async_notifier_register(struct cal_dev *cal)
+       return 0;
+ error:
+-      v4l2_async_notifier_cleanup(&cal->notifier);
++      v4l2_async_nf_cleanup(&cal->notifier);
+       return ret;
+ }
+ static void cal_async_notifier_unregister(struct cal_dev *cal)
+ {
+-      v4l2_async_notifier_unregister(&cal->notifier);
+-      v4l2_async_notifier_cleanup(&cal->notifier);
++      v4l2_async_nf_unregister(&cal->notifier);
++      v4l2_async_nf_cleanup(&cal->notifier);
+ }
+ /* ------------------------------------------------------------------
+diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
+index 905005e271ca9..fda8fc0e48143 100644
+--- a/drivers/media/platform/video-mux.c
++++ b/drivers/media/platform/video-mux.c
+@@ -360,7 +360,7 @@ static int video_mux_async_register(struct video_mux *vmux,
+       unsigned int i;
+       int ret;
+-      v4l2_async_notifier_init(&vmux->notifier);
++      v4l2_async_nf_init(&vmux->notifier);
+       for (i = 0; i < num_input_pads; i++) {
+               struct v4l2_async_subdev *asd;
+@@ -380,8 +380,8 @@ static int video_mux_async_register(struct video_mux *vmux,
+               }
+               fwnode_handle_put(remote_ep);
+-              asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                      &vmux->notifier, ep, struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode_remote(&vmux->notifier, ep,
++                                                    struct v4l2_async_subdev);
+               fwnode_handle_put(ep);
+@@ -395,8 +395,7 @@ static int video_mux_async_register(struct video_mux *vmux,
+       vmux->notifier.ops = &video_mux_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&vmux->subdev,
+-                                                &vmux->notifier);
++      ret = v4l2_async_subdev_nf_register(&vmux->subdev, &vmux->notifier);
+       if (ret)
+               return ret;
+@@ -477,8 +476,8 @@ static int video_mux_probe(struct platform_device *pdev)
+       ret = video_mux_async_register(vmux, num_pads - 1);
+       if (ret) {
+-              v4l2_async_notifier_unregister(&vmux->notifier);
+-              v4l2_async_notifier_cleanup(&vmux->notifier);
++              v4l2_async_nf_unregister(&vmux->notifier);
++              v4l2_async_nf_cleanup(&vmux->notifier);
+       }
+       return ret;
+@@ -489,8 +488,8 @@ static int video_mux_remove(struct platform_device *pdev)
+       struct video_mux *vmux = platform_get_drvdata(pdev);
+       struct v4l2_subdev *sd = &vmux->subdev;
+-      v4l2_async_notifier_unregister(&vmux->notifier);
+-      v4l2_async_notifier_cleanup(&vmux->notifier);
++      v4l2_async_nf_unregister(&vmux->notifier);
++      v4l2_async_nf_cleanup(&vmux->notifier);
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
+index 5896a662da3ba..0a16c218a50a7 100644
+--- a/drivers/media/platform/xilinx/xilinx-vipp.c
++++ b/drivers/media/platform/xilinx/xilinx-vipp.c
+@@ -382,9 +382,8 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
+                       continue;
+               }
+-              xge = v4l2_async_notifier_add_fwnode_subdev(
+-                      &xdev->notifier, remote,
+-                      struct xvip_graph_entity);
++              xge = v4l2_async_nf_add_fwnode(&xdev->notifier, remote,
++                                             struct xvip_graph_entity);
+               fwnode_handle_put(remote);
+               if (IS_ERR(xge)) {
+                       ret = PTR_ERR(xge);
+@@ -395,7 +394,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
+       return 0;
+ err_notifier_cleanup:
+-      v4l2_async_notifier_cleanup(&xdev->notifier);
++      v4l2_async_nf_cleanup(&xdev->notifier);
+       fwnode_handle_put(ep);
+       return ret;
+ }
+@@ -420,7 +419,7 @@ static int xvip_graph_parse(struct xvip_composite_device *xdev)
+               entity = to_xvip_entity(asd);
+               ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode);
+               if (ret < 0) {
+-                      v4l2_async_notifier_cleanup(&xdev->notifier);
++                      v4l2_async_nf_cleanup(&xdev->notifier);
+                       break;
+               }
+       }
+@@ -497,8 +496,8 @@ static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
+       struct xvip_dma *dmap;
+       struct xvip_dma *dma;
+-      v4l2_async_notifier_unregister(&xdev->notifier);
+-      v4l2_async_notifier_cleanup(&xdev->notifier);
++      v4l2_async_nf_unregister(&xdev->notifier);
++      v4l2_async_nf_cleanup(&xdev->notifier);
+       list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) {
+               xvip_dma_cleanup(dma);
+@@ -533,7 +532,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev)
+       /* Register the subdevices notifier. */
+       xdev->notifier.ops = &xvip_graph_notify_ops;
+-      ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
++      ret = v4l2_async_nf_register(&xdev->v4l2_dev, &xdev->notifier);
+       if (ret < 0) {
+               dev_err(xdev->dev, "notifier registration failed\n");
+               goto done;
+@@ -597,7 +596,7 @@ static int xvip_composite_probe(struct platform_device *pdev)
+       xdev->dev = &pdev->dev;
+       INIT_LIST_HEAD(&xdev->dmas);
+-      v4l2_async_notifier_init(&xdev->notifier);
++      v4l2_async_nf_init(&xdev->notifier);
+       ret = xvip_composite_v4l2_init(xdev);
+       if (ret < 0)
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index cd9e78c63791b..0404267f1ae4f 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -24,9 +24,9 @@
+ #include <media/v4l2-fwnode.h>
+ #include <media/v4l2-subdev.h>
+-static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+-                                        struct v4l2_subdev *subdev,
+-                                        struct v4l2_async_subdev *asd)
++static int v4l2_async_nf_call_bound(struct v4l2_async_notifier *n,
++                                  struct v4l2_subdev *subdev,
++                                  struct v4l2_async_subdev *asd)
+ {
+       if (!n->ops || !n->ops->bound)
+               return 0;
+@@ -34,9 +34,9 @@ static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n,
+       return n->ops->bound(n, subdev, asd);
+ }
+-static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+-                                          struct v4l2_subdev *subdev,
+-                                          struct v4l2_async_subdev *asd)
++static void v4l2_async_nf_call_unbind(struct v4l2_async_notifier *n,
++                                    struct v4l2_subdev *subdev,
++                                    struct v4l2_async_subdev *asd)
+ {
+       if (!n->ops || !n->ops->unbind)
+               return;
+@@ -44,7 +44,7 @@ static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n,
+       n->ops->unbind(n, subdev, asd);
+ }
+-static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n)
++static int v4l2_async_nf_call_complete(struct v4l2_async_notifier *n)
+ {
+       if (!n->ops || !n->ops->complete)
+               return 0;
+@@ -215,7 +215,7 @@ v4l2_async_find_subdev_notifier(struct v4l2_subdev *sd)
+ /* Get v4l2_device related to the notifier if one can be found. */
+ static struct v4l2_device *
+-v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_find_v4l2_dev(struct v4l2_async_notifier *notifier)
+ {
+       while (notifier->parent)
+               notifier = notifier->parent;
+@@ -227,7 +227,7 @@ v4l2_async_notifier_find_v4l2_dev(struct v4l2_async_notifier *notifier)
+  * Return true if all child sub-device notifiers are complete, false otherwise.
+  */
+ static bool
+-v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_can_complete(struct v4l2_async_notifier *notifier)
+ {
+       struct v4l2_subdev *sd;
+@@ -239,7 +239,7 @@ v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
+                       v4l2_async_find_subdev_notifier(sd);
+               if (subdev_notifier &&
+-                  !v4l2_async_notifier_can_complete(subdev_notifier))
++                  !v4l2_async_nf_can_complete(subdev_notifier))
+                       return false;
+       }
+@@ -251,7 +251,7 @@ v4l2_async_notifier_can_complete(struct v4l2_async_notifier *notifier)
+  * sub-devices have been bound; v4l2_device is also available then.
+  */
+ static int
+-v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_try_complete(struct v4l2_async_notifier *notifier)
+ {
+       /* Quick check whether there are still more sub-devices here. */
+       if (!list_empty(&notifier->waiting))
+@@ -266,14 +266,14 @@ v4l2_async_notifier_try_complete(struct v4l2_async_notifier *notifier)
+               return 0;
+       /* Is everything ready? */
+-      if (!v4l2_async_notifier_can_complete(notifier))
++      if (!v4l2_async_nf_can_complete(notifier))
+               return 0;
+-      return v4l2_async_notifier_call_complete(notifier);
++      return v4l2_async_nf_call_complete(notifier);
+ }
+ static int
+-v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier);
++v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier);
+ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+                                  struct v4l2_device *v4l2_dev,
+@@ -287,7 +287,7 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+       if (ret < 0)
+               return ret;
+-      ret = v4l2_async_notifier_call_bound(notifier, sd, asd);
++      ret = v4l2_async_nf_call_bound(notifier, sd, asd);
+       if (ret < 0) {
+               v4l2_device_unregister_subdev(sd);
+               return ret;
+@@ -315,15 +315,15 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+        */
+       subdev_notifier->parent = notifier;
+-      return v4l2_async_notifier_try_all_subdevs(subdev_notifier);
++      return v4l2_async_nf_try_all_subdevs(subdev_notifier);
+ }
+ /* Test all async sub-devices in a notifier for a match. */
+ static int
+-v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_try_all_subdevs(struct v4l2_async_notifier *notifier)
+ {
+       struct v4l2_device *v4l2_dev =
+-              v4l2_async_notifier_find_v4l2_dev(notifier);
++              v4l2_async_nf_find_v4l2_dev(notifier);
+       struct v4l2_subdev *sd;
+       if (!v4l2_dev)
+@@ -367,7 +367,7 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd)
+ /* Unbind all sub-devices in the notifier tree. */
+ static void
+-v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
+ {
+       struct v4l2_subdev *sd, *tmp;
+@@ -376,9 +376,9 @@ v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
+                       v4l2_async_find_subdev_notifier(sd);
+               if (subdev_notifier)
+-                      v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
++                      v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
+-              v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
++              v4l2_async_nf_call_unbind(notifier, sd, sd->asd);
+               v4l2_async_cleanup(sd);
+               list_move(&sd->async_list, &subdev_list);
+@@ -389,8 +389,8 @@ v4l2_async_notifier_unbind_all_subdevs(struct v4l2_async_notifier *notifier)
+ /* See if an async sub-device can be found in a notifier's lists. */
+ static bool
+-__v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+-                                     struct v4l2_async_subdev *asd)
++__v4l2_async_nf_has_async_subdev(struct v4l2_async_notifier *notifier,
++                               struct v4l2_async_subdev *asd)
+ {
+       struct v4l2_async_subdev *asd_y;
+       struct v4l2_subdev *sd;
+@@ -416,9 +416,8 @@ __v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+  * If @this_index < 0, search the notifier's entire @asd_list.
+  */
+ static bool
+-v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+-                                   struct v4l2_async_subdev *asd,
+-                                   int this_index)
++v4l2_async_nf_has_async_subdev(struct v4l2_async_notifier *notifier,
++                             struct v4l2_async_subdev *asd, int this_index)
+ {
+       struct v4l2_async_subdev *asd_y;
+       int j = 0;
+@@ -435,15 +434,15 @@ v4l2_async_notifier_has_async_subdev(struct v4l2_async_notifier *notifier,
+       /* Check that an asd does not exist in other notifiers. */
+       list_for_each_entry(notifier, &notifier_list, list)
+-              if (__v4l2_async_notifier_has_async_subdev(notifier, asd))
++              if (__v4l2_async_nf_has_async_subdev(notifier, asd))
+                       return true;
+       return false;
+ }
+-static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
+-                                       struct v4l2_async_subdev *asd,
+-                                       int this_index)
++static int v4l2_async_nf_asd_valid(struct v4l2_async_notifier *notifier,
++                                 struct v4l2_async_subdev *asd,
++                                 int this_index)
+ {
+       struct device *dev =
+               notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL;
+@@ -454,8 +453,7 @@ static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
+       switch (asd->match_type) {
+       case V4L2_ASYNC_MATCH_I2C:
+       case V4L2_ASYNC_MATCH_FWNODE:
+-              if (v4l2_async_notifier_has_async_subdev(notifier, asd,
+-                                                       this_index)) {
++              if (v4l2_async_nf_has_async_subdev(notifier, asd, this_index)) {
+                       dev_dbg(dev, "subdev descriptor already listed in this or other notifiers\n");
+                       return -EEXIST;
+               }
+@@ -469,13 +467,13 @@ static int v4l2_async_notifier_asd_valid(struct v4l2_async_notifier *notifier,
+       return 0;
+ }
+-void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier)
++void v4l2_async_nf_init(struct v4l2_async_notifier *notifier)
+ {
+       INIT_LIST_HEAD(&notifier->asd_list);
+ }
+-EXPORT_SYMBOL(v4l2_async_notifier_init);
++EXPORT_SYMBOL(v4l2_async_nf_init);
+-static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
++static int __v4l2_async_nf_register(struct v4l2_async_notifier *notifier)
+ {
+       struct v4l2_async_subdev *asd;
+       int ret, i = 0;
+@@ -486,18 +484,18 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+       mutex_lock(&list_lock);
+       list_for_each_entry(asd, &notifier->asd_list, asd_list) {
+-              ret = v4l2_async_notifier_asd_valid(notifier, asd, i++);
++              ret = v4l2_async_nf_asd_valid(notifier, asd, i++);
+               if (ret)
+                       goto err_unlock;
+               list_add_tail(&asd->list, &notifier->waiting);
+       }
+-      ret = v4l2_async_notifier_try_all_subdevs(notifier);
++      ret = v4l2_async_nf_try_all_subdevs(notifier);
+       if (ret < 0)
+               goto err_unbind;
+-      ret = v4l2_async_notifier_try_complete(notifier);
++      ret = v4l2_async_nf_try_complete(notifier);
+       if (ret < 0)
+               goto err_unbind;
+@@ -512,7 +510,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+       /*
+        * On failure, unbind all sub-devices registered through this notifier.
+        */
+-      v4l2_async_notifier_unbind_all_subdevs(notifier);
++      v4l2_async_nf_unbind_all_subdevs(notifier);
+ err_unlock:
+       mutex_unlock(&list_lock);
+@@ -520,8 +518,8 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+       return ret;
+ }
+-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+-                               struct v4l2_async_notifier *notifier)
++int v4l2_async_nf_register(struct v4l2_device *v4l2_dev,
++                         struct v4l2_async_notifier *notifier)
+ {
+       int ret;
+@@ -530,16 +528,16 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+       notifier->v4l2_dev = v4l2_dev;
+-      ret = __v4l2_async_notifier_register(notifier);
++      ret = __v4l2_async_nf_register(notifier);
+       if (ret)
+               notifier->v4l2_dev = NULL;
+       return ret;
+ }
+-EXPORT_SYMBOL(v4l2_async_notifier_register);
++EXPORT_SYMBOL(v4l2_async_nf_register);
+-int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+-                                      struct v4l2_async_notifier *notifier)
++int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd,
++                                struct v4l2_async_notifier *notifier)
+ {
+       int ret;
+@@ -548,21 +546,21 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+       notifier->sd = sd;
+-      ret = __v4l2_async_notifier_register(notifier);
++      ret = __v4l2_async_nf_register(notifier);
+       if (ret)
+               notifier->sd = NULL;
+       return ret;
+ }
+-EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
++EXPORT_SYMBOL(v4l2_async_subdev_nf_register);
+ static void
+-__v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
++__v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
+ {
+       if (!notifier || (!notifier->v4l2_dev && !notifier->sd))
+               return;
+-      v4l2_async_notifier_unbind_all_subdevs(notifier);
++      v4l2_async_nf_unbind_all_subdevs(notifier);
+       notifier->sd = NULL;
+       notifier->v4l2_dev = NULL;
+@@ -570,17 +568,17 @@ __v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+       list_del(&notifier->list);
+ }
+-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
++void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
+ {
+       mutex_lock(&list_lock);
+-      __v4l2_async_notifier_unregister(notifier);
++      __v4l2_async_nf_unregister(notifier);
+       mutex_unlock(&list_lock);
+ }
+-EXPORT_SYMBOL(v4l2_async_notifier_unregister);
++EXPORT_SYMBOL(v4l2_async_nf_unregister);
+-static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
++static void __v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier)
+ {
+       struct v4l2_async_subdev *asd, *tmp;
+@@ -601,24 +599,24 @@ static void __v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
+       }
+ }
+-void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
++void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier)
+ {
+       mutex_lock(&list_lock);
+-      __v4l2_async_notifier_cleanup(notifier);
++      __v4l2_async_nf_cleanup(notifier);
+       mutex_unlock(&list_lock);
+ }
+-EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup);
++EXPORT_SYMBOL_GPL(v4l2_async_nf_cleanup);
+-int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+-                                 struct v4l2_async_subdev *asd)
++int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier,
++                             struct v4l2_async_subdev *asd)
+ {
+       int ret;
+       mutex_lock(&list_lock);
+-      ret = v4l2_async_notifier_asd_valid(notifier, asd, -1);
++      ret = v4l2_async_nf_asd_valid(notifier, asd, -1);
+       if (ret)
+               goto unlock;
+@@ -628,12 +626,12 @@ int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+       mutex_unlock(&list_lock);
+       return ret;
+ }
+-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_subdev);
++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_subdev);
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+-                                      struct fwnode_handle *fwnode,
+-                                      unsigned int asd_struct_size)
++__v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier,
++                         struct fwnode_handle *fwnode,
++                         unsigned int asd_struct_size)
+ {
+       struct v4l2_async_subdev *asd;
+       int ret;
+@@ -645,7 +643,7 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+       asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+       asd->match.fwnode = fwnode_handle_get(fwnode);
+-      ret = __v4l2_async_notifier_add_subdev(notifier, asd);
++      ret = __v4l2_async_nf_add_subdev(notifier, asd);
+       if (ret) {
+               fwnode_handle_put(fwnode);
+               kfree(asd);
+@@ -654,12 +652,12 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+       return asd;
+ }
+-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_subdev);
++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode);
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+-                                             struct fwnode_handle *endpoint,
+-                                             unsigned int asd_struct_size)
++__v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif,
++                                struct fwnode_handle *endpoint,
++                                unsigned int asd_struct_size)
+ {
+       struct v4l2_async_subdev *asd;
+       struct fwnode_handle *remote;
+@@ -668,21 +666,19 @@ __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif
+       if (!remote)
+               return ERR_PTR(-ENOTCONN);
+-      asd = __v4l2_async_notifier_add_fwnode_subdev(notif, remote,
+-                                                    asd_struct_size);
++      asd = __v4l2_async_nf_add_fwnode(notif, remote, asd_struct_size);
+       /*
+-       * Calling __v4l2_async_notifier_add_fwnode_subdev grabs a refcount,
++       * Calling __v4l2_async_nf_add_fwnode grabs a refcount,
+        * so drop the one we got in fwnode_graph_get_remote_port_parent.
+        */
+       fwnode_handle_put(remote);
+       return asd;
+ }
+-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_fwnode_remote_subdev);
++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_fwnode_remote);
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+-                                   int adapter_id, unsigned short address,
+-                                   unsigned int asd_struct_size)
++__v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, int adapter_id,
++                      unsigned short address, unsigned int asd_struct_size)
+ {
+       struct v4l2_async_subdev *asd;
+       int ret;
+@@ -695,7 +691,7 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+       asd->match.i2c.adapter_id = adapter_id;
+       asd->match.i2c.address = address;
+-      ret = __v4l2_async_notifier_add_subdev(notifier, asd);
++      ret = __v4l2_async_nf_add_subdev(notifier, asd);
+       if (ret) {
+               kfree(asd);
+               return ERR_PTR(ret);
+@@ -703,7 +699,7 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+       return asd;
+ }
+-EXPORT_SYMBOL_GPL(__v4l2_async_notifier_add_i2c_subdev);
++EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c);
+ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+ {
+@@ -725,7 +721,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+       list_for_each_entry(notifier, &notifier_list, list) {
+               struct v4l2_device *v4l2_dev =
+-                      v4l2_async_notifier_find_v4l2_dev(notifier);
++                      v4l2_async_nf_find_v4l2_dev(notifier);
+               struct v4l2_async_subdev *asd;
+               if (!v4l2_dev)
+@@ -739,7 +735,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+               if (ret)
+                       goto err_unbind;
+-              ret = v4l2_async_notifier_try_complete(notifier);
++              ret = v4l2_async_nf_try_complete(notifier);
+               if (ret)
+                       goto err_unbind;
+@@ -761,10 +757,10 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+        */
+       subdev_notifier = v4l2_async_find_subdev_notifier(sd);
+       if (subdev_notifier)
+-              v4l2_async_notifier_unbind_all_subdevs(subdev_notifier);
++              v4l2_async_nf_unbind_all_subdevs(subdev_notifier);
+       if (sd->asd)
+-              v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
++              v4l2_async_nf_call_unbind(notifier, sd, sd->asd);
+       v4l2_async_cleanup(sd);
+       mutex_unlock(&list_lock);
+@@ -780,8 +776,8 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+       mutex_lock(&list_lock);
+-      __v4l2_async_notifier_unregister(sd->subdev_notifier);
+-      __v4l2_async_notifier_cleanup(sd->subdev_notifier);
++      __v4l2_async_nf_unregister(sd->subdev_notifier);
++      __v4l2_async_nf_cleanup(sd->subdev_notifier);
+       kfree(sd->subdev_notifier);
+       sd->subdev_notifier = NULL;
+@@ -790,7 +786,7 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+               list_add(&sd->asd->list, &notifier->waiting);
+-              v4l2_async_notifier_call_unbind(notifier, sd, sd->asd);
++              v4l2_async_nf_call_unbind(notifier, sd, sd->asd);
+       }
+       v4l2_async_cleanup(sd);
+@@ -825,7 +821,7 @@ static void print_waiting_subdev(struct seq_file *s,
+ }
+ static const char *
+-v4l2_async_notifier_name(struct v4l2_async_notifier *notifier)
++v4l2_async_nf_name(struct v4l2_async_notifier *notifier)
+ {
+       if (notifier->v4l2_dev)
+               return notifier->v4l2_dev->name;
+@@ -843,7 +839,7 @@ static int pending_subdevs_show(struct seq_file *s, void *data)
+       mutex_lock(&list_lock);
+       list_for_each_entry(notif, &notifier_list, list) {
+-              seq_printf(s, "%s:\n", v4l2_async_notifier_name(notif));
++              seq_printf(s, "%s:\n", v4l2_async_nf_name(notif));
+               list_for_each_entry(asd, &notif->waiting, list)
+                       print_waiting_subdev(s, asd);
+       }
+diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
+index 5d2eaad1fa684..eb14193cc5aed 100644
+--- a/drivers/media/v4l2-core/v4l2-fwnode.c
++++ b/drivers/media/v4l2-core/v4l2-fwnode.c
+@@ -790,11 +790,11 @@ int v4l2_fwnode_device_parse(struct device *dev,
+ EXPORT_SYMBOL_GPL(v4l2_fwnode_device_parse);
+ static int
+-v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
+-                                        struct v4l2_async_notifier *notifier,
+-                                        struct fwnode_handle *endpoint,
+-                                        unsigned int asd_struct_size,
+-                                        parse_endpoint_func parse_endpoint)
++v4l2_async_nf_fwnode_parse_endpoint(struct device *dev,
++                                  struct v4l2_async_notifier *notifier,
++                                  struct fwnode_handle *endpoint,
++                                  unsigned int asd_struct_size,
++                                  parse_endpoint_func parse_endpoint)
+ {
+       struct v4l2_fwnode_endpoint vep = { .bus_type = 0 };
+       struct v4l2_async_subdev *asd;
+@@ -832,7 +832,7 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
+       if (ret < 0)
+               goto out_err;
+-      ret = __v4l2_async_notifier_add_subdev(notifier, asd);
++      ret = __v4l2_async_nf_add_subdev(notifier, asd);
+       if (ret < 0) {
+               /* not an error if asd already exists */
+               if (ret == -EEXIST)
+@@ -850,12 +850,11 @@ v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
+ }
+ static int
+-__v4l2_async_notifier_parse_fwnode_ep(struct device *dev,
+-                                    struct v4l2_async_notifier *notifier,
+-                                    size_t asd_struct_size,
+-                                    unsigned int port,
+-                                    bool has_port,
+-                                    parse_endpoint_func parse_endpoint)
++__v4l2_async_nf_parse_fwnode_ep(struct device *dev,
++                              struct v4l2_async_notifier *notifier,
++                              size_t asd_struct_size, unsigned int port,
++                              bool has_port,
++                              parse_endpoint_func parse_endpoint)
+ {
+       struct fwnode_handle *fwnode;
+       int ret = 0;
+@@ -884,11 +883,10 @@ __v4l2_async_notifier_parse_fwnode_ep(struct device *dev,
+                               continue;
+               }
+-              ret = v4l2_async_notifier_fwnode_parse_endpoint(dev,
+-                                                              notifier,
+-                                                              fwnode,
+-                                                              asd_struct_size,
+-                                                              parse_endpoint);
++              ret = v4l2_async_nf_fwnode_parse_endpoint(dev, notifier,
++                                                        fwnode,
++                                                        asd_struct_size,
++                                                        parse_endpoint);
+               if (ret < 0)
+                       break;
+       }
+@@ -899,16 +897,15 @@ __v4l2_async_notifier_parse_fwnode_ep(struct device *dev,
+ }
+ int
+-v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev,
+-                                         struct v4l2_async_notifier *notifier,
+-                                         size_t asd_struct_size,
+-                                         parse_endpoint_func parse_endpoint)
++v4l2_async_nf_parse_fwnode_endpoints(struct device *dev,
++                                   struct v4l2_async_notifier *notifier,
++                                   size_t asd_struct_size,
++                                   parse_endpoint_func parse_endpoint)
+ {
+-      return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier,
+-                                                   asd_struct_size, 0,
+-                                                   false, parse_endpoint);
++      return __v4l2_async_nf_parse_fwnode_ep(dev, notifier, asd_struct_size,
++                                             0, false, parse_endpoint);
+ }
+-EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
++EXPORT_SYMBOL_GPL(v4l2_async_nf_parse_fwnode_endpoints);
+ /*
+  * v4l2_fwnode_reference_parse - parse references for async sub-devices
+@@ -952,9 +949,8 @@ static int v4l2_fwnode_reference_parse(struct device *dev,
+            index++) {
+               struct v4l2_async_subdev *asd;
+-              asd = v4l2_async_notifier_add_fwnode_subdev(notifier,
+-                                                          args.fwnode,
+-                                                          struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode(notifier, args.fwnode,
++                                             struct v4l2_async_subdev);
+               fwnode_handle_put(args.fwnode);
+               if (IS_ERR(asd)) {
+                       /* not an error if asd already exists */
+@@ -1253,8 +1249,8 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
+            index++) {
+               struct v4l2_async_subdev *asd;
+-              asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
+-                                                          struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode(notifier, fwnode,
++                                             struct v4l2_async_subdev);
+               fwnode_handle_put(fwnode);
+               if (IS_ERR(asd)) {
+                       ret = PTR_ERR(asd);
+@@ -1270,7 +1266,7 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
+ }
+ /**
+- * v4l2_async_notifier_parse_fwnode_sensor - parse common references on
++ * v4l2_async_nf_parse_fwnode_sensor - parse common references on
+  *                                         sensors for async sub-devices
+  * @dev: the device node the properties of which are parsed for references
+  * @notifier: the async notifier where the async subdevs will be added
+@@ -1279,7 +1275,7 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
+  * sensor and set up async sub-devices for them.
+  *
+  * Any notifier populated using this function must be released with a call to
+- * v4l2_async_notifier_release() after it has been unregistered and the async
++ * v4l2_async_nf_release() after it has been unregistered and the async
+  * sub-devices are no longer in use, even in the case the function returned an
+  * error.
+  *
+@@ -1288,8 +1284,8 @@ v4l2_fwnode_reference_parse_int_props(struct device *dev,
+  *       -EINVAL if property parsing failed
+  */
+ static int
+-v4l2_async_notifier_parse_fwnode_sensor(struct device *dev,
+-                                      struct v4l2_async_notifier *notifier)
++v4l2_async_nf_parse_fwnode_sensor(struct device *dev,
++                                struct v4l2_async_notifier *notifier)
+ {
+       static const char * const led_props[] = { "led" };
+       static const struct v4l2_fwnode_int_props props[] = {
+@@ -1330,13 +1326,13 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd)
+       if (!notifier)
+               return -ENOMEM;
+-      v4l2_async_notifier_init(notifier);
++      v4l2_async_nf_init(notifier);
+-      ret = v4l2_async_notifier_parse_fwnode_sensor(sd->dev, notifier);
++      ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier);
+       if (ret < 0)
+               goto out_cleanup;
+-      ret = v4l2_async_subdev_notifier_register(sd, notifier);
++      ret = v4l2_async_subdev_nf_register(sd, notifier);
+       if (ret < 0)
+               goto out_cleanup;
+@@ -1349,10 +1345,10 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd)
+       return 0;
+ out_unregister:
+-      v4l2_async_notifier_unregister(notifier);
++      v4l2_async_nf_unregister(notifier);
+ out_cleanup:
+-      v4l2_async_notifier_cleanup(notifier);
++      v4l2_async_nf_cleanup(notifier);
+       kfree(notifier);
+       return ret;
+diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
+index bb1305c9daaf5..45f9d797b9da6 100644
+--- a/drivers/staging/media/imx/imx-media-csi.c
++++ b/drivers/staging/media/imx/imx-media-csi.c
+@@ -1924,7 +1924,7 @@ static int imx_csi_async_register(struct csi_priv *priv)
+       unsigned int port;
+       int ret;
+-      v4l2_async_notifier_init(&priv->notifier);
++      v4l2_async_nf_init(&priv->notifier);
+       /* get this CSI's port id */
+       ret = fwnode_property_read_u32(dev_fwnode(priv->dev), "reg", &port);
+@@ -1935,8 +1935,8 @@ static int imx_csi_async_register(struct csi_priv *priv)
+                                            port, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+       if (ep) {
+-              asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                      &priv->notifier, ep, struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep,
++                                                    struct v4l2_async_subdev);
+               fwnode_handle_put(ep);
+@@ -1950,8 +1950,7 @@ static int imx_csi_async_register(struct csi_priv *priv)
+       priv->notifier.ops = &csi_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&priv->sd,
+-                                                &priv->notifier);
++      ret = v4l2_async_subdev_nf_register(&priv->sd, &priv->notifier);
+       if (ret)
+               return ret;
+@@ -2040,8 +2039,8 @@ static int imx_csi_probe(struct platform_device *pdev)
+       return 0;
+ cleanup:
+-      v4l2_async_notifier_unregister(&priv->notifier);
+-      v4l2_async_notifier_cleanup(&priv->notifier);
++      v4l2_async_nf_unregister(&priv->notifier);
++      v4l2_async_nf_cleanup(&priv->notifier);
+ free:
+       v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
+       mutex_destroy(&priv->lock);
+@@ -2055,8 +2054,8 @@ static int imx_csi_remove(struct platform_device *pdev)
+       v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
+       mutex_destroy(&priv->lock);
+-      v4l2_async_notifier_unregister(&priv->notifier);
+-      v4l2_async_notifier_cleanup(&priv->notifier);
++      v4l2_async_nf_unregister(&priv->notifier);
++      v4l2_async_nf_cleanup(&priv->notifier);
+       v4l2_async_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c
+index 4d873726a461b..80b69a9a752cb 100644
+--- a/drivers/staging/media/imx/imx-media-dev-common.c
++++ b/drivers/staging/media/imx/imx-media-dev-common.c
+@@ -381,7 +381,7 @@ struct imx_media_dev *imx_media_dev_init(struct device *dev,
+       INIT_LIST_HEAD(&imxmd->vdev_list);
+-      v4l2_async_notifier_init(&imxmd->notifier);
++      v4l2_async_nf_init(&imxmd->notifier);
+       return imxmd;
+@@ -405,11 +405,10 @@ int imx_media_dev_notifier_register(struct imx_media_dev *imxmd,
+       /* prepare the async subdev notifier and register it */
+       imxmd->notifier.ops = ops ? ops : &imx_media_notifier_ops;
+-      ret = v4l2_async_notifier_register(&imxmd->v4l2_dev,
+-                                         &imxmd->notifier);
++      ret = v4l2_async_nf_register(&imxmd->v4l2_dev, &imxmd->notifier);
+       if (ret) {
+               v4l2_err(&imxmd->v4l2_dev,
+-                       "v4l2_async_notifier_register failed with %d\n", ret);
++                       "v4l2_async_nf_register failed with %d\n", ret);
+               return ret;
+       }
+diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
+index 338b8bd0bb076..f85462214e221 100644
+--- a/drivers/staging/media/imx/imx-media-dev.c
++++ b/drivers/staging/media/imx/imx-media-dev.c
+@@ -94,7 +94,7 @@ static int imx_media_probe(struct platform_device *pdev)
+       return 0;
+ cleanup:
+-      v4l2_async_notifier_cleanup(&imxmd->notifier);
++      v4l2_async_nf_cleanup(&imxmd->notifier);
+       v4l2_device_unregister(&imxmd->v4l2_dev);
+       media_device_cleanup(&imxmd->md);
+@@ -113,9 +113,9 @@ static int imx_media_remove(struct platform_device *pdev)
+               imxmd->m2m_vdev = NULL;
+       }
+-      v4l2_async_notifier_unregister(&imxmd->notifier);
++      v4l2_async_nf_unregister(&imxmd->notifier);
+       imx_media_unregister_ipu_internal_subdevs(imxmd);
+-      v4l2_async_notifier_cleanup(&imxmd->notifier);
++      v4l2_async_nf_cleanup(&imxmd->notifier);
+       media_device_unregister(&imxmd->md);
+       v4l2_device_unregister(&imxmd->v4l2_dev);
+       media_device_cleanup(&imxmd->md);
+diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
+index b677cf0e0c849..59f1eb7b62bcd 100644
+--- a/drivers/staging/media/imx/imx-media-of.c
++++ b/drivers/staging/media/imx/imx-media-of.c
+@@ -29,9 +29,9 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd,
+       }
+       /* add CSI fwnode to async notifier */
+-      asd = v4l2_async_notifier_add_fwnode_subdev(&imxmd->notifier,
+-                                                  of_fwnode_handle(csi_np),
+-                                                  struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode(&imxmd->notifier,
++                                     of_fwnode_handle(csi_np),
++                                     struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               if (ret == -EEXIST)
+diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
+index 9de0ebd439dc6..a0941fc2907b7 100644
+--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
++++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
+@@ -647,7 +647,7 @@ static int csi2_async_register(struct csi2_dev *csi2)
+       struct fwnode_handle *ep;
+       int ret;
+-      v4l2_async_notifier_init(&csi2->notifier);
++      v4l2_async_nf_init(&csi2->notifier);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+@@ -663,8 +663,8 @@ static int csi2_async_register(struct csi2_dev *csi2)
+       dev_dbg(csi2->dev, "data lanes: %d\n", vep.bus.mipi_csi2.num_data_lanes);
+       dev_dbg(csi2->dev, "flags: 0x%08x\n", vep.bus.mipi_csi2.flags);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-              &csi2->notifier, ep, struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&csi2->notifier, ep,
++                                            struct v4l2_async_subdev);
+       fwnode_handle_put(ep);
+       if (IS_ERR(asd))
+@@ -672,8 +672,7 @@ static int csi2_async_register(struct csi2_dev *csi2)
+       csi2->notifier.ops = &csi2_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&csi2->sd,
+-                                                &csi2->notifier);
++      ret = v4l2_async_subdev_nf_register(&csi2->sd, &csi2->notifier);
+       if (ret)
+               return ret;
+@@ -768,8 +767,8 @@ static int csi2_probe(struct platform_device *pdev)
+       return 0;
+ clean_notifier:
+-      v4l2_async_notifier_unregister(&csi2->notifier);
+-      v4l2_async_notifier_cleanup(&csi2->notifier);
++      v4l2_async_nf_unregister(&csi2->notifier);
++      v4l2_async_nf_cleanup(&csi2->notifier);
+       clk_disable_unprepare(csi2->dphy_clk);
+ pllref_off:
+       clk_disable_unprepare(csi2->pllref_clk);
+@@ -783,8 +782,8 @@ static int csi2_remove(struct platform_device *pdev)
+       struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+       struct csi2_dev *csi2 = sd_to_dev(sd);
+-      v4l2_async_notifier_unregister(&csi2->notifier);
+-      v4l2_async_notifier_cleanup(&csi2->notifier);
++      v4l2_async_nf_unregister(&csi2->notifier);
++      v4l2_async_nf_cleanup(&csi2->notifier);
+       v4l2_async_unregister_subdev(sd);
+       clk_disable_unprepare(csi2->dphy_clk);
+       clk_disable_unprepare(csi2->pllref_clk);
+diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
+index 1271837329124..2288dadb2683a 100644
+--- a/drivers/staging/media/imx/imx7-media-csi.c
++++ b/drivers/staging/media/imx/imx7-media-csi.c
+@@ -1099,13 +1099,13 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
+       struct fwnode_handle *ep;
+       int ret;
+-      v4l2_async_notifier_init(&csi->notifier);
++      v4l2_async_nf_init(&csi->notifier);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+       if (ep) {
+-              asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-                      &csi->notifier, ep, struct v4l2_async_subdev);
++              asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
++                                                    struct v4l2_async_subdev);
+               fwnode_handle_put(ep);
+@@ -1119,7 +1119,7 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
+       csi->notifier.ops = &imx7_csi_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier);
++      ret = v4l2_async_subdev_nf_register(&csi->sd, &csi->notifier);
+       if (ret)
+               return ret;
+@@ -1210,12 +1210,12 @@ static int imx7_csi_probe(struct platform_device *pdev)
+       return 0;
+ subdev_notifier_cleanup:
+-      v4l2_async_notifier_unregister(&csi->notifier);
+-      v4l2_async_notifier_cleanup(&csi->notifier);
++      v4l2_async_nf_unregister(&csi->notifier);
++      v4l2_async_nf_cleanup(&csi->notifier);
+ cleanup:
+-      v4l2_async_notifier_unregister(&imxmd->notifier);
+-      v4l2_async_notifier_cleanup(&imxmd->notifier);
++      v4l2_async_nf_unregister(&imxmd->notifier);
++      v4l2_async_nf_cleanup(&imxmd->notifier);
+       v4l2_device_unregister(&imxmd->v4l2_dev);
+       media_device_unregister(&imxmd->md);
+       media_device_cleanup(&imxmd->md);
+@@ -1232,15 +1232,15 @@ static int imx7_csi_remove(struct platform_device *pdev)
+       struct imx7_csi *csi = v4l2_get_subdevdata(sd);
+       struct imx_media_dev *imxmd = csi->imxmd;
+-      v4l2_async_notifier_unregister(&imxmd->notifier);
+-      v4l2_async_notifier_cleanup(&imxmd->notifier);
++      v4l2_async_nf_unregister(&imxmd->notifier);
++      v4l2_async_nf_cleanup(&imxmd->notifier);
+       media_device_unregister(&imxmd->md);
+       v4l2_device_unregister(&imxmd->v4l2_dev);
+       media_device_cleanup(&imxmd->md);
+-      v4l2_async_notifier_unregister(&csi->notifier);
+-      v4l2_async_notifier_cleanup(&csi->notifier);
++      v4l2_async_nf_unregister(&csi->notifier);
++      v4l2_async_nf_cleanup(&csi->notifier);
+       v4l2_async_unregister_subdev(sd);
+       mutex_destroy(&csi->lock);
+diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
+index d35e523741168..9ea723bb5f209 100644
+--- a/drivers/staging/media/imx/imx7-mipi-csis.c
++++ b/drivers/staging/media/imx/imx7-mipi-csis.c
+@@ -1160,7 +1160,7 @@ static int mipi_csis_async_register(struct csi_state *state)
+       unsigned int i;
+       int ret;
+-      v4l2_async_notifier_init(&state->notifier);
++      v4l2_async_nf_init(&state->notifier);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+@@ -1185,8 +1185,8 @@ static int mipi_csis_async_register(struct csi_state *state)
+       dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes);
+       dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+-              &state->notifier, ep, struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
++                                            struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto err_parse;
+@@ -1196,7 +1196,7 @@ static int mipi_csis_async_register(struct csi_state *state)
+       state->notifier.ops = &mipi_csis_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier);
++      ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier);
+       if (ret)
+               return ret;
+@@ -1427,8 +1427,8 @@ static int mipi_csis_probe(struct platform_device *pdev)
+       mipi_csis_debugfs_exit(state);
+ cleanup:
+       media_entity_cleanup(&state->sd.entity);
+-      v4l2_async_notifier_unregister(&state->notifier);
+-      v4l2_async_notifier_cleanup(&state->notifier);
++      v4l2_async_nf_unregister(&state->notifier);
++      v4l2_async_nf_cleanup(&state->notifier);
+       v4l2_async_unregister_subdev(&state->sd);
+ disable_clock:
+       mipi_csis_clk_disable(state);
+@@ -1443,8 +1443,8 @@ static int mipi_csis_remove(struct platform_device *pdev)
+       struct csi_state *state = mipi_sd_to_csis_state(sd);
+       mipi_csis_debugfs_exit(state);
+-      v4l2_async_notifier_unregister(&state->notifier);
+-      v4l2_async_notifier_cleanup(&state->notifier);
++      v4l2_async_nf_unregister(&state->notifier);
++      v4l2_async_nf_cleanup(&state->notifier);
+       v4l2_async_unregister_subdev(&state->sd);
+       pm_runtime_disable(&pdev->dev);
+diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
+index 1d28313dbed7d..3b9fa75efac6b 100644
+--- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c
++++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
+@@ -640,7 +640,7 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state)
+       unsigned int i;
+       int ret;
+-      v4l2_async_notifier_init(&state->notifier);
++      v4l2_async_nf_init(&state->notifier);
+       ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
+                                            FWNODE_GRAPH_ENDPOINT_NEXT);
+@@ -666,8 +666,8 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state)
+               state->bus.num_data_lanes,
+               state->bus.flags);
+-      asd = v4l2_async_notifier_add_fwnode_remote_subdev(&state->notifier,
+-                                                         ep, struct v4l2_async_subdev);
++      asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
++                                            struct v4l2_async_subdev);
+       if (IS_ERR(asd)) {
+               ret = PTR_ERR(asd);
+               goto err_parse;
+@@ -677,7 +677,7 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state)
+       state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
+-      ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier);
++      ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier);
+       if (ret)
+               return ret;
+@@ -957,8 +957,8 @@ static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
+       imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
+       media_entity_cleanup(&state->sd.entity);
+-      v4l2_async_notifier_unregister(&state->notifier);
+-      v4l2_async_notifier_cleanup(&state->notifier);
++      v4l2_async_nf_unregister(&state->notifier);
++      v4l2_async_nf_cleanup(&state->notifier);
+       v4l2_async_unregister_subdev(&state->sd);
+ icc:
+       imx8mq_mipi_csi_release_icc(pdev);
+@@ -973,8 +973,8 @@ static int imx8mq_mipi_csi_remove(struct platform_device *pdev)
+       struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+       struct csi_state *state = mipi_sd_to_csi2_state(sd);
+-      v4l2_async_notifier_unregister(&state->notifier);
+-      v4l2_async_notifier_cleanup(&state->notifier);
++      v4l2_async_nf_unregister(&state->notifier);
++      v4l2_async_nf_cleanup(&state->notifier);
+       v4l2_async_unregister_subdev(&state->sd);
+       pm_runtime_disable(&pdev->dev);
+diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
+index d321790b07d95..69d9787d53384 100644
+--- a/drivers/staging/media/tegra-video/vi.c
++++ b/drivers/staging/media/tegra-video/vi.c
+@@ -1272,7 +1272,7 @@ static int tegra_channel_init(struct tegra_vi_channel *chan)
+       }
+       if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
+-              v4l2_async_notifier_init(&chan->notifier);
++              v4l2_async_nf_init(&chan->notifier);
+       return 0;
+@@ -1811,8 +1811,8 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan,
+                       continue;
+               }
+-              tvge = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier, remote,
+-                                                           struct tegra_vi_graph_entity);
++              tvge = v4l2_async_nf_add_fwnode(&chan->notifier, remote,
++                                              struct tegra_vi_graph_entity);
+               if (IS_ERR(tvge)) {
+                       ret = PTR_ERR(tvge);
+                       dev_err(vi->dev,
+@@ -1834,7 +1834,7 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan,
+ cleanup:
+       dev_err(vi->dev, "failed parsing the graph: %d\n", ret);
+-      v4l2_async_notifier_cleanup(&chan->notifier);
++      v4l2_async_nf_cleanup(&chan->notifier);
+       of_node_put(node);
+       return ret;
+ }
+@@ -1868,13 +1868,12 @@ static int tegra_vi_graph_init(struct tegra_vi *vi)
+                       continue;
+               chan->notifier.ops = &tegra_vi_async_ops;
+-              ret = v4l2_async_notifier_register(&vid->v4l2_dev,
+-                                                 &chan->notifier);
++              ret = v4l2_async_nf_register(&vid->v4l2_dev, &chan->notifier);
+               if (ret < 0) {
+                       dev_err(vi->dev,
+                               "failed to register channel %d notifier: %d\n",
+                               chan->portnos[0], ret);
+-                      v4l2_async_notifier_cleanup(&chan->notifier);
++                      v4l2_async_nf_cleanup(&chan->notifier);
+               }
+       }
+@@ -1887,8 +1886,8 @@ static void tegra_vi_graph_cleanup(struct tegra_vi *vi)
+       list_for_each_entry(chan, &vi->vi_chans, list) {
+               vb2_video_unregister_device(&chan->video);
+-              v4l2_async_notifier_unregister(&chan->notifier);
+-              v4l2_async_notifier_cleanup(&chan->notifier);
++              v4l2_async_nf_unregister(&chan->notifier);
++              v4l2_async_nf_cleanup(&chan->notifier);
+       }
+ }
+diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
+index fa4901162663b..13ff3ad948f43 100644
+--- a/include/media/v4l2-async.h
++++ b/include/media/v4l2-async.h
+@@ -123,45 +123,45 @@ struct v4l2_async_notifier {
+ void v4l2_async_debug_init(struct dentry *debugfs_dir);
+ /**
+- * v4l2_async_notifier_init - Initialize a notifier.
++ * v4l2_async_nf_init - Initialize a notifier.
+  *
+  * @notifier: pointer to &struct v4l2_async_notifier
+  *
+  * This function initializes the notifier @asd_list. It must be called
+  * before adding a subdevice to a notifier, using one of:
+- * v4l2_async_notifier_add_fwnode_remote_subdev(),
+- * v4l2_async_notifier_add_fwnode_subdev(),
+- * v4l2_async_notifier_add_i2c_subdev(),
+- * __v4l2_async_notifier_add_subdev() or
+- * v4l2_async_notifier_parse_fwnode_endpoints().
++ * v4l2_async_nf_add_fwnode_remote(),
++ * v4l2_async_nf_add_fwnode(),
++ * v4l2_async_nf_add_i2c(),
++ * __v4l2_async_nf_add_subdev() or
++ * v4l2_async_nf_parse_fwnode_endpoints().
+  */
+-void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
++void v4l2_async_nf_init(struct v4l2_async_notifier *notifier);
+ /**
+- * __v4l2_async_notifier_add_subdev - Add an async subdev to the
++ * __v4l2_async_nf_add_subdev - Add an async subdev to the
+  *                            notifier's master asd list.
+  *
+  * @notifier: pointer to &struct v4l2_async_notifier
+  * @asd: pointer to &struct v4l2_async_subdev
+  *
+  * \warning: Drivers should avoid using this function and instead use one of:
+- * v4l2_async_notifier_add_fwnode_subdev(),
+- * v4l2_async_notifier_add_fwnode_remote_subdev() or
+- * v4l2_async_notifier_add_i2c_subdev().
++ * v4l2_async_nf_add_fwnode(),
++ * v4l2_async_nf_add_fwnode_remote() or
++ * v4l2_async_nf_add_i2c().
+  *
+  * Call this function before registering a notifier to link the provided @asd to
+  * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as
+  * it will be freed by the framework when the notifier is destroyed.
+  */
+-int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+-                                 struct v4l2_async_subdev *asd);
++int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier,
++                             struct v4l2_async_subdev *asd);
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+-                                      struct fwnode_handle *fwnode,
+-                                      unsigned int asd_struct_size);
++__v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier,
++                         struct fwnode_handle *fwnode,
++                         unsigned int asd_struct_size);
+ /**
+- * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async
++ * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async
+  *                            subdev to the notifier's master asd_list.
+  *
+  * @notifier: pointer to &struct v4l2_async_notifier
+@@ -175,16 +175,15 @@ __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+  * notifiers @asd_list. The function also gets a reference of the fwnode which
+  * is released later at notifier cleanup time.
+  */
+-#define v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, type) \
+-      ((type *)__v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, \
+-                                                         sizeof(type)))
++#define v4l2_async_nf_add_fwnode(notifier, fwnode, type)              \
++      ((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type)))
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+-                                             struct fwnode_handle *endpoint,
+-                                             unsigned int asd_struct_size);
++__v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif,
++                                struct fwnode_handle *endpoint,
++                                unsigned int asd_struct_size);
+ /**
+- * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode
++ * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode
+  *                                              remote async subdev to the
+  *                                              notifier's master asd_list.
+  *
+@@ -200,20 +199,18 @@ __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif
+  * function also gets a reference of the fwnode which is released later at
+  * notifier cleanup time.
+  *
+- * This is just like v4l2_async_notifier_add_fwnode_subdev(), but with the
++ * This is just like v4l2_async_nf_add_fwnode(), but with the
+  * exception that the fwnode refers to a local endpoint, not the remote one.
+  */
+-#define v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep, type) \
+-      ((type *)                                                       \
+-       __v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep,   \
+-                                                      sizeof(type)))
++#define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \
++      ((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type)))
+ struct v4l2_async_subdev *
+-__v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+-                                   int adapter_id, unsigned short address,
+-                                   unsigned int asd_struct_size);
++__v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier,
++                      int adapter_id, unsigned short address,
++                      unsigned int asd_struct_size);
+ /**
+- * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
++ * v4l2_async_nf_add_i2c - Allocate and add an i2c async
+  *                            subdev to the notifier's master asd_list.
+  *
+  * @notifier: pointer to &struct v4l2_async_notifier
+@@ -223,59 +220,59 @@ __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+  *      v4l2_async_subdev shall be the first member of the driver's async
+  *      sub-device struct, i.e. both begin at the same memory address.
+  *
+- * Same as v4l2_async_notifier_add_fwnode_subdev() but for I2C matched
++ * Same as v4l2_async_nf_add_fwnode() but for I2C matched
+  * sub-devices.
+  */
+-#define v4l2_async_notifier_add_i2c_subdev(notifier, adapter, address, type) \
+-      ((type *)__v4l2_async_notifier_add_i2c_subdev(notifier, adapter, \
+-                                                    address, sizeof(type)))
++#define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \
++      ((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \
++                                       sizeof(type)))
+ /**
+- * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
++ * v4l2_async_nf_register - registers a subdevice asynchronous notifier
+  *
+  * @v4l2_dev: pointer to &struct v4l2_device
+  * @notifier: pointer to &struct v4l2_async_notifier
+  */
+-int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+-                               struct v4l2_async_notifier *notifier);
++int v4l2_async_nf_register(struct v4l2_device *v4l2_dev,
++                         struct v4l2_async_notifier *notifier);
+ /**
+- * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous
++ * v4l2_async_subdev_nf_register - registers a subdevice asynchronous
+  *                                     notifier for a sub-device
+  *
+  * @sd: pointer to &struct v4l2_subdev
+  * @notifier: pointer to &struct v4l2_async_notifier
+  */
+-int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+-                                      struct v4l2_async_notifier *notifier);
++int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd,
++                                struct v4l2_async_notifier *notifier);
+ /**
+- * v4l2_async_notifier_unregister - unregisters a subdevice
++ * v4l2_async_nf_unregister - unregisters a subdevice
+  *    asynchronous notifier
+  *
+  * @notifier: pointer to &struct v4l2_async_notifier
+  */
+-void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
++void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier);
+ /**
+- * v4l2_async_notifier_cleanup - clean up notifier resources
++ * v4l2_async_nf_cleanup - clean up notifier resources
+  * @notifier: the notifier the resources of which are to be cleaned up
+  *
+  * Release memory resources related to a notifier, including the async
+  * sub-devices allocated for the purposes of the notifier but not the notifier
+  * itself. The user is responsible for calling this function to clean up the
+  * notifier after calling
+- * v4l2_async_notifier_add_fwnode_remote_subdev(),
+- * v4l2_async_notifier_add_fwnode_subdev(),
+- * v4l2_async_notifier_add_i2c_subdev(),
+- * __v4l2_async_notifier_add_subdev() or
+- * v4l2_async_notifier_parse_fwnode_endpoints().
++ * v4l2_async_nf_add_fwnode_remote(),
++ * v4l2_async_nf_add_fwnode(),
++ * v4l2_async_nf_add_i2c(),
++ * __v4l2_async_nf_add_subdev() or
++ * v4l2_async_nf_parse_fwnode_endpoints().
+  *
+- * There is no harm from calling v4l2_async_notifier_cleanup() in other
++ * There is no harm from calling v4l2_async_nf_cleanup() in other
+  * cases as long as its memory has been zeroed after it has been
+  * allocated.
+  */
+-void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
++void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier);
+ /**
+  * v4l2_async_register_subdev - registers a sub-device to the asynchronous
+@@ -295,7 +292,7 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
+  *
+  * This function is just like v4l2_async_register_subdev() with the exception
+  * that calling it will also parse firmware interfaces for remote references
+- * using v4l2_async_notifier_parse_fwnode_sensor() and registers the
++ * using v4l2_async_nf_parse_fwnode_sensor() and registers the
+  * async sub-devices. The sub-device is similarly unregistered by calling
+  * v4l2_async_unregister_subdev().
+  *
+diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
+index 7ab033b819eb0..9c97f1dbd1c68 100644
+--- a/include/media/v4l2-fwnode.h
++++ b/include/media/v4l2-fwnode.h
+@@ -463,7 +463,7 @@ typedef int (*parse_endpoint_func)(struct device *dev,
+                                 struct v4l2_async_subdev *asd);
+ /**
+- * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a
++ * v4l2_async_nf_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a
+  *                                            device node
+  * @dev: the device the endpoints of which are to be parsed
+  * @notifier: notifier for @dev
+@@ -496,7 +496,7 @@ typedef int (*parse_endpoint_func)(struct device *dev,
+  * to retain that configuration, the user needs to allocate memory for it.
+  *
+  * Any notifier populated using this function must be released with a call to
+- * v4l2_async_notifier_cleanup() after it has been unregistered and the async
++ * v4l2_async_nf_cleanup() after it has been unregistered and the async
+  * sub-devices are no longer in use, even if the function returned an error.
+  *
+  * Return: %0 on success, including when no async sub-devices are found
+@@ -505,10 +505,10 @@ typedef int (*parse_endpoint_func)(struct device *dev,
+  *       Other error codes as returned by @parse_endpoint
+  */
+ int
+-v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev,
+-                                         struct v4l2_async_notifier *notifier,
+-                                         size_t asd_struct_size,
+-                                         parse_endpoint_func parse_endpoint);
++v4l2_async_nf_parse_fwnode_endpoints(struct device *dev,
++                                   struct v4l2_async_notifier *notifier,
++                                   size_t asd_struct_size,
++                                   parse_endpoint_func parse_endpoint);
+ /* Helper macros to access the connector links. */
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch b/queue-5.15/media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch
new file mode 100644 (file)
index 0000000..e1e39ed
--- /dev/null
@@ -0,0 +1,56 @@
+From ac72e3bee2a0ab408d6920be85269e70b30239de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 16:12:02 +0800
+Subject: media: vidtv: mux: Add check and kfree for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 1fd6eb12642e0c32692924ff359c07de4b781d78 ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+Moreover, use kfree() in the later error handling in order to avoid
+memory leak.
+
+Fixes: c2f78f0cb294 ("media: vidtv: psi: add a Network Information Table (NIT)")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/test-drivers/vidtv/vidtv_mux.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c
+index b51e6a3b8cbeb..f99878eff7ace 100644
+--- a/drivers/media/test-drivers/vidtv/vidtv_mux.c
++++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c
+@@ -504,13 +504,16 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe,
+       m->priv = args->priv;
+       m->network_id = args->network_id;
+       m->network_name = kstrdup(args->network_name, GFP_KERNEL);
++      if (!m->network_name)
++              goto free_mux_buf;
++
+       m->timing.current_jiffies = get_jiffies_64();
+       if (args->channels)
+               m->channels = args->channels;
+       else
+               if (vidtv_channels_init(m) < 0)
+-                      goto free_mux_buf;
++                      goto free_mux_network_name;
+       /* will alloc data for pmt_sections after initializing pat */
+       if (vidtv_channel_si_init(m) < 0)
+@@ -527,6 +530,8 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe,
+       vidtv_channel_si_destroy(m);
+ free_channels:
+       vidtv_channels_destroy(m);
++free_mux_network_name:
++      kfree(m->network_name);
+ free_mux_buf:
+       vfree(m->mux_buf);
+ free_mux:
+-- 
+2.42.0
+
diff --git a/queue-5.15/media-vidtv-psi-add-check-for-kstrdup.patch b/queue-5.15/media-vidtv-psi-add-check-for-kstrdup.patch
new file mode 100644 (file)
index 0000000..a42978b
--- /dev/null
@@ -0,0 +1,111 @@
+From c87b962ba806c7ccfb1dff3fcc072ef0a9e80b10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 16:12:01 +0800
+Subject: media: vidtv: psi: Add check for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 76a2c5df6ca8bd8ada45e953b8c72b746f42918d ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+
+Fixes: 7a7899f6f58e ("media: vidtv: psi: Implement an Event Information Table (EIT)")
+Fixes: c2f78f0cb294 ("media: vidtv: psi: add a Network Information Table (NIT)")
+Fixes: f90cf6079bf6 ("media: vidtv: add a bridge driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/test-drivers/vidtv/vidtv_psi.c | 45 +++++++++++++++++---
+ 1 file changed, 40 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c
+index c11ac8dca73df..988324587c4ed 100644
+--- a/drivers/media/test-drivers/vidtv/vidtv_psi.c
++++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c
+@@ -307,16 +307,29 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc
+       desc->service_name_len = service_name_len;
+-      if (service_name && service_name_len)
++      if (service_name && service_name_len) {
+               desc->service_name = kstrdup(service_name, GFP_KERNEL);
++              if (!desc->service_name)
++                      goto free_desc;
++      }
+       desc->provider_name_len = provider_name_len;
+-      if (provider_name && provider_name_len)
++      if (provider_name && provider_name_len) {
+               desc->provider_name = kstrdup(provider_name, GFP_KERNEL);
++              if (!desc->provider_name)
++                      goto free_desc_service_name;
++      }
+       vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
+       return desc;
++
++free_desc_service_name:
++      if (service_name && service_name_len)
++              kfree(desc->service_name);
++free_desc:
++      kfree(desc);
++      return NULL;
+ }
+ struct vidtv_psi_desc_registration
+@@ -361,8 +374,13 @@ struct vidtv_psi_desc_network_name
+       desc->length = network_name_len;
+-      if (network_name && network_name_len)
++      if (network_name && network_name_len) {
+               desc->network_name = kstrdup(network_name, GFP_KERNEL);
++              if (!desc->network_name) {
++                      kfree(desc);
++                      return NULL;
++              }
++      }
+       vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
+       return desc;
+@@ -448,15 +466,32 @@ struct vidtv_psi_desc_short_event
+               iso_language_code = "eng";
+       desc->iso_language_code = kstrdup(iso_language_code, GFP_KERNEL);
++      if (!desc->iso_language_code)
++              goto free_desc;
+-      if (event_name && event_name_len)
++      if (event_name && event_name_len) {
+               desc->event_name = kstrdup(event_name, GFP_KERNEL);
++              if (!desc->event_name)
++                      goto free_desc_language_code;
++      }
+-      if (text && text_len)
++      if (text && text_len) {
+               desc->text = kstrdup(text, GFP_KERNEL);
++              if (!desc->text)
++                      goto free_desc_event_name;
++      }
+       vidtv_psi_desc_chain(head, (struct vidtv_psi_desc *)desc);
+       return desc;
++
++free_desc_event_name:
++      if (event_name && event_name_len)
++              kfree(desc->event_name);
++free_desc_language_code:
++      kfree(desc->iso_language_code);
++free_desc:
++      kfree(desc);
++      return NULL;
+ }
+ struct vidtv_psi_desc *vidtv_psi_desc_clone(struct vidtv_psi_desc *desc)
+-- 
+2.42.0
+
diff --git a/queue-5.15/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch b/queue-5.15/mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch
new file mode 100644 (file)
index 0000000..2455999
--- /dev/null
@@ -0,0 +1,50 @@
+From 27e0903b660081f285211c9ae8bb3263d5d1d2c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Oct 2023 22:54:14 +0200
+Subject: mfd: arizona-spi: Set pdata.hpdet_channel for ACPI enumerated devs
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 831d1af85133e1763d41e20414912d9a1058ea72 ]
+
+Commit 9e86b2ad4c11 changed the channel used for HPDET detection
+(headphones vs lineout detection) from being hardcoded to
+ARIZONA_ACCDET_MODE_HPL (HP left channel) to it being configurable
+through arizona_pdata.hpdet_channel the DT/OF parsing added for
+filling arizona_pdata on devicetree platforms ensures that
+arizona_pdata.hpdet_channel gets set to ARIZONA_ACCDET_MODE_HPL
+when not specified in the devicetree-node.
+
+But on ACPI platforms where arizona_pdata is filled by
+arizona_spi_acpi_probe() arizona_pdata.hpdet_channel was not
+getting set, causing it to default to 0 aka ARIZONA_ACCDET_MODE_MIC.
+
+This causes headphones to get misdetected as line-out on some models.
+Fix this by setting hpdet_channel = ARIZONA_ACCDET_MODE_HPL.
+
+Fixes: e933836744a2 ("mfd: arizona: Add support for ACPI enumeration of WM5102 connected over SPI")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20231014205414.59415-1-hdegoede@redhat.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/arizona-spi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
+index aa1d6f94ae532..8d826b58732dc 100644
+--- a/drivers/mfd/arizona-spi.c
++++ b/drivers/mfd/arizona-spi.c
+@@ -118,6 +118,9 @@ static int arizona_spi_acpi_probe(struct arizona *arizona)
+       arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
+       arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
++      /* Use left headphone speaker for HP vs line-out detection */
++      arizona->pdata.hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
++
+       return 0;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/mfd-core-ensure-disabled-devices-are-skipped-without.patch b/queue-5.15/mfd-core-ensure-disabled-devices-are-skipped-without.patch
new file mode 100644 (file)
index 0000000..9e10b51
--- /dev/null
@@ -0,0 +1,77 @@
+From 30b1659c73f46697ed9a223329120b52371a0ba0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 18:39:17 +0200
+Subject: mfd: core: Ensure disabled devices are skipped without aborting
+
+From: Herve Codina <herve.codina@bootlin.com>
+
+[ Upstream commit 7ba7bdef4d14e3722e2842da3b48cbadb73e52d6 ]
+
+The loop searching for a matching device based on its compatible
+string is aborted when a matching disabled device is found.
+This abort prevents to add devices as soon as one disabled device
+is found.
+
+Continue searching for an other device instead of aborting on the
+first disabled one fixes the issue.
+
+Fixes: 22380b65dc70 ("mfd: mfd-core: Ensure disabled devices are ignored without error")
+Signed-off-by: Herve Codina <herve.codina@bootlin.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Link: https://lore.kernel.org/r/528425d6472176bb1d02d79596b51f8c28a551cc.1692376361.git.christophe.leroy@csgroup.eu
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/mfd-core.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
+index 684a011a63968..53ea3fab66a46 100644
+--- a/drivers/mfd/mfd-core.c
++++ b/drivers/mfd/mfd-core.c
+@@ -159,6 +159,7 @@ static int mfd_add_device(struct device *parent, int id,
+       struct platform_device *pdev;
+       struct device_node *np = NULL;
+       struct mfd_of_node_entry *of_entry, *tmp;
++      bool disabled = false;
+       int ret = -ENOMEM;
+       int platform_id;
+       int r;
+@@ -196,11 +197,10 @@ static int mfd_add_device(struct device *parent, int id,
+       if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
+               for_each_child_of_node(parent->of_node, np) {
+                       if (of_device_is_compatible(np, cell->of_compatible)) {
+-                              /* Ignore 'disabled' devices error free */
++                              /* Skip 'disabled' devices */
+                               if (!of_device_is_available(np)) {
+-                                      of_node_put(np);
+-                                      ret = 0;
+-                                      goto fail_alias;
++                                      disabled = true;
++                                      continue;
+                               }
+                               ret = mfd_match_of_node_to_dev(pdev, np, cell);
+@@ -210,10 +210,17 @@ static int mfd_add_device(struct device *parent, int id,
+                               if (ret)
+                                       goto fail_alias;
+-                              break;
++                              goto match;
+                       }
+               }
++              if (disabled) {
++                      /* Ignore 'disabled' devices error free */
++                      ret = 0;
++                      goto fail_alias;
++              }
++
++match:
+               if (!pdev->dev.of_node)
+                       pr_warn("%s: Failed to locate of_node [id: %d]\n",
+                               cell->name, platform_id);
+-- 
+2.42.0
+
diff --git a/queue-5.15/mfd-core-un-constify-mfd_cell.of_reg.patch b/queue-5.15/mfd-core-un-constify-mfd_cell.of_reg.patch
new file mode 100644 (file)
index 0000000..322b737
--- /dev/null
@@ -0,0 +1,40 @@
+From 3823c590ee7fe24654d4847acb932eecd16d7b54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Aug 2023 22:16:11 +0200
+Subject: mfd: core: Un-constify mfd_cell.of_reg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 3c70342f1f0045dc827bb2f02d814ce31e0e0d05 ]
+
+Enable dynamically filling in the whole mfd_cell structure. All other
+fields already allow that.
+
+Fixes: 466a62d7642f ("mfd: core: Make a best effort attempt to match devices with the correct of_nodes")
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/b73fe4bc4bd6ba1af90940a640ed65fe254c0408.1693253717.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mfd/core.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
+index 0bc7cba798a34..b449765b5cac1 100644
+--- a/include/linux/mfd/core.h
++++ b/include/linux/mfd/core.h
+@@ -92,7 +92,7 @@ struct mfd_cell {
+        * (above) when matching OF nodes with devices that have identical
+        * compatible strings
+        */
+-      const u64 of_reg;
++      u64 of_reg;
+       /* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */
+       bool use_of_reg;
+-- 
+2.42.0
+
diff --git a/queue-5.15/mfd-dln2-fix-double-put-in-dln2_probe.patch b/queue-5.15/mfd-dln2-fix-double-put-in-dln2_probe.patch
new file mode 100644 (file)
index 0000000..f207e4e
--- /dev/null
@@ -0,0 +1,37 @@
+From c148b085e07062ac10c46ccfb5b75604a2ad4a93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 10:41:33 +0800
+Subject: mfd: dln2: Fix double put in dln2_probe
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit 759c409bc5fc496cbc22cd0b392d3cbb0c0e23eb ]
+
+The dln2_free() already contains usb_put_dev(). Therefore,
+the redundant usb_put_dev() before dln2_free() may lead to
+a double free.
+
+Fixes: 96da8f148396 ("mfd: dln2: Fix memory leak in dln2_probe()")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Link: https://lore.kernel.org/r/20230925024134.9683-1-dinghao.liu@zju.edu.cn
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/dln2.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
+index fc65f9e25fda8..852129ea07666 100644
+--- a/drivers/mfd/dln2.c
++++ b/drivers/mfd/dln2.c
+@@ -836,7 +836,6 @@ static int dln2_probe(struct usb_interface *interface,
+       dln2_stop_rx_urbs(dln2);
+ out_free:
+-      usb_put_dev(dln2->usb_dev);
+       dln2_free(dln2);
+       return ret;
+-- 
+2.42.0
+
diff --git a/queue-5.15/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch b/queue-5.15/misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch
new file mode 100644 (file)
index 0000000..0b06485
--- /dev/null
@@ -0,0 +1,65 @@
+From 84fae41037c49a5c56fd72682f397b1779fc2158 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 11:50:20 +0800
+Subject: misc: st_core: Do not call kfree_skb() under spin_lock_irqsave()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 4d08c3d12b61022501989f9f071514d2d6f77c47 ]
+
+It is not allowed to call kfree_skb() from hardware interrupt
+context or with hardware interrupts being disabled.
+So replace kfree_skb() with dev_kfree_skb_irq() under
+spin_lock_irqsave(). Compile tested only.
+
+Fixes: 53618cc1e51e ("Staging: sources for ST core")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230823035020.1281892-1-ruanjinjie@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/ti-st/st_core.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
+index 7f6976a9f508b..48e0f8377e659 100644
+--- a/drivers/misc/ti-st/st_core.c
++++ b/drivers/misc/ti-st/st_core.c
+@@ -15,6 +15,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/ti_wilink_st.h>
++#include <linux/netdevice.h>
+ extern void st_kim_recv(void *, const unsigned char *, long);
+ void st_int_recv(void *, const unsigned char *, long);
+@@ -435,7 +436,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
+       case ST_LL_AWAKE_TO_ASLEEP:
+               pr_err("ST LL is illegal state(%ld),"
+                          "purging received skb.", st_ll_getstate(st_gdata));
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+               break;
+       case ST_LL_ASLEEP:
+               skb_queue_tail(&st_gdata->tx_waitq, skb);
+@@ -444,7 +445,7 @@ static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
+       default:
+               pr_err("ST LL is illegal state(%ld),"
+                          "purging received skb.", st_ll_getstate(st_gdata));
+-              kfree_skb(skb);
++              dev_kfree_skb_irq(skb);
+               break;
+       }
+@@ -498,7 +499,7 @@ void st_tx_wakeup(struct st_data_s *st_data)
+                               spin_unlock_irqrestore(&st_data->lock, flags);
+                               break;
+                       }
+-                      kfree_skb(skb);
++                      dev_kfree_skb_irq(skb);
+                       spin_unlock_irqrestore(&st_data->lock, flags);
+               }
+               /* if wake-up is set in another context- restart sending */
+-- 
+2.42.0
+
diff --git a/queue-5.15/mlxsw-use-size_mul-in-call-to-struct_size.patch b/queue-5.15/mlxsw-use-size_mul-in-call-to-struct_size.patch
new file mode 100644 (file)
index 0000000..7bedb39
--- /dev/null
@@ -0,0 +1,39 @@
+From 6f6564f53844662b1fcd6011e3669a2b62b1399f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 13:01:23 -0600
+Subject: mlxsw: Use size_mul() in call to struct_size()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit e22c6ea025013ae447fe269269753ffec763dde5 ]
+
+If, for any reason, the open-coded arithmetic causes a wraparound, the
+protection that `struct_size()` adds against potential integer overflows
+is defeated. Fix this by hardening call to `struct_size()` with `size_mul()`.
+
+Fixes: 2285ec872d9d ("mlxsw: spectrum_acl_bloom_filter: use struct_size() in kzalloc()")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
+index dbd3bebf11eca..2e8b17e3b9358 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
+@@ -251,7 +251,7 @@ mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks)
+        * is 2^ACL_MAX_BF_LOG
+        */
+       bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG);
+-      bf = kzalloc(struct_size(bf, refcnt, bf_bank_size * num_erp_banks),
++      bf = kzalloc(struct_size(bf, refcnt, size_mul(bf_bank_size, num_erp_banks)),
+                    GFP_KERNEL);
+       if (!bf)
+               return ERR_PTR(-ENOMEM);
+-- 
+2.42.0
+
diff --git a/queue-5.15/modpost-fix-tee-module_device_table-built-on-big-end.patch b/queue-5.15/modpost-fix-tee-module_device_table-built-on-big-end.patch
new file mode 100644 (file)
index 0000000..cc8aab9
--- /dev/null
@@ -0,0 +1,71 @@
+From f52c3bfbcbaaaa7d56960215ebc75cafdc1da9da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Oct 2023 02:04:44 +0900
+Subject: modpost: fix tee MODULE_DEVICE_TABLE built on big-endian host
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 7f54e00e5842663c2cea501bbbdfa572c94348a3 ]
+
+When MODULE_DEVICE_TABLE(tee, ) is built on a host with a different
+endianness from the target architecture, it results in an incorrect
+MODULE_ALIAS().
+
+For example, see a case where drivers/char/hw_random/optee-rng.c
+is built as a module for ARM little-endian.
+
+If you build it on a little-endian host, you will get the correct
+MODULE_ALIAS:
+
+    $ grep MODULE_ALIAS drivers/char/hw_random/optee-rng.mod.c
+    MODULE_ALIAS("tee:ab7a617c-b8e7-4d8f-8301-d09b61036b64*");
+
+However, if you build it on a big-endian host, you will get a wrong
+MODULE_ALIAS:
+
+    $ grep MODULE_ALIAS drivers/char/hw_random/optee-rng.mod.c
+    MODULE_ALIAS("tee:646b0361-9bd0-0183-8f4d-e7b87c617aab*");
+
+The same problem also occurs when you enable CONFIG_CPU_BIG_ENDIAN,
+and build it on a little-endian host.
+
+This issue has been unnoticed because the ARM kernel is configured for
+little-endian by default, and most likely built on a little-endian host
+(cross-build on x86 or native-build on ARM).
+
+The uuid field must not be reversed because uuid_t is an array of __u8.
+
+Fixes: 0fc1db9d1059 ("tee: add bus driver framework for TEE based devices")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/mod/file2alias.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 05089ef5cc0ec..23e7102abe0cd 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -1339,13 +1339,13 @@ static int do_typec_entry(const char *filename, void *symval, char *alias)
+ /* Looks like: tee:uuid */
+ static int do_tee_entry(const char *filename, void *symval, char *alias)
+ {
+-      DEF_FIELD(symval, tee_client_device_id, uuid);
++      DEF_FIELD_ADDR(symval, tee_client_device_id, uuid);
+       sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+-              uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4],
+-              uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9],
+-              uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14],
+-              uuid.b[15]);
++              uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4],
++              uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9],
++              uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14],
++              uuid->b[15]);
+       add_wildcard(alias);
+       return 1;
+-- 
+2.42.0
+
diff --git a/queue-5.15/mt76-add-support-for-overriding-the-device-used-for-.patch b/queue-5.15/mt76-add-support-for-overriding-the-device-used-for-.patch
new file mode 100644 (file)
index 0000000..3246cc9
--- /dev/null
@@ -0,0 +1,172 @@
+From 8cca2b28f42b2fb0317d172f3a7bcd7568555193 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jan 2022 13:22:28 +0100
+Subject: mt76: add support for overriding the device used for DMA mapping
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d1ddc536df93ae406ef671deb3218898d3515ea4 ]
+
+WED support requires using non-coherent DMA, whereas the PCI device might
+be configured for coherent DMA.
+The WED driver will take care of changing the PCI HIF coherent IO setting
+on attach.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 317620593349 ("wifi: mt76: mt7603: improve stuck beacon handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c      | 34 +++++++++----------
+ drivers/net/wireless/mediatek/mt76/mac80211.c |  1 +
+ drivers/net/wireless/mediatek/mt76/mt76.h     |  1 +
+ 3 files changed, 19 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index 1344c88729a84..71a04c92117a6 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -20,7 +20,7 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+       if (!txwi)
+               return NULL;
+-      addr = dma_map_single(dev->dev, txwi, dev->drv->txwi_size,
++      addr = dma_map_single(dev->dma_dev, txwi, dev->drv->txwi_size,
+                             DMA_TO_DEVICE);
+       t = (struct mt76_txwi_cache *)(txwi + dev->drv->txwi_size);
+       t->dma_addr = addr;
+@@ -74,7 +74,7 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+       local_bh_disable();
+       while ((t = __mt76_get_txwi(dev)) != NULL) {
+-              dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
++              dma_unmap_single(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
+                                DMA_TO_DEVICE);
+               kfree(mt76_get_txwi_ptr(dev, t));
+       }
+@@ -123,7 +123,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+       q->hw_idx = idx;
+       size = q->ndesc * sizeof(struct mt76_desc);
+-      q->desc = dmam_alloc_coherent(dev->dev, size, &q->desc_dma, GFP_KERNEL);
++      q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
+       if (!q->desc)
+               return -ENOMEM;
+@@ -205,11 +205,11 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+       struct mt76_queue_entry *e = &q->entry[idx];
+       if (!e->skip_buf0)
+-              dma_unmap_single(dev->dev, e->dma_addr[0], e->dma_len[0],
++              dma_unmap_single(dev->dma_dev, e->dma_addr[0], e->dma_len[0],
+                                DMA_TO_DEVICE);
+       if (!e->skip_buf1)
+-              dma_unmap_single(dev->dev, e->dma_addr[1], e->dma_len[1],
++              dma_unmap_single(dev->dma_dev, e->dma_addr[1], e->dma_len[1],
+                                DMA_TO_DEVICE);
+       if (e->txwi == DMA_DUMMY_DATA)
+@@ -290,7 +290,7 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+       if (info)
+               *info = le32_to_cpu(desc->info);
+-      dma_unmap_single(dev->dev, buf_addr, buf_len, DMA_FROM_DEVICE);
++      dma_unmap_single(dev->dma_dev, buf_addr, buf_len, DMA_FROM_DEVICE);
+       e->buf = NULL;
+       return buf;
+@@ -327,9 +327,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+       if (q->queued + 1 >= q->ndesc - 1)
+               goto error;
+-      addr = dma_map_single(dev->dev, skb->data, skb->len,
++      addr = dma_map_single(dev->dma_dev, skb->data, skb->len,
+                             DMA_TO_DEVICE);
+-      if (unlikely(dma_mapping_error(dev->dev, addr)))
++      if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
+               goto error;
+       buf.addr = addr;
+@@ -376,8 +376,8 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+               mt76_insert_hdr_pad(skb);
+       len = skb_headlen(skb);
+-      addr = dma_map_single(dev->dev, skb->data, len, DMA_TO_DEVICE);
+-      if (unlikely(dma_mapping_error(dev->dev, addr)))
++      addr = dma_map_single(dev->dma_dev, skb->data, len, DMA_TO_DEVICE);
++      if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
+               goto free;
+       tx_info.buf[n].addr = t->dma_addr;
+@@ -389,9 +389,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+               if (n == ARRAY_SIZE(tx_info.buf))
+                       goto unmap;
+-              addr = dma_map_single(dev->dev, iter->data, iter->len,
++              addr = dma_map_single(dev->dma_dev, iter->data, iter->len,
+                                     DMA_TO_DEVICE);
+-              if (unlikely(dma_mapping_error(dev->dev, addr)))
++              if (unlikely(dma_mapping_error(dev->dma_dev, addr)))
+                       goto unmap;
+               tx_info.buf[n].addr = addr;
+@@ -404,10 +404,10 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+               goto unmap;
+       }
+-      dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
++      dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
+                               DMA_TO_DEVICE);
+       ret = dev->drv->tx_prepare_skb(dev, txwi, q->qid, wcid, sta, &tx_info);
+-      dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
++      dma_sync_single_for_device(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
+                                  DMA_TO_DEVICE);
+       if (ret < 0)
+               goto unmap;
+@@ -417,7 +417,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ unmap:
+       for (n--; n > 0; n--)
+-              dma_unmap_single(dev->dev, tx_info.buf[n].addr,
++              dma_unmap_single(dev->dma_dev, tx_info.buf[n].addr,
+                                tx_info.buf[n].len, DMA_TO_DEVICE);
+ free:
+@@ -461,8 +461,8 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+               if (!buf)
+                       break;
+-              addr = dma_map_single(dev->dev, buf, len, DMA_FROM_DEVICE);
+-              if (unlikely(dma_mapping_error(dev->dev, addr))) {
++              addr = dma_map_single(dev->dma_dev, buf, len, DMA_FROM_DEVICE);
++              if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
+                       skb_free_frag(buf);
+                       break;
+               }
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index 028519a739fd1..3c7d5abe9cc2a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -428,6 +428,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+       dev->hw = hw;
+       dev->dev = pdev;
+       dev->drv = drv_ops;
++      dev->dma_dev = pdev;
+       phy = &dev->phy;
+       phy->dev = dev;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index eb1fb955b7777..87ae528581bbf 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -660,6 +660,7 @@ struct mt76_dev {
+       const struct mt76_driver_ops *drv;
+       const struct mt76_mcu_ops *mcu_ops;
+       struct device *dev;
++      struct device *dma_dev;
+       struct mt76_mcu mcu;
+-- 
+2.42.0
+
diff --git a/queue-5.15/mt76-dma-use-kzalloc-instead-of-devm_kzalloc-for-txw.patch b/queue-5.15/mt76-dma-use-kzalloc-instead-of-devm_kzalloc-for-txw.patch
new file mode 100644 (file)
index 0000000..3c66d46
--- /dev/null
@@ -0,0 +1,48 @@
+From 14935965b05e31f7016304cf4c0cf3f081eef7ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Mar 2022 21:56:20 +0100
+Subject: mt76: dma: use kzalloc instead of devm_kzalloc for txwi
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 402e01092e79583923579662f244bc538f466f36 ]
+
+dma unmap is already needed for cleanup anyway, so we don't need the extra
+tracking and can save a bit of memory here
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 317620593349 ("wifi: mt76: mt7603: improve stuck beacon handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index 69e0e68757f53..1344c88729a84 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -16,7 +16,7 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+       int size;
+       size = L1_CACHE_ALIGN(dev->drv->txwi_size + sizeof(*t));
+-      txwi = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
++      txwi = kzalloc(size, GFP_ATOMIC);
+       if (!txwi)
+               return NULL;
+@@ -73,9 +73,11 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+       struct mt76_txwi_cache *t;
+       local_bh_disable();
+-      while ((t = __mt76_get_txwi(dev)) != NULL)
++      while ((t = __mt76_get_txwi(dev)) != NULL) {
+               dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
+                                DMA_TO_DEVICE);
++              kfree(mt76_get_txwi_ptr(dev, t));
++      }
+       local_bh_enable();
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/mt76-pass-original-queue-id-from-__mt76_tx_queue_skb.patch b/queue-5.15/mt76-pass-original-queue-id-from-__mt76_tx_queue_skb.patch
new file mode 100644 (file)
index 0000000..5d487d9
--- /dev/null
@@ -0,0 +1,181 @@
+From e8400b54904e13be73dc574a8a89d7ba3ef46af6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 17:52:24 +0200
+Subject: mt76: pass original queue id from __mt76_tx_queue_skb to the driver
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d08295f5be8e63e64f9e664572f1b582ede7958b ]
+
+MT7615 and newer map multiple software tx queues to the hardware id
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Stable-dep-of: 317620593349 ("wifi: mt76: mt7603: improve stuck beacon handling")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c           | 6 +++---
+ drivers/net/wireless/mediatek/mt76/mt76.h          | 4 ++--
+ drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 6 +++---
+ drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c  | 3 ++-
+ drivers/net/wireless/mediatek/mt76/sdio.c          | 6 +++---
+ drivers/net/wireless/mediatek/mt76/testmode.c      | 4 ++--
+ drivers/net/wireless/mediatek/mt76/tx.c            | 2 +-
+ drivers/net/wireless/mediatek/mt76/usb.c           | 6 +++---
+ 8 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
+index 71a04c92117a6..f225a34e21861 100644
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -349,8 +349,8 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ static int
+ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+-                    struct sk_buff *skb, struct mt76_wcid *wcid,
+-                    struct ieee80211_sta *sta)
++                    enum mt76_txq_id qid, struct sk_buff *skb,
++                    struct mt76_wcid *wcid, struct ieee80211_sta *sta)
+ {
+       struct ieee80211_tx_status status = {
+               .sta = sta,
+@@ -406,7 +406,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+       dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
+                               DMA_TO_DEVICE);
+-      ret = dev->drv->tx_prepare_skb(dev, txwi, q->qid, wcid, sta, &tx_info);
++      ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta, &tx_info);
+       dma_sync_single_for_device(dev->dma_dev, t->dma_addr, dev->drv->txwi_size,
+                                  DMA_TO_DEVICE);
+       if (ret < 0)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 87ae528581bbf..27f04fb2796d7 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -195,8 +195,8 @@ struct mt76_queue_ops {
+                    u32 ring_base);
+       int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q,
+-                          struct sk_buff *skb, struct mt76_wcid *wcid,
+-                          struct ieee80211_sta *sta);
++                          enum mt76_txq_id qid, struct sk_buff *skb,
++                          struct mt76_wcid *wcid, struct ieee80211_sta *sta);
+       int (*tx_queue_skb_raw)(struct mt76_dev *dev, struct mt76_queue *q,
+                               struct sk_buff *skb, u32 tx_info);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+index 5d4522f440b74..e35e0a68c6e48 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+@@ -24,8 +24,8 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+       if (!skb)
+               return;
+-      mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON], skb,
+-                        &mvif->sta.wcid, NULL);
++      mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON],
++                        MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
+       spin_lock_bh(&dev->ps_lock);
+       mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY |
+@@ -123,7 +123,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
+               struct ieee80211_vif *vif = info->control.vif;
+               struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
+-              mt76_tx_queue_skb(dev, q, skb, &mvif->sta.wcid, NULL);
++              mt76_tx_queue_skb(dev, q, MT_TXQ_CAB, skb, &mvif->sta.wcid, NULL);
+       }
+       mt76_queue_kick(dev, q);
+       spin_unlock_bh(&q->lock);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+index b50084bbe83de..6ba3a7975e1bf 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+@@ -59,7 +59,8 @@ static void mt76x02_pre_tbtt_tasklet(struct tasklet_struct *t)
+               struct ieee80211_vif *vif = info->control.vif;
+               struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+-              mt76_tx_queue_skb(dev, q, skb, &mvif->group_wcid, NULL);
++              mt76_tx_queue_skb(dev, q, MT_TXQ_PSD, skb, &mvif->group_wcid,
++                                NULL);
+       }
+       spin_unlock_bh(&q->lock);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
+index 9e639d0b9c631..4964f19558be2 100644
+--- a/drivers/net/wireless/mediatek/mt76/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/sdio.c
+@@ -243,8 +243,8 @@ static void mt76s_tx_status_data(struct work_struct *work)
+ static int
+ mt76s_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+-                 struct sk_buff *skb, struct mt76_wcid *wcid,
+-                 struct ieee80211_sta *sta)
++                 enum mt76_txq_id qid, struct sk_buff *skb,
++                 struct mt76_wcid *wcid, struct ieee80211_sta *sta)
+ {
+       struct mt76_tx_info tx_info = {
+               .skb = skb,
+@@ -256,7 +256,7 @@ mt76s_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+               return -ENOSPC;
+       skb->prev = skb->next = NULL;
+-      err = dev->drv->tx_prepare_skb(dev, NULL, q->qid, wcid, sta, &tx_info);
++      err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
+       if (err < 0)
+               return err;
+diff --git a/drivers/net/wireless/mediatek/mt76/testmode.c b/drivers/net/wireless/mediatek/mt76/testmode.c
+index 0109433e8c2fe..12b13946fba18 100644
+--- a/drivers/net/wireless/mediatek/mt76/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/testmode.c
+@@ -49,8 +49,8 @@ void mt76_testmode_tx_pending(struct mt76_phy *phy)
+              q->queued < q->ndesc / 2) {
+               int ret;
+-              ret = dev->queue_ops->tx_queue_skb(dev, q, skb_get(skb), wcid,
+-                                                 NULL);
++              ret = dev->queue_ops->tx_queue_skb(dev, q, qid, skb_get(skb),
++                                                 wcid, NULL);
+               if (ret < 0)
+                       break;
+diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
+index 7d126634547f1..134a735a06329 100644
+--- a/drivers/net/wireless/mediatek/mt76/tx.c
++++ b/drivers/net/wireless/mediatek/mt76/tx.c
+@@ -259,7 +259,7 @@ __mt76_tx_queue_skb(struct mt76_phy *phy, int qid, struct sk_buff *skb,
+       int idx;
+       non_aql = !info->tx_time_est;
+-      idx = dev->queue_ops->tx_queue_skb(dev, q, skb, wcid, sta);
++      idx = dev->queue_ops->tx_queue_skb(dev, q, qid, skb, wcid, sta);
+       if (idx < 0 || !sta)
+               return idx;
+diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
+index b47343e321b81..392632c3f1b1d 100644
+--- a/drivers/net/wireless/mediatek/mt76/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/usb.c
+@@ -901,8 +901,8 @@ mt76u_tx_setup_buffers(struct mt76_dev *dev, struct sk_buff *skb,
+ static int
+ mt76u_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+-                 struct sk_buff *skb, struct mt76_wcid *wcid,
+-                 struct ieee80211_sta *sta)
++                 enum mt76_txq_id qid, struct sk_buff *skb,
++                 struct mt76_wcid *wcid, struct ieee80211_sta *sta)
+ {
+       struct mt76_tx_info tx_info = {
+               .skb = skb,
+@@ -914,7 +914,7 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+               return -ENOSPC;
+       skb->prev = skb->next = NULL;
+-      err = dev->drv->tx_prepare_skb(dev, NULL, q->qid, wcid, sta, &tx_info);
++      err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
+       if (err < 0)
+               return err;
+-- 
+2.42.0
+
diff --git a/queue-5.15/nd_btt-make-btt-lanes-preemptible.patch b/queue-5.15/nd_btt-make-btt-lanes-preemptible.patch
new file mode 100644 (file)
index 0000000..63be755
--- /dev/null
@@ -0,0 +1,94 @@
+From aba9f0451f31b86461de4108d4778361dcfce011 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Sep 2023 07:37:12 +0200
+Subject: nd_btt: Make BTT lanes preemptible
+
+From: Tomas Glozar <tglozar@redhat.com>
+
+[ Upstream commit 36c75ce3bd299878fd9b238e9803d3817ddafbf3 ]
+
+nd_region_acquire_lane uses get_cpu, which disables preemption. This is
+an issue on PREEMPT_RT kernels, since btt_write_pg and also
+nd_region_acquire_lane itself take a spin lock, resulting in BUG:
+sleeping function called from invalid context.
+
+Fix the issue by replacing get_cpu with smp_process_id and
+migrate_disable when needed. This makes BTT operations preemptible, thus
+permitting the use of spin_lock.
+
+BUG example occurring when running ndctl tests on PREEMPT_RT kernel:
+
+BUG: sleeping function called from invalid context at
+kernel/locking/spinlock_rt.c:48
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 4903, name:
+libndctl
+preempt_count: 1, expected: 0
+RCU nest depth: 0, expected: 0
+Preemption disabled at:
+[<ffffffffc1313db5>] nd_region_acquire_lane+0x15/0x90 [libnvdimm]
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x8e/0xb0
+ __might_resched+0x19b/0x250
+ rt_spin_lock+0x4c/0x100
+ ? btt_write_pg+0x2d7/0x500 [nd_btt]
+ btt_write_pg+0x2d7/0x500 [nd_btt]
+ ? local_clock_noinstr+0x9/0xc0
+ btt_submit_bio+0x16d/0x270 [nd_btt]
+ __submit_bio+0x48/0x80
+ __submit_bio_noacct+0x7e/0x1e0
+ submit_bio_wait+0x58/0xb0
+ __blkdev_direct_IO_simple+0x107/0x240
+ ? inode_set_ctime_current+0x51/0x110
+ ? __pfx_submit_bio_wait_endio+0x10/0x10
+ blkdev_write_iter+0x1d8/0x290
+ vfs_write+0x237/0x330
+ ...
+ </TASK>
+
+Fixes: 5212e11fde4d ("nd_btt: atomic sector updates")
+Signed-off-by: Tomas Glozar <tglozar@redhat.com>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Ira Weiny <ira.weiny@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvdimm/region_devs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
+index 70ad891a76bae..c2d3343b5596b 100644
+--- a/drivers/nvdimm/region_devs.c
++++ b/drivers/nvdimm/region_devs.c
+@@ -966,7 +966,8 @@ unsigned int nd_region_acquire_lane(struct nd_region *nd_region)
+ {
+       unsigned int cpu, lane;
+-      cpu = get_cpu();
++      migrate_disable();
++      cpu = smp_processor_id();
+       if (nd_region->num_lanes < nr_cpu_ids) {
+               struct nd_percpu_lane *ndl_lock, *ndl_count;
+@@ -985,16 +986,15 @@ EXPORT_SYMBOL(nd_region_acquire_lane);
+ void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane)
+ {
+       if (nd_region->num_lanes < nr_cpu_ids) {
+-              unsigned int cpu = get_cpu();
++              unsigned int cpu = smp_processor_id();
+               struct nd_percpu_lane *ndl_lock, *ndl_count;
+               ndl_count = per_cpu_ptr(nd_region->lane, cpu);
+               ndl_lock = per_cpu_ptr(nd_region->lane, lane);
+               if (--ndl_count->count == 0)
+                       spin_unlock(&ndl_lock->lock);
+-              put_cpu();
+       }
+-      put_cpu();
++      migrate_enable();
+ }
+ EXPORT_SYMBOL(nd_region_release_lane);
+-- 
+2.42.0
+
diff --git a/queue-5.15/net-add-dev_stats_read-helper.patch b/queue-5.15/net-add-dev_stats_read-helper.patch
new file mode 100644 (file)
index 0000000..4b73913
--- /dev/null
@@ -0,0 +1,55 @@
+From c3efe8573fe7882a19dd660a3ee05cf9f8bf7ead Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 08:52:16 +0000
+Subject: net: add DEV_STATS_READ() helper
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0b068c714ca9479d2783cc333fff5bc2d4a6d45c ]
+
+Companion of DEV_STATS_INC() & DEV_STATS_ADD().
+
+This is going to be used in the series.
+
+Use it in macsec_get_stats64().
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: ff672b9ffeb3 ("ipvlan: properly track tx_errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c      | 6 +++---
+ include/linux/netdevice.h | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 07c822c301185..ab134fe1fda62 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -3681,9 +3681,9 @@ static void macsec_get_stats64(struct net_device *dev,
+       dev_fetch_sw_netstats(s, dev->tstats);
+-      s->rx_dropped = atomic_long_read(&dev->stats.__rx_dropped);
+-      s->tx_dropped = atomic_long_read(&dev->stats.__tx_dropped);
+-      s->rx_errors = atomic_long_read(&dev->stats.__rx_errors);
++      s->rx_dropped = DEV_STATS_READ(dev, rx_dropped);
++      s->tx_dropped = DEV_STATS_READ(dev, tx_dropped);
++      s->rx_errors = DEV_STATS_READ(dev, rx_errors);
+ }
+ static int macsec_get_iflink(const struct net_device *dev)
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 132f4344fee9f..829ebde5d50d5 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -5499,5 +5499,6 @@ extern struct net_device *blackhole_netdev;
+ #define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD)
+ #define DEV_STATS_ADD(DEV, FIELD, VAL)        \
+               atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
++#define DEV_STATS_READ(DEV, FIELD) atomic_long_read(&(DEV)->stats.__##FIELD)
+ #endif        /* _LINUX_NETDEVICE_H */
+-- 
+2.42.0
+
diff --git a/queue-5.15/net-spider_net-use-size_add-in-call-to-struct_size.patch b/queue-5.15/net-spider_net-use-size_add-in-call-to-struct_size.patch
new file mode 100644 (file)
index 0000000..0734626
--- /dev/null
@@ -0,0 +1,40 @@
+From e6524459e9454e9e55647f2e238c565fa1011439 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 13:25:36 -0600
+Subject: net: spider_net: Use size_add() in call to struct_size()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 0201409079b975e46cc40e8bdff4bd61329ee10f ]
+
+If, for any reason, the open-coded arithmetic causes a wraparound,
+the protection that `struct_size()` adds against potential integer
+overflows is defeated. Fix this by hardening call to `struct_size()`
+with `size_add()`.
+
+Fixes: 3f1071ec39f7 ("net: spider_net: Use struct_size() helper")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Geoff Levand <geoff@infradead.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/toshiba/spider_net.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/toshiba/spider_net.c b/drivers/net/ethernet/toshiba/spider_net.c
+index 66d4e024d11e9..f62fbb1087a9e 100644
+--- a/drivers/net/ethernet/toshiba/spider_net.c
++++ b/drivers/net/ethernet/toshiba/spider_net.c
+@@ -2332,7 +2332,7 @@ spider_net_alloc_card(void)
+       struct spider_net_card *card;
+       netdev = alloc_etherdev(struct_size(card, darray,
+-                                          tx_descriptors + rx_descriptors));
++                                          size_add(tx_descriptors, rx_descriptors)));
+       if (!netdev)
+               return NULL;
+-- 
+2.42.0
+
diff --git a/queue-5.15/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch b/queue-5.15/netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch
new file mode 100644 (file)
index 0000000..f260a64
--- /dev/null
@@ -0,0 +1,38 @@
+From e3c1064486cfb437c7d1170cb69679609efa632e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Sep 2023 21:19:19 +0200
+Subject: netfilter: nf_tables: Drop pointless memset when dumping rules
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 30fa41a0f6df4c85790cc6499ddc4a926a113bfa ]
+
+None of the dump callbacks uses netlink_callback::args beyond the first
+element, no need to zero the data.
+
+Fixes: 96518518cc41 ("netfilter: add nftables")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8a4cd1c16e0e4..8f12e83280cbd 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3184,10 +3184,6 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
+                       goto cont_skip;
+               if (*idx < s_idx)
+                       goto cont;
+-              if (*idx > s_idx) {
+-                      memset(&cb->args[1], 0,
+-                                      sizeof(cb->args) - sizeof(cb->args[0]));
+-              }
+               if (prule)
+                       handle = prule->handle;
+               else
+-- 
+2.42.0
+
diff --git a/queue-5.15/padata-fix-refcnt-handling-in-padata_free_shell.patch b/queue-5.15/padata-fix-refcnt-handling-in-padata_free_shell.patch
new file mode 100644 (file)
index 0000000..bed48be
--- /dev/null
@@ -0,0 +1,110 @@
+From f42a1130daa9f11fd1dd673b35f78826a13404e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Oct 2023 09:15:21 +0800
+Subject: padata: Fix refcnt handling in padata_free_shell()
+
+From: WangJinchao <wangjinchao@xfusion.com>
+
+[ Upstream commit 7ddc21e317b360c3444de3023bcc83b85fabae2f ]
+
+In a high-load arm64 environment, the pcrypt_aead01 test in LTP can lead
+to system UAF (Use-After-Free) issues. Due to the lengthy analysis of
+the pcrypt_aead01 function call, I'll describe the problem scenario
+using a simplified model:
+
+Suppose there's a user of padata named `user_function` that adheres to
+the padata requirement of calling `padata_free_shell` after `serial()`
+has been invoked, as demonstrated in the following code:
+
+```c
+struct request {
+    struct padata_priv padata;
+    struct completion *done;
+};
+
+void parallel(struct padata_priv *padata) {
+    do_something();
+}
+
+void serial(struct padata_priv *padata) {
+    struct request *request = container_of(padata,
+                               struct request,
+                               padata);
+    complete(request->done);
+}
+
+void user_function() {
+    DECLARE_COMPLETION(done)
+    padata->parallel = parallel;
+    padata->serial = serial;
+    padata_do_parallel();
+    wait_for_completion(&done);
+    padata_free_shell();
+}
+```
+
+In the corresponding padata.c file, there's the following code:
+
+```c
+static void padata_serial_worker(struct work_struct *serial_work) {
+    ...
+    cnt = 0;
+
+    while (!list_empty(&local_list)) {
+        ...
+        padata->serial(padata);
+        cnt++;
+    }
+
+    local_bh_enable();
+
+    if (refcount_sub_and_test(cnt, &pd->refcnt))
+        padata_free_pd(pd);
+}
+```
+
+Because of the high system load and the accumulation of unexecuted
+softirq at this moment, `local_bh_enable()` in padata takes longer
+to execute than usual. Subsequently, when accessing `pd->refcnt`,
+`pd` has already been released by `padata_free_shell()`, resulting
+in a UAF issue with `pd->refcnt`.
+
+The fix is straightforward: add `refcount_dec_and_test` before calling
+`padata_free_pd` in `padata_free_shell`.
+
+Fixes: 07928d9bfc81 ("padata: Remove broken queue flushing")
+
+Signed-off-by: WangJinchao <wangjinchao@xfusion.com>
+Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/padata.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index c17f772cc315a..c6025a48fb49e 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -1094,12 +1094,16 @@ EXPORT_SYMBOL(padata_alloc_shell);
+  */
+ void padata_free_shell(struct padata_shell *ps)
+ {
++      struct parallel_data *pd;
++
+       if (!ps)
+               return;
+       mutex_lock(&ps->pinst->lock);
+       list_del(&ps->list);
+-      padata_free_pd(rcu_dereference_protected(ps->pd, 1));
++      pd = rcu_dereference_protected(ps->pd, 1);
++      if (refcount_dec_and_test(&pd->refcnt))
++              padata_free_pd(pd);
+       mutex_unlock(&ps->pinst->lock);
+       kfree(ps);
+-- 
+2.42.0
+
diff --git a/queue-5.15/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch b/queue-5.15/pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch
new file mode 100644 (file)
index 0000000..86e059b
--- /dev/null
@@ -0,0 +1,43 @@
+From bfd42c01aa52bd286c1320a5920f6bacc06220ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:25:41 +0800
+Subject: pcmcia: cs: fix possible hung task and memory leak pccardd()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e3ea1b4847e49234e691c0d66bf030bd65bb7f2b ]
+
+If device_register() returns error in pccardd(), it leads two issues:
+
+1. The socket_released has never been completed, it will block
+   pcmcia_unregister_socket(), because of waiting for completion
+   of socket_released.
+2. The device name allocated by dev_set_name() is leaked.
+
+Fix this two issues by calling put_device() when device_register() fails.
+socket_released can be completed in pcmcia_release_socket(), the name can
+be freed in kobject_cleanup().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pcmcia/cs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
+index f70197154a362..820cce7c8b400 100644
+--- a/drivers/pcmcia/cs.c
++++ b/drivers/pcmcia/cs.c
+@@ -605,6 +605,7 @@ static int pccardd(void *__skt)
+               dev_warn(&skt->dev, "PCMCIA: unable to register socket\n");
+               skt->thread = NULL;
+               complete(&skt->thread_done);
++              put_device(&skt->dev);
+               return 0;
+       }
+       ret = pccard_sysfs_add_socket(&skt->dev);
+-- 
+2.42.0
+
diff --git a/queue-5.15/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch b/queue-5.15/pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch
new file mode 100644 (file)
index 0000000..e9cac7e
--- /dev/null
@@ -0,0 +1,53 @@
+From 28725e8ddb54255485eb63173bc75e94a35b05b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:29:24 +0800
+Subject: pcmcia: ds: fix possible name leak in error path in
+ pcmcia_device_add()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 99e1241049a92dd3e9a90a0f91e32ce390133278 ]
+
+Afer commit 1fa5ae857bb1 ("driver core: get rid of struct device's
+bus_id string array"), the name of device is allocated dynamically.
+Therefore, it needs to be freed, which is done by the driver core for
+us once all references to the device are gone. Therefore, move the
+dev_set_name() call immediately before the call device_register(), which
+either succeeds (then the freeing will be done upon subsequent remvoal),
+or puts the reference in the error call. Also, it is not unusual that the
+return value of dev_set_name is not checked.
+
+Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+[linux@dominikbrodowski.net: simplification, commit message modified]
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pcmcia/ds.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
+index bdbd38fed94d2..f8baf178ef3c6 100644
+--- a/drivers/pcmcia/ds.c
++++ b/drivers/pcmcia/ds.c
+@@ -513,9 +513,6 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+       /* by default don't allow DMA */
+       p_dev->dma_mask = 0;
+       p_dev->dev.dma_mask = &p_dev->dma_mask;
+-      dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no);
+-      if (!dev_name(&p_dev->dev))
+-              goto err_free;
+       p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
+       if (!p_dev->devname)
+               goto err_free;
+@@ -573,6 +570,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+       pcmcia_device_query(p_dev);
++      dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no);
+       if (device_register(&p_dev->dev)) {
+               mutex_lock(&s->ops_mutex);
+               list_del(&p_dev->socket_device_list);
+-- 
+2.42.0
+
diff --git a/queue-5.15/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch b/queue-5.15/pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch
new file mode 100644 (file)
index 0000000..68b582c
--- /dev/null
@@ -0,0 +1,49 @@
+From 13d67d54d1de77a8f35da3948aaa3d9f3a57db95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Nov 2022 17:29:23 +0800
+Subject: pcmcia: ds: fix refcount leak in pcmcia_device_add()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 402ab979b29126068e0b596b641422ff7490214c ]
+
+As the comment of device_register() says, it should use put_device()
+to give up the reference in the error path. Then, insofar resources
+will be freed in pcmcia_release_dev(), the error path is no longer
+needed. In particular, this means that the (previously missing) dropping
+of the reference to &p_dev->function_config->ref is now handled by
+pcmcia_release_dev().
+
+Fixes: 360b65b95bae ("[PATCH] pcmcia: make config_t independent, add reference counting")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+[linux@dominikbrodowski.net: simplification, commit message rewrite]
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pcmcia/ds.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
+index 5bd1b80424e72..bdbd38fed94d2 100644
+--- a/drivers/pcmcia/ds.c
++++ b/drivers/pcmcia/ds.c
+@@ -573,8 +573,14 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
+       pcmcia_device_query(p_dev);
+-      if (device_register(&p_dev->dev))
+-              goto err_unreg;
++      if (device_register(&p_dev->dev)) {
++              mutex_lock(&s->ops_mutex);
++              list_del(&p_dev->socket_device_list);
++              s->device_count--;
++              mutex_unlock(&s->ops_mutex);
++              put_device(&p_dev->dev);
++              return NULL;
++      }
+       return p_dev;
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-evlist-add-evlist__add_dummy_on_all_cpus.patch b/queue-5.15/perf-evlist-add-evlist__add_dummy_on_all_cpus.patch
new file mode 100644 (file)
index 0000000..4839063
--- /dev/null
@@ -0,0 +1,106 @@
+From a4455e5be294c717c5f1b67c1ef9471f3229e41f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:54:26 +0300
+Subject: perf evlist: Add evlist__add_dummy_on_all_cpus()
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 126d68fdcabed8c2ca5ffaba785add93ef722da8 ]
+
+Add evlist__add_dummy_on_all_cpus() to enable creating a system-wide dummy
+event that sets up the system-wide maps before map propagation.
+
+For convenience, add evlist__add_aux_dummy() so that the logic can be used
+whether or not the event needs to be system-wide.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Link: https://lore.kernel.org/r/20220524075436.29144-6-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: f9cdeb58a9cf ("perf evlist: Avoid frequency mode for the dummy event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evlist.c | 45 ++++++++++++++++++++++++++++++++++++++++
+ tools/perf/util/evlist.h |  5 +++++
+ 2 files changed, 50 insertions(+)
+
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index 39d294f6c3218..a75cdcf381308 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -258,6 +258,51 @@ int evlist__add_dummy(struct evlist *evlist)
+       return 0;
+ }
++static void evlist__add_on_all_cpus(struct evlist *evlist, struct evsel *evsel)
++{
++      evsel->core.system_wide = true;
++
++      /*
++       * All CPUs.
++       *
++       * Note perf_event_open() does not accept CPUs that are not online, so
++       * in fact this CPU list will include only all online CPUs.
++       */
++      perf_cpu_map__put(evsel->core.own_cpus);
++      evsel->core.own_cpus = perf_cpu_map__new(NULL);
++      perf_cpu_map__put(evsel->core.cpus);
++      evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus);
++
++      /* No threads */
++      perf_thread_map__put(evsel->core.threads);
++      evsel->core.threads = perf_thread_map__new_dummy();
++
++      evlist__add(evlist, evsel);
++}
++
++struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide)
++{
++      struct evsel *evsel = evlist__dummy_event(evlist);
++
++      if (!evsel)
++              return NULL;
++
++      evsel->core.attr.exclude_kernel = 1;
++      evsel->core.attr.exclude_guest = 1;
++      evsel->core.attr.exclude_hv = 1;
++      evsel->core.attr.freq = 0;
++      evsel->core.attr.sample_period = 1;
++      evsel->no_aux_samples = true;
++      evsel->name = strdup("dummy:u");
++
++      if (system_wide)
++              evlist__add_on_all_cpus(evlist, evsel);
++      else
++              evlist__add(evlist, evsel);
++
++      return evsel;
++}
++
+ static int evlist__add_attrs(struct evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs)
+ {
+       struct evsel *evsel, *n;
+diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
+index ec177f783ee67..decf5c944adba 100644
+--- a/tools/perf/util/evlist.h
++++ b/tools/perf/util/evlist.h
+@@ -112,6 +112,11 @@ int __evlist__add_default_attrs(struct evlist *evlist,
+ int arch_evlist__add_default_attrs(struct evlist *evlist);
+ int evlist__add_dummy(struct evlist *evlist);
++struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide);
++static inline struct evsel *evlist__add_dummy_on_all_cpus(struct evlist *evlist)
++{
++      return evlist__add_aux_dummy(evlist, true);
++}
+ int evlist__add_sb_event(struct evlist *evlist, struct perf_event_attr *attr,
+                        evsel__sb_cb_t cb, void *data);
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-evlist-avoid-frequency-mode-for-the-dummy-event.patch b/queue-5.15/perf-evlist-avoid-frequency-mode-for-the-dummy-event.patch
new file mode 100644 (file)
index 0000000..4c3b3c5
--- /dev/null
@@ -0,0 +1,86 @@
+From dce002fd193111afa04774420e3798b77c54e543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 20:56:40 -0700
+Subject: perf evlist: Avoid frequency mode for the dummy event
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit f9cdeb58a9cf46c09b56f5f661ea8da24b6458c3 ]
+
+Dummy events are created with an attribute where the period and freq
+are zero. evsel__config will then see the uninitialized values and
+initialize them in evsel__default_freq_period. As fequency mode is
+used by default the dummy event would be set to use frequency
+mode. However, this has no effect on the dummy event but does cause
+unnecessary timers/interrupts. Avoid this overhead by setting the
+period to 1 for dummy events.
+
+evlist__add_aux_dummy calls evlist__add_dummy then sets freq=0 and
+period=1. This isn't necessary after this change and so the setting is
+removed.
+
+From Stephane:
+
+The dummy event is not counting anything. It is used to collect mmap
+records and avoid a race condition during the synthesize mmap phase of
+perf record. As such, it should not cause any overhead during active
+profiling. Yet, it did. Because of a bug the dummy event was
+programmed as a sampling event in frequency mode. Events in that mode
+incur more kernel overheads because on timer tick, the kernel has to
+look at the number of samples for each event and potentially adjust
+the sampling period to achieve the desired frequency. The dummy event
+was therefore adding a frequency event to task and ctx contexts we may
+otherwise not have any, e.g.,
+
+  perf record -a -e cpu/event=0x3c,period=10000000/.
+
+On each timer tick the perf_adjust_freq_unthr_context() is invoked and
+if ctx->nr_freq is non-zero, then the kernel will loop over ALL the
+events of the context looking for frequency mode ones. In doing, so it
+locks the context, and enable/disable the PMU of each hw event. If all
+the events of the context are in period mode, the kernel will have to
+traverse the list for nothing incurring overhead. The overhead is
+multiplied by a very large factor when this happens in a guest kernel.
+There is no need for the dummy event to be in frequency mode, it does
+not count anything and therefore should not cause extra overhead for
+no reason.
+
+Fixes: 5bae0250237f ("perf evlist: Introduce perf_evlist__new_dummy constructor")
+Reported-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20230916035640.1074422-1-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evlist.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index 63ef40543a9fe..9d0f2feb25671 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -248,6 +248,9 @@ int evlist__add_dummy(struct evlist *evlist)
+               .type   = PERF_TYPE_SOFTWARE,
+               .config = PERF_COUNT_SW_DUMMY,
+               .size   = sizeof(attr), /* to capture ABI version */
++              /* Avoid frequency mode for dummy events to avoid associated timers. */
++              .freq = 0,
++              .sample_period = 1,
+       };
+       struct evsel *evsel = evsel__new_idx(&attr, evlist->core.nr_entries);
+@@ -268,8 +271,6 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide)
+       evsel->core.attr.exclude_kernel = 1;
+       evsel->core.attr.exclude_guest = 1;
+       evsel->core.attr.exclude_hv = 1;
+-      evsel->core.attr.freq = 0;
+-      evsel->core.attr.sample_period = 1;
+       evsel->core.system_wide = system_wide;
+       evsel->no_aux_samples = true;
+       evsel->name = strdup("dummy:u");
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch b/queue-5.15/perf-hisi-fix-use-after-free-when-register-pmu-fails.patch
new file mode 100644 (file)
index 0000000..0122474
--- /dev/null
@@ -0,0 +1,62 @@
+From 9a4221bcf19da839b0e44457b8ea21cdc9352b5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 19:36:30 +0800
+Subject: perf: hisi: Fix use-after-free when register pmu fails
+
+From: Junhao He <hejunhao3@huawei.com>
+
+[ Upstream commit b805cafc604bfdb671fae7347a57f51154afa735 ]
+
+When we fail to register the uncore pmu, the pmu context may not been
+allocated. The error handing will call cpuhp_state_remove_instance()
+to call uncore pmu offline callback, which migrate the pmu context.
+Since that's liable to lead to some kind of use-after-free.
+
+Use cpuhp_state_remove_instance_nocalls() instead of
+cpuhp_state_remove_instance() so that the notifiers don't execute after
+the PMU device has been failed to register.
+
+Fixes: a0ab25cd82ee ("drivers/perf: hisi: Add support for HiSilicon PA PMU driver")
+FIxes: 3bf30882c3c7 ("drivers/perf: hisi: Add support for HiSilicon SLLC PMU driver")
+Signed-off-by: Junhao He <hejunhao3@huawei.com>
+Link: https://lore.kernel.org/r/20231024113630.13472-1-hejunhao3@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/hisilicon/hisi_uncore_pa_pmu.c   | 4 ++--
+ drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+index 83264ec0a9573..7b096f1dc9eb1 100644
+--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
++++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
+@@ -434,8 +434,8 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
+       ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
+       if (ret) {
+               dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
+-              cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
+-                                          &pa_pmu->node);
++              cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
++                                                  &pa_pmu->node);
+               return ret;
+       }
+diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+index 6aedc303ff56a..f3cd00fc9bbe6 100644
+--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
++++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
+@@ -463,8 +463,8 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
+       ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
+       if (ret) {
+               dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
+-              cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
+-                                          &sllc_pmu->node);
++              cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
++                                                  &sllc_pmu->node);
+               return ret;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-hist-add-missing-puts-to-hist__account_cycles.patch b/queue-5.15/perf-hist-add-missing-puts-to-hist__account_cycles.patch
new file mode 100644 (file)
index 0000000..902429b
--- /dev/null
@@ -0,0 +1,81 @@
+From 97b7b4274c2ef00e21401c010ce1366d7038ef1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 15:23:08 -0700
+Subject: perf hist: Add missing puts to hist__account_cycles
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit c1149037f65bcf0334886180ebe3d5efcf214912 ]
+
+Caught using reference count checking on perf top with
+"--call-graph=lbr". After this no memory leaks were detected.
+
+Fixes: 57849998e2cd ("perf report: Add processing for cycle histograms")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: German Gomez <german.gomez@arm.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Nick Terrell <terrelln@fb.com>
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: Changbin Du <changbin.du@huawei.com>
+Cc: liuwenyu <liuwenyu7@huawei.com>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Miguel Ojeda <ojeda@kernel.org>
+Cc: Song Liu <song@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Yanteng Si <siyanteng@loongson.cn>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Link: https://lore.kernel.org/r/20231024222353.3024098-6-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/hist.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index b776465e04ef3..e67935b1e3060 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -2635,8 +2635,6 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
+       /* If we have branch cycles always annotate them. */
+       if (bs && bs->nr && entries[0].flags.cycles) {
+-              int i;
+-
+               bi = sample__resolve_bstack(sample, al);
+               if (bi) {
+                       struct addr_map_symbol *prev = NULL;
+@@ -2651,7 +2649,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
+                        * Note that perf stores branches reversed from
+                        * program order!
+                        */
+-                      for (i = bs->nr - 1; i >= 0; i--) {
++                      for (int i = bs->nr - 1; i >= 0; i--) {
+                               addr_map_symbol__account_cycles(&bi[i].from,
+                                       nonany_branch_mode ? NULL : prev,
+                                       bi[i].flags.cycles);
+@@ -2660,6 +2658,12 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
+                               if (total_cycles)
+                                       *total_cycles += bi[i].flags.cycles;
+                       }
++                      for (unsigned int i = 0; i < bs->nr; i++) {
++                              map__put(bi[i].to.ms.map);
++                              maps__put(bi[i].to.ms.maps);
++                              map__put(bi[i].from.ms.map);
++                              maps__put(bi[i].from.ms.maps);
++                      }
+                       free(bi);
+               }
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch b/queue-5.15/perf-machine-avoid-out-of-bounds-lbr-memory-read.patch
new file mode 100644 (file)
index 0000000..a132c49
--- /dev/null
@@ -0,0 +1,80 @@
+From 94ef4f4326d44d2915eaacff0e2d3e0f557fafa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 15:23:05 -0700
+Subject: perf machine: Avoid out of bounds LBR memory read
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit ab8ce150781d326c6bfbe1e09f175ffde1186f80 ]
+
+Running perf top with address sanitizer and "--call-graph=lbr" fails
+due to reading sample 0 when no samples exist. Add a guard to prevent
+this.
+
+Fixes: e2b23483eb1d ("perf machine: Factor out lbr_callchain_add_lbr_ip()")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: German Gomez <german.gomez@arm.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Nick Terrell <terrelln@fb.com>
+Cc: Sean Christopherson <seanjc@google.com>
+Cc: Changbin Du <changbin.du@huawei.com>
+Cc: liuwenyu <liuwenyu7@huawei.com>
+Cc: Yang Jihong <yangjihong1@huawei.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Miguel Ojeda <ojeda@kernel.org>
+Cc: Song Liu <song@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Yanteng Si <siyanteng@loongson.cn>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Link: https://lore.kernel.org/r/20231024222353.3024098-3-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/machine.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
+index 55a041329990c..a0df9d24b2cb4 100644
+--- a/tools/perf/util/machine.c
++++ b/tools/perf/util/machine.c
+@@ -2437,16 +2437,18 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread,
+               save_lbr_cursor_node(thread, cursor, i);
+       }
+-      /* Add LBR ip from first entries.to */
+-      ip = entries[0].to;
+-      flags = &entries[0].flags;
+-      *branch_from = entries[0].from;
+-      err = add_callchain_ip(thread, cursor, parent,
+-                             root_al, &cpumode, ip,
+-                             true, flags, NULL,
+-                             *branch_from);
+-      if (err)
+-              return err;
++      if (lbr_nr > 0) {
++              /* Add LBR ip from first entries.to */
++              ip = entries[0].to;
++              flags = &entries[0].flags;
++              *branch_from = entries[0].from;
++              err = add_callchain_ip(thread, cursor, parent,
++                              root_al, &cpumode, ip,
++                              true, flags, NULL,
++                              *branch_from);
++              if (err)
++                      return err;
++      }
+       return 0;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/perf-tools-get-rid-of-evlist__add_on_all_cpus.patch b/queue-5.15/perf-tools-get-rid-of-evlist__add_on_all_cpus.patch
new file mode 100644 (file)
index 0000000..5fcda1f
--- /dev/null
@@ -0,0 +1,81 @@
+From 0bad7dc2bbd481839db55a75620e7603c114eee2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Oct 2022 13:46:45 -0700
+Subject: perf tools: Get rid of evlist__add_on_all_cpus()
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 60ea006f72512fd7c36f16cdbe91f4fc284f8115 ]
+
+The cpu and thread maps are properly handled in libperf now.  No need to
+do it in the perf tools anymore.  Let's remove the logic.
+
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20221003204647.1481128-4-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: f9cdeb58a9cf ("perf evlist: Avoid frequency mode for the dummy event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evlist.c | 29 ++---------------------------
+ 1 file changed, 2 insertions(+), 27 deletions(-)
+
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index a75cdcf381308..63ef40543a9fe 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -258,28 +258,6 @@ int evlist__add_dummy(struct evlist *evlist)
+       return 0;
+ }
+-static void evlist__add_on_all_cpus(struct evlist *evlist, struct evsel *evsel)
+-{
+-      evsel->core.system_wide = true;
+-
+-      /*
+-       * All CPUs.
+-       *
+-       * Note perf_event_open() does not accept CPUs that are not online, so
+-       * in fact this CPU list will include only all online CPUs.
+-       */
+-      perf_cpu_map__put(evsel->core.own_cpus);
+-      evsel->core.own_cpus = perf_cpu_map__new(NULL);
+-      perf_cpu_map__put(evsel->core.cpus);
+-      evsel->core.cpus = perf_cpu_map__get(evsel->core.own_cpus);
+-
+-      /* No threads */
+-      perf_thread_map__put(evsel->core.threads);
+-      evsel->core.threads = perf_thread_map__new_dummy();
+-
+-      evlist__add(evlist, evsel);
+-}
+-
+ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide)
+ {
+       struct evsel *evsel = evlist__dummy_event(evlist);
+@@ -292,14 +270,11 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, bool system_wide)
+       evsel->core.attr.exclude_hv = 1;
+       evsel->core.attr.freq = 0;
+       evsel->core.attr.sample_period = 1;
++      evsel->core.system_wide = system_wide;
+       evsel->no_aux_samples = true;
+       evsel->name = strdup("dummy:u");
+-      if (system_wide)
+-              evlist__add_on_all_cpus(evlist, evsel);
+-      else
+-              evlist__add(evlist, evsel);
+-
++      evlist__add(evlist, evsel);
+       return evsel;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/platform-x86-wmi-fix-opening-of-char-device.patch b/queue-5.15/platform-x86-wmi-fix-opening-of-char-device.patch
new file mode 100644 (file)
index 0000000..bd05df6
--- /dev/null
@@ -0,0 +1,69 @@
+From aff140ddac1b15e0ca9ad483da85784ef7fce10a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 23:10:04 +0200
+Subject: platform/x86: wmi: Fix opening of char device
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit eba9ac7abab91c8f6d351460239108bef5e7a0b6 ]
+
+Since commit fa1f68db6ca7 ("drivers: misc: pass miscdevice pointer via
+file private data"), the miscdevice stores a pointer to itself inside
+filp->private_data, which means that private_data will not be NULL when
+wmi_char_open() is called. This might cause memory corruption should
+wmi_char_open() be unable to find its driver, something which can
+happen when the associated WMI device is deleted in wmi_free_devices().
+
+Fix the problem by using the miscdevice pointer to retrieve the WMI
+device data associated with a char device using container_of(). This
+also avoids wmi_char_open() picking a wrong WMI device bound to a
+driver with the same name as the original driver.
+
+Fixes: 44b6b7661132 ("platform/x86: wmi: create userspace interface for drivers")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20231020211005.38216-5-W_Armin@gmx.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/wmi.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
+index 530778dbdd093..63265ab964245 100644
+--- a/drivers/platform/x86/wmi.c
++++ b/drivers/platform/x86/wmi.c
+@@ -827,21 +827,13 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
+ }
+ static int wmi_char_open(struct inode *inode, struct file *filp)
+ {
+-      const char *driver_name = filp->f_path.dentry->d_iname;
+-      struct wmi_block *wblock;
+-      struct wmi_block *next;
+-
+-      list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
+-              if (!wblock->dev.dev.driver)
+-                      continue;
+-              if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) {
+-                      filp->private_data = wblock;
+-                      break;
+-              }
+-      }
++      /*
++       * The miscdevice already stores a pointer to itself
++       * inside filp->private_data
++       */
++      struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev);
+-      if (!filp->private_data)
+-              return -ENODEV;
++      filp->private_data = wblock;
+       return nonseekable_open(inode, filp);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch b/queue-5.15/platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch
new file mode 100644 (file)
index 0000000..0d67cda
--- /dev/null
@@ -0,0 +1,84 @@
+From 7723b028daf17e2a0ebf61dd46224bb24a3ee1ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 23:10:03 +0200
+Subject: platform/x86: wmi: Fix probe failure when failing to register WMI
+ devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit ed85891a276edaf7a867de0e9acd0837bc3008f2 ]
+
+When a WMI device besides the first one somehow fails to register,
+retval is returned while still containing a negative error code. This
+causes the ACPI device fail to probe, leaving behind zombie WMI devices
+leading to various errors later.
+
+Handle the single error path separately and return 0 unconditionally
+after trying to register all WMI devices to solve the issue. Also
+continue to register WMI devices even if some fail to allocate memory.
+
+Fixes: 6ee50aaa9a20 ("platform/x86: wmi: Instantiate all devices before adding them")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Link: https://lore.kernel.org/r/20231020211005.38216-4-W_Armin@gmx.de
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/wmi.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
+index 7ce0408d3bfdd..e87ed10fd6269 100644
+--- a/drivers/platform/x86/wmi.c
++++ b/drivers/platform/x86/wmi.c
+@@ -1161,8 +1161,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
+       struct wmi_block *wblock, *next;
+       union acpi_object *obj;
+       acpi_status status;
+-      int retval = 0;
+       u32 i, total;
++      int retval;
+       status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
+       if (ACPI_FAILURE(status))
+@@ -1173,8 +1173,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
+               return -ENXIO;
+       if (obj->type != ACPI_TYPE_BUFFER) {
+-              retval = -ENXIO;
+-              goto out_free_pointer;
++              kfree(obj);
++              return -ENXIO;
+       }
+       gblock = (const struct guid_block *)obj->buffer.pointer;
+@@ -1195,8 +1195,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
+               wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
+               if (!wblock) {
+-                      retval = -ENOMEM;
+-                      break;
++                      dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid);
++                      continue;
+               }
+               wblock->acpi_device = device;
+@@ -1235,9 +1235,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
+               }
+       }
+-out_free_pointer:
+-      kfree(out.pointer);
+-      return retval;
++      kfree(obj);
++
++      return 0;
+ }
+ /*
+-- 
+2.42.0
+
diff --git a/queue-5.15/platform-x86-wmi-remove-unnecessary-initializations.patch b/queue-5.15/platform-x86-wmi-remove-unnecessary-initializations.patch
new file mode 100644 (file)
index 0000000..b679bd0
--- /dev/null
@@ -0,0 +1,94 @@
+From c2639adbd067567b5bf3b3732092a2fa44d0a9bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Sep 2021 17:55:10 +0000
+Subject: platform/x86: wmi: remove unnecessary initializations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Barnabás Pőcze <pobrn@protonmail.com>
+
+[ Upstream commit 43aacf838ef7384d985ef5385ecb0124f8c70007 ]
+
+Some pointers are initialized when they are defined,
+but they are almost immediately reassigned in the
+following lines. Remove these superfluous assignments.
+
+Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
+Link: https://lore.kernel.org/r/20210904175450.156801-6-pobrn@protonmail.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Stable-dep-of: eba9ac7abab9 ("platform/x86: wmi: Fix opening of char device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/wmi.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
+index e87ed10fd6269..530778dbdd093 100644
+--- a/drivers/platform/x86/wmi.c
++++ b/drivers/platform/x86/wmi.c
+@@ -188,7 +188,7 @@ static int get_subobj_info(acpi_handle handle, const char *pathname,
+ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
+ {
+-      struct guid_block *block = NULL;
++      struct guid_block *block;
+       char method[5];
+       acpi_status status;
+       acpi_handle handle;
+@@ -262,8 +262,8 @@ EXPORT_SYMBOL_GPL(wmi_evaluate_method);
+ acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance,
+       u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
+ {
+-      struct guid_block *block = NULL;
+-      struct wmi_block *wblock = NULL;
++      struct guid_block *block;
++      struct wmi_block *wblock;
+       acpi_handle handle;
+       acpi_status status;
+       struct acpi_object_list input;
+@@ -310,7 +310,7 @@ EXPORT_SYMBOL_GPL(wmidev_evaluate_method);
+ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
+                                struct acpi_buffer *out)
+ {
+-      struct guid_block *block = NULL;
++      struct guid_block *block;
+       acpi_handle handle;
+       acpi_status status, wc_status = AE_ERROR;
+       struct acpi_object_list input;
+@@ -423,8 +423,8 @@ EXPORT_SYMBOL_GPL(wmidev_block_query);
+ acpi_status wmi_set_block(const char *guid_string, u8 instance,
+                         const struct acpi_buffer *in)
+ {
+-      struct guid_block *block = NULL;
+       struct wmi_block *wblock = NULL;
++      struct guid_block *block;
+       acpi_handle handle;
+       struct acpi_object_list input;
+       union acpi_object params[2];
+@@ -828,8 +828,8 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
+ static int wmi_char_open(struct inode *inode, struct file *filp)
+ {
+       const char *driver_name = filp->f_path.dentry->d_iname;
+-      struct wmi_block *wblock = NULL;
+-      struct wmi_block *next = NULL;
++      struct wmi_block *wblock;
++      struct wmi_block *next;
+       list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
+               if (!wblock->dev.dev.driver)
+@@ -861,8 +861,8 @@ static long wmi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+       struct wmi_ioctl_buffer __user *input =
+               (struct wmi_ioctl_buffer __user *) arg;
+       struct wmi_block *wblock = filp->private_data;
+-      struct wmi_ioctl_buffer *buf = NULL;
+-      struct wmi_driver *wdriver = NULL;
++      struct wmi_ioctl_buffer *buf;
++      struct wmi_driver *wdriver;
+       int ret;
+       if (_IOC_TYPE(cmd) != WMI_IOC)
+-- 
+2.42.0
+
diff --git a/queue-5.15/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch b/queue-5.15/pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch
new file mode 100644 (file)
index 0000000..01b04b2
--- /dev/null
@@ -0,0 +1,53 @@
+From 1c9089c867fac0beefc1ab3cea9605ff8a841af8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 11:32:17 +0200
+Subject: PM / devfreq: rockchip-dfi: Make pmu regmap mandatory
+
+From: Sascha Hauer <s.hauer@pengutronix.de>
+
+[ Upstream commit 1e0731c05c985deb68a97fa44c1adcd3305dda90 ]
+
+As a matter of fact the regmap_pmu already is mandatory because
+it is used unconditionally in the driver. Bail out gracefully in
+probe() rather than crashing later.
+
+Link: https://lore.kernel.org/lkml/20230704093242.583575-2-s.hauer@pengutronix.de/
+Fixes: b9d1262bca0af ("PM / devfreq: event: support rockchip dfi controller")
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/devfreq/event/rockchip-dfi.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
+index 9a88faaf8b27f..4dafdf23197b9 100644
+--- a/drivers/devfreq/event/rockchip-dfi.c
++++ b/drivers/devfreq/event/rockchip-dfi.c
+@@ -194,14 +194,15 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
+               return PTR_ERR(data->clk);
+       }
+-      /* try to find the optional reference to the pmu syscon */
+       node = of_parse_phandle(np, "rockchip,pmu", 0);
+-      if (node) {
+-              data->regmap_pmu = syscon_node_to_regmap(node);
+-              of_node_put(node);
+-              if (IS_ERR(data->regmap_pmu))
+-                      return PTR_ERR(data->regmap_pmu);
+-      }
++      if (!node)
++              return dev_err_probe(&pdev->dev, -ENODEV, "Can't find pmu_grf registers\n");
++
++      data->regmap_pmu = syscon_node_to_regmap(node);
++      of_node_put(node);
++      if (IS_ERR(data->regmap_pmu))
++              return PTR_ERR(data->regmap_pmu);
++
+       data->dev = dev;
+       desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch b/queue-5.15/powerpc-40x-remove-stale-pte_atomic_updates-macro.patch
new file mode 100644 (file)
index 0000000..edda97a
--- /dev/null
@@ -0,0 +1,44 @@
+From 041abb3e9fbef36ac40e41310f0e314e42877c2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Sep 2023 20:31:17 +0200
+Subject: powerpc/40x: Remove stale PTE_ATOMIC_UPDATES macro
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit cc8ee288f484a2a59c01ccd4d8a417d6ed3466e3 ]
+
+40x TLB handlers were reworked by commit 2c74e2586bb9 ("powerpc/40x:
+Rework 40x PTE access and TLB miss") to not require PTE_ATOMIC_UPDATES
+anymore.
+
+Then commit 4e1df545e2fa ("powerpc/pgtable: Drop PTE_ATOMIC_UPDATES")
+removed all code related to PTE_ATOMIC_UPDATES.
+
+Remove left over PTE_ATOMIC_UPDATES macro.
+
+Fixes: 2c74e2586bb9 ("powerpc/40x: Rework 40x PTE access and TLB miss")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/f061db5857fcd748f84a6707aad01754686ce97e.1695659959.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/nohash/32/pte-40x.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h
+index 2d3153cfc0d79..acf61242e85bf 100644
+--- a/arch/powerpc/include/asm/nohash/32/pte-40x.h
++++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h
+@@ -69,9 +69,6 @@
+ #define _PTE_NONE_MASK        0
+-/* Until my rework is finished, 40x still needs atomic PTE updates */
+-#define PTE_ATOMIC_UPDATES    1
+-
+ #define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED)
+ #define _PAGE_BASE    (_PAGE_BASE_NC)
+-- 
+2.42.0
+
diff --git a/queue-5.15/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch b/queue-5.15/powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch
new file mode 100644 (file)
index 0000000..d5ceffe
--- /dev/null
@@ -0,0 +1,40 @@
+From 8b52563e4794fb7f023064d62286db1297877a22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Mar 2023 14:48:31 +0100
+Subject: powerpc/imc-pmu: Use the correct spinlock initializer.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 007240d59c11f87ac4f6cfc6a1d116630b6b634c ]
+
+The macro __SPIN_LOCK_INITIALIZER() is implementation specific. Users
+that desire to initialize a spinlock in a struct must use
+__SPIN_LOCK_UNLOCKED().
+
+Use __SPIN_LOCK_UNLOCKED() for the spinlock_t in imc_global_refc.
+
+Fixes: 76d588dddc459 ("powerpc/imc-pmu: Fix use of mutex in IRQs disabled section")
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230309134831.Nz12nqsU@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/imc-pmu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
+index b8a100b9736c7..55a853edc3bea 100644
+--- a/arch/powerpc/perf/imc-pmu.c
++++ b/arch/powerpc/perf/imc-pmu.c
+@@ -50,7 +50,7 @@ static int trace_imc_mem_size;
+  * core and trace-imc
+  */
+ static struct imc_pmu_ref imc_global_refc = {
+-      .lock = __SPIN_LOCK_INITIALIZER(imc_global_refc.lock),
++      .lock = __SPIN_LOCK_UNLOCKED(imc_global_refc.lock),
+       .id = 0,
+       .refc = 0,
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/powerpc-only-define-__parse_fpscr-when-required.patch b/queue-5.15/powerpc-only-define-__parse_fpscr-when-required.patch
new file mode 100644 (file)
index 0000000..6368871
--- /dev/null
@@ -0,0 +1,55 @@
+From c94bb87ef35f6796772323a3d7c40b2018ee1823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 14:33:13 +0200
+Subject: powerpc: Only define __parse_fpscr() when required
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit c7e0d9bb9154c6e6b2ac8746faba27b53393f25e ]
+
+Clang 17 reports:
+
+arch/powerpc/kernel/traps.c:1167:19: error: unused function '__parse_fpscr' [-Werror,-Wunused-function]
+
+__parse_fpscr() is called from two sites. First call is guarded
+by #ifdef CONFIG_PPC_FPU_REGS
+
+Second call is guarded by CONFIG_MATH_EMULATION which selects
+CONFIG_PPC_FPU_REGS.
+
+So only define __parse_fpscr() when CONFIG_PPC_FPU_REGS is defined.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202309210327.WkqSd5Bq-lkp@intel.com/
+Fixes: b6254ced4da6 ("powerpc/signal: Don't manage floating point regs when no FPU")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/5de2998c57f3983563b27b39228ea9a7229d4110.1695385984.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/traps.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
+index a08bb7cefdc54..fe912983ced96 100644
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -1148,6 +1148,7 @@ static void emulate_single_step(struct pt_regs *regs)
+               __single_step_exception(regs);
+ }
++#ifdef CONFIG_PPC_FPU_REGS
+ static inline int __parse_fpscr(unsigned long fpscr)
+ {
+       int ret = FPE_FLTUNK;
+@@ -1174,6 +1175,7 @@ static inline int __parse_fpscr(unsigned long fpscr)
+       return ret;
+ }
++#endif
+ static void parse_fpe(struct pt_regs *regs)
+ {
+-- 
+2.42.0
+
diff --git a/queue-5.15/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch b/queue-5.15/powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch
new file mode 100644 (file)
index 0000000..8d50ed4
--- /dev/null
@@ -0,0 +1,43 @@
+From 50d3fd64250fa8af779b91a74d3b826f34fea471 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Dec 2022 15:46:23 +0800
+Subject: powerpc/pseries: fix potential memory leak in
+ init_cpu_associativity()
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit 95f1a128cd728a7257d78e868f1f5a145fc43736 ]
+
+If the vcpu_associativity alloc memory successfully but the
+pcpu_associativity fails to alloc memory, the vcpu_associativity
+memory leaks.
+
+Fixes: d62c8deeb6e6 ("powerpc/pseries: Provide vcpu dispatch statistics")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Reviewed-by: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/1671003983-10794-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/lpar.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index d133597a84ca0..fce0237b07155 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -524,8 +524,10 @@ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
+       if (cmd) {
+               rc = init_cpu_associativity();
+-              if (rc)
++              if (rc) {
++                      destroy_cpu_associativity();
+                       goto out;
++              }
+               for_each_possible_cpu(cpu) {
+                       disp = per_cpu_ptr(&vcpu_disp_data, cpu);
+-- 
+2.42.0
+
diff --git a/queue-5.15/powerpc-xive-fix-endian-conversion-size.patch b/queue-5.15/powerpc-xive-fix-endian-conversion-size.patch
new file mode 100644 (file)
index 0000000..f49598f
--- /dev/null
@@ -0,0 +1,41 @@
+From 607f3f59c5816b3d7b64f7794ba42661b5c2adcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 16:37:00 +1100
+Subject: powerpc/xive: Fix endian conversion size
+
+From: Benjamin Gray <bgray@linux.ibm.com>
+
+[ Upstream commit ff7a60ab1e065257a0e467c13b519f4debcd7fcf ]
+
+Sparse reports a size mismatch in the endian swap. The Opal
+implementation[1] passes the value as a __be64, and the receiving
+variable out_qsize is a u64, so the use of be32_to_cpu() appears to be
+an error.
+
+[1]: https://github.com/open-power/skiboot/blob/80e2b1dc73/hw/xive.c#L3854
+
+Fixes: 88ec6b93c8e7 ("powerpc/xive: add OPAL extensions for the XIVE native exploitation support")
+Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20231011053711.93427-2-bgray@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/native.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
+index 1aec282cd650d..b6323bdecfa4c 100644
+--- a/arch/powerpc/sysdev/xive/native.c
++++ b/arch/powerpc/sysdev/xive/native.c
+@@ -786,7 +786,7 @@ int xive_native_get_queue_info(u32 vp_id, u32 prio,
+       if (out_qpage)
+               *out_qpage = be64_to_cpu(qpage);
+       if (out_qsize)
+-              *out_qsize = be32_to_cpu(qsize);
++              *out_qsize = be64_to_cpu(qsize);
+       if (out_qeoi_page)
+               *out_qeoi_page = be64_to_cpu(qeoi_page);
+       if (out_escalate_irq)
+-- 
+2.42.0
+
diff --git a/queue-5.15/pstore-platform-add-check-for-kstrdup.patch b/queue-5.15/pstore-platform-add-check-for-kstrdup.patch
new file mode 100644 (file)
index 0000000..ad4b03e
--- /dev/null
@@ -0,0 +1,63 @@
+From e384beef309da2c7d0e211f19129261e8759337a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 10:27:06 +0800
+Subject: pstore/platform: Add check for kstrdup
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit a19d48f7c5d57c0f0405a7d4334d1d38fe9d3c1c ]
+
+Add check for the return value of kstrdup() and return the error
+if it fails in order to avoid NULL pointer dereference.
+
+Fixes: 563ca40ddf40 ("pstore/platform: Switch pstore_info::name to const")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20230623022706.32125-1-jiasheng@iscas.ac.cn
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/platform.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
+index ad96ba97d8f97..3fc4739f82d86 100644
+--- a/fs/pstore/platform.c
++++ b/fs/pstore/platform.c
+@@ -561,6 +561,8 @@ static int pstore_write_user_compat(struct pstore_record *record,
+  */
+ int pstore_register(struct pstore_info *psi)
+ {
++      char *new_backend;
++
+       if (backend && strcmp(backend, psi->name)) {
+               pr_warn("ignoring unexpected backend '%s'\n", psi->name);
+               return -EPERM;
+@@ -580,11 +582,16 @@ int pstore_register(struct pstore_info *psi)
+               return -EINVAL;
+       }
++      new_backend = kstrdup(psi->name, GFP_KERNEL);
++      if (!new_backend)
++              return -ENOMEM;
++
+       mutex_lock(&psinfo_lock);
+       if (psinfo) {
+               pr_warn("backend '%s' already loaded: ignoring '%s'\n",
+                       psinfo->name, psi->name);
+               mutex_unlock(&psinfo_lock);
++              kfree(new_backend);
+               return -EBUSY;
+       }
+@@ -617,7 +624,7 @@ int pstore_register(struct pstore_info *psi)
+        * Update the module parameter backend, so it is visible
+        * through /sys/module/pstore/parameters/backend
+        */
+-      backend = kstrdup(psi->name, GFP_KERNEL);
++      backend = new_backend;
+       pr_info("Registered %s as persistent store backend\n", psi->name);
+-- 
+2.42.0
+
diff --git a/queue-5.15/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch b/queue-5.15/r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch
new file mode 100644 (file)
index 0000000..5f396fd
--- /dev/null
@@ -0,0 +1,52 @@
+From 9fa06c0e8bfa31ac60ee8edb31ec9ad07818f456 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 08:51:13 +0200
+Subject: r8169: fix rare issue with broken rx after link-down on RTL8125
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 621735f590643e3048ca2060c285b80551660601 ]
+
+In very rare cases (I've seen two reports so far about different
+RTL8125 chip versions) it seems the MAC locks up when link goes down
+and requires a software reset to get revived.
+Realtek doesn't publish hw errata information, therefore the root cause
+is unknown. Realtek vendor drivers do a full hw re-initialization on
+each link-up event, the slimmed-down variant here was reported to fix
+the issue for the reporting user.
+It's not fully clear which parts of the NIC are reset as part of the
+software reset, therefore I can't rule out side effects.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Reported-by: Martin Kjær Jørgensen <me@lagy.org>
+Link: https://lore.kernel.org/netdev/97ec2232-3257-316c-c3e7-a08192ce16a6@gmail.com/T/
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/9edde757-9c3b-4730-be3b-0ef3a374ff71@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 73bbcb72cf3f0..ab84c623a7c62 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4661,7 +4661,11 @@ static void r8169_phylink_handler(struct net_device *ndev)
+       if (netif_carrier_ok(ndev)) {
+               rtl_link_chg_patch(tp);
+               pm_request_resume(d);
++              netif_wake_queue(tp->dev);
+       } else {
++              /* In few cases rx is broken after link-down otherwise */
++              if (rtl_is_8125(tp))
++                      rtl_reset_work(tp);
+               pm_runtime_idle(d);
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/r8169-use-tp_to_dev-instead-of-open-code.patch b/queue-5.15/r8169-use-tp_to_dev-instead-of-open-code.patch
new file mode 100644 (file)
index 0000000..98259ba
--- /dev/null
@@ -0,0 +1,49 @@
+From b69734d3fae7bdfdca28a40866231859f293fba2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Nov 2022 01:12:44 +0900
+Subject: r8169: use tp_to_dev instead of open code
+
+From: Juhee Kang <claudiajkang@gmail.com>
+
+[ Upstream commit 4b6c6065fca123d419afef005a696f51e6590470 ]
+
+The open code is defined as a helper function(tp_to_dev) on r8169_main.c,
+which the open code is &tp->pci_dev->dev. The helper function was added
+in commit 1e1205b7d3e9 ("r8169: add helper tp_to_dev"). And then later,
+commit f1e911d5d0df ("r8169: add basic phylib support") added
+r8169_phylink_handler function but it didn't use the helper function.
+Thus, tp_to_dev() replaces the open code. This patch doesn't change logic.
+
+Signed-off-by: Juhee Kang <claudiajkang@gmail.com>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/20221129161244.5356-1-claudiajkang@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 621735f59064 ("r8169: fix rare issue with broken rx after link-down on RTL8125")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 1cd0928472c0c..73bbcb72cf3f0 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4656,12 +4656,13 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
+ static void r8169_phylink_handler(struct net_device *ndev)
+ {
+       struct rtl8169_private *tp = netdev_priv(ndev);
++      struct device *d = tp_to_dev(tp);
+       if (netif_carrier_ok(ndev)) {
+               rtl_link_chg_patch(tp);
+-              pm_request_resume(&tp->pci_dev->dev);
++              pm_request_resume(d);
+       } else {
+-              pm_runtime_idle(&tp->pci_dev->dev);
++              pm_runtime_idle(d);
+       }
+       if (net_ratelimit())
+-- 
+2.42.0
+
diff --git a/queue-5.15/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch b/queue-5.15/rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch
new file mode 100644 (file)
index 0000000..70be05b
--- /dev/null
@@ -0,0 +1,118 @@
+From 4194d26e5a49ffb3de4f8a8481a1784ad1e96e82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Sep 2023 15:21:36 -0600
+Subject: RDMA/core: Use size_{add,sub,mul}() in calls to struct_size()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 81760bedc65194ff38e1e4faefd5f9f0c95c19a4 ]
+
+If, for any reason, the open-coded arithmetic causes a wraparound,
+the protection that `struct_size()` provides against potential integer
+overflows is defeated. Fix this by hardening calls to `struct_size()`
+with `size_add()`, `size_sub()` and `size_mul()`.
+
+Fixes: 467f432a521a ("RDMA/core: Split port and device counter sysfs attributes")
+Fixes: a4676388e2e2 ("RDMA/core: Simplify how the gid_attrs sysfs is created")
+Fixes: e9dd5daf884c ("IB/umad: Refactor code to use cdev_device_add()")
+Fixes: 324e227ea7c9 ("RDMA/device: Add ib_device_get_by_netdev()")
+Fixes: 5aad26a7eac5 ("IB/core: Use struct_size() in kzalloc()")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/ZQdt4NsJFwwOYxUR@work
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c   |  2 +-
+ drivers/infiniband/core/sa_query.c |  4 +++-
+ drivers/infiniband/core/sysfs.c    | 10 +++++-----
+ drivers/infiniband/core/user_mad.c |  4 +++-
+ 4 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index ab2106a09f9c6..2c2ac63b39c42 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -803,7 +803,7 @@ static int alloc_port_data(struct ib_device *device)
+        * empty slots at the beginning.
+        */
+       pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
+-                                      rdma_end_port(device) + 1),
++                                      size_add(rdma_end_port(device), 1)),
+                           GFP_KERNEL);
+       if (!pdata_rcu)
+               return -ENOMEM;
+diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
+index c00f8e28aab75..1557c71dd152f 100644
+--- a/drivers/infiniband/core/sa_query.c
++++ b/drivers/infiniband/core/sa_query.c
+@@ -2132,7 +2132,9 @@ static int ib_sa_add_one(struct ib_device *device)
+       s = rdma_start_port(device);
+       e = rdma_end_port(device);
+-      sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
++      sa_dev = kzalloc(struct_size(sa_dev, port,
++                                   size_add(size_sub(e, s), 1)),
++                       GFP_KERNEL);
+       if (!sa_dev)
+               return -ENOMEM;
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+index 253ccaf343f69..afc59048c40c8 100644
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -902,7 +902,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
+        * Two extra attribue elements here, one for the lifespan entry and
+        * one to NULL terminate the list for the sysfs core code
+        */
+-      data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
++      data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
+                      GFP_KERNEL);
+       if (!data)
+               goto err_free_stats;
+@@ -1001,7 +1001,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
+        * Two extra attribue elements here, one for the lifespan entry and
+        * one to NULL terminate the list for the sysfs core code
+        */
+-      data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
++      data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
+                      GFP_KERNEL);
+       if (!data)
+               goto err_free_stats;
+@@ -1125,7 +1125,7 @@ static int setup_gid_attrs(struct ib_port *port,
+       int ret;
+       gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
+-                                           attr->gid_tbl_len * 2),
++                                           size_mul(attr->gid_tbl_len, 2)),
+                                GFP_KERNEL);
+       if (!gid_attr_group)
+               return -ENOMEM;
+@@ -1190,8 +1190,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
+       int ret;
+       p = kvzalloc(struct_size(p, attrs_list,
+-                              attr->gid_tbl_len + attr->pkey_tbl_len),
+-                  GFP_KERNEL);
++                              size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
++                   GFP_KERNEL);
+       if (!p)
+               return ERR_PTR(-ENOMEM);
+       p->ibdev = device;
+diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
+index a61c9ede43387..5c284dfbe6923 100644
+--- a/drivers/infiniband/core/user_mad.c
++++ b/drivers/infiniband/core/user_mad.c
+@@ -1378,7 +1378,9 @@ static int ib_umad_add_one(struct ib_device *device)
+       s = rdma_start_port(device);
+       e = rdma_end_port(device);
+-      umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
++      umad_dev = kzalloc(struct_size(umad_dev, ports,
++                                     size_add(size_sub(e, s), 1)),
++                         GFP_KERNEL);
+       if (!umad_dev)
+               return -ENOMEM;
+-- 
+2.42.0
+
diff --git a/queue-5.15/rdma-hfi1-workaround-truncation-compilation-error.patch b/queue-5.15/rdma-hfi1-workaround-truncation-compilation-error.patch
new file mode 100644 (file)
index 0000000..3a16703
--- /dev/null
@@ -0,0 +1,57 @@
+From afedc1e5f9e5e434fc0aa45cb5d1e0a38dff95aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 18:07:31 +0300
+Subject: RDMA/hfi1: Workaround truncation compilation error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit d4b2d165714c0ce8777d5131f6e0aad617b7adc4 ]
+
+Increase name array to be large enough to overcome the following
+compilation error.
+
+drivers/infiniband/hw/hfi1/efivar.c: In function ‘read_hfi1_efi_var’:
+drivers/infiniband/hw/hfi1/efivar.c:124:44: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
+  124 |         snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
+      |                                            ^
+drivers/infiniband/hw/hfi1/efivar.c:124:9: note: ‘snprintf’ output 2 or more bytes (assuming 65) into a destination of size 64
+  124 |         snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
+      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/infiniband/hw/hfi1/efivar.c:133:52: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
+  133 |                 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
+      |                                                    ^
+drivers/infiniband/hw/hfi1/efivar.c:133:17: note: ‘snprintf’ output 2 or more bytes (assuming 65) into a destination of size 64
+  133 |                 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
+      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cc1: all warnings being treated as errors
+make[6]: *** [scripts/Makefile.build:243: drivers/infiniband/hw/hfi1/efivar.o] Error 1
+
+Fixes: c03c08d50b3d ("IB/hfi1: Check upper-case EFI variables")
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/238fa39a8fd60e87a5ad7e1ca6584fcdf32e9519.1698159993.git.leonro@nvidia.com
+Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/efivar.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/efivar.c b/drivers/infiniband/hw/hfi1/efivar.c
+index f275dd1abed85..7a3caf2cd9071 100644
+--- a/drivers/infiniband/hw/hfi1/efivar.c
++++ b/drivers/infiniband/hw/hfi1/efivar.c
+@@ -110,7 +110,7 @@ int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind,
+                     unsigned long *size, void **return_data)
+ {
+       char prefix_name[64];
+-      char name[64];
++      char name[128];
+       int result;
+       int i;
+-- 
+2.42.0
+
diff --git a/queue-5.15/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch b/queue-5.15/rdma-hns-fix-signed-unsigned-mixed-comparisons.patch
new file mode 100644 (file)
index 0000000..b15a1b7
--- /dev/null
@@ -0,0 +1,41 @@
+From 20217d7520a0d288a89595dbb3afa32221ac8ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 20:52:35 +0800
+Subject: RDMA/hns: Fix signed-unsigned mixed comparisons
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit b5f9efff101b06fd06a5e280a2b00b1335f5f476 ]
+
+The ib_mtu_enum_to_int() and uverbs_attr_get_len() may returns a negative
+value. In this case, mixed comparisons of signed and unsigned types will
+throw wrong results.
+
+This patch adds judgement for this situation.
+
+Fixes: 30b707886aeb ("RDMA/hns: Support inline data in extented sge space for RC")
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20231017125239.164455-4-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_hw_v2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 4554d3e78b37b..59e1f51022f16 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -244,7 +244,7 @@ static bool check_inl_data_len(struct hns_roce_qp *qp, unsigned int len)
+       struct hns_roce_dev *hr_dev = to_hr_dev(qp->ibqp.device);
+       int mtu = ib_mtu_enum_to_int(qp->path_mtu);
+-      if (len > qp->max_inline_data || len > mtu) {
++      if (mtu < 0 || len > qp->max_inline_data || len > mtu) {
+               ibdev_err(&hr_dev->ib_dev,
+                         "invalid length of data, data len = %u, max inline len = %u, path mtu = %d.\n",
+                         len, qp->max_inline_data, mtu);
+-- 
+2.42.0
+
diff --git a/queue-5.15/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch b/queue-5.15/rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch
new file mode 100644 (file)
index 0000000..7901a04
--- /dev/null
@@ -0,0 +1,44 @@
+From 17a4849ae3a46872333e77a4ac26d307221ec7e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 20:52:34 +0800
+Subject: RDMA/hns: Fix uninitialized ucmd in hns_roce_create_qp_common()
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit c64e9710f9241e38a1c761ed1c1a30854784da66 ]
+
+ucmd in hns_roce_create_qp_common() are not initialized. But it works fine
+until new member sdb_addr is added to struct hns_roce_ib_create_qp.
+
+If the user-mode driver uses an old version ABI, then the value of the new
+member will be undefined after ib_copy_from_udata().
+
+This patch fixes it by initialize this variable to 0. And the default value
+of the new member sdb_addr will be 0 which is invalid.
+
+Fixes: 0425e3e6e0c7 ("RDMA/hns: Support flush cqe for hip08 in kernel space")
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20231017125239.164455-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_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index 00dade1cfff20..d085998b19c87 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -1049,7 +1049,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
+ {
+       struct hns_roce_ib_create_qp_resp resp = {};
+       struct ib_device *ibdev = &hr_dev->ib_dev;
+-      struct hns_roce_ib_create_qp ucmd;
++      struct hns_roce_ib_create_qp ucmd = {};
+       int ret;
+       mutex_init(&hr_qp->mutex);
+-- 
+2.42.0
+
diff --git a/queue-5.15/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch b/queue-5.15/rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch
new file mode 100644 (file)
index 0000000..fbc8f4e
--- /dev/null
@@ -0,0 +1,39 @@
+From c5b784263a978e49b65607bbc0a7dae4c333469b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 20:52:37 +0800
+Subject: RDMA/hns: The UD mode can only be configured with DCQCN
+
+From: Luoyouming <luoyouming@huawei.com>
+
+[ Upstream commit 27c5fd271d8b8730fc0bb1b6cae953ad7808a874 ]
+
+Due to hardware limitations, only DCQCN is supported for UD. Therefore, the
+default algorithm for UD is set to DCQCN.
+
+Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW")
+Signed-off-by: Luoyouming <luoyouming@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20231017125239.164455-6-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_hw_v2.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 59e1f51022f16..f034021f3adc1 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -4556,6 +4556,9 @@ static int check_cong_type(struct ib_qp *ibqp,
+ {
+       struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
++      if (ibqp->qp_type == IB_QPT_UD)
++              hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
++
+       /* different congestion types match different configurations */
+       switch (hr_dev->caps.cong_type) {
+       case CONG_TYPE_DCQCN:
+-- 
+2.42.0
+
diff --git a/queue-5.15/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch b/queue-5.15/regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch
new file mode 100644 (file)
index 0000000..fe9d3da
--- /dev/null
@@ -0,0 +1,37 @@
+From beed7db9fb4538c34ca371d7ff5c1f0b733a1349 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 22:04:06 +0200
+Subject: regmap: debugfs: Fix a erroneous check after snprintf()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d3601857e14de6369f00ae19564f1d817d175d19 ]
+
+This error handling looks really strange.
+Check if the string has been truncated instead.
+
+Fixes: f0c2319f9f19 ("regmap: Expose the driver name in debugfs")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/8595de2462c490561f70020a6d11f4d6b652b468.1693857825.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regmap-debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
+index ad684d37c2dae..6caed4b556365 100644
+--- a/drivers/base/regmap/regmap-debugfs.c
++++ b/drivers/base/regmap/regmap-debugfs.c
+@@ -48,7 +48,7 @@ static ssize_t regmap_name_read_file(struct file *file,
+               name = map->dev->driver->name;
+       ret = snprintf(buf, PAGE_SIZE, "%s\n", name);
+-      if (ret < 0) {
++      if (ret >= PAGE_SIZE) {
+               kfree(buf);
+               return ret;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/regmap-prevent-noinc-writes-from-clobbering-cache.patch b/queue-5.15/regmap-prevent-noinc-writes-from-clobbering-cache.patch
new file mode 100644 (file)
index 0000000..30f6e0a
--- /dev/null
@@ -0,0 +1,57 @@
+From 2f7d595cf67e4d2d02e08939cdfa2564978c5685 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Nov 2023 10:29:27 -0400
+Subject: regmap: prevent noinc writes from clobbering cache
+
+From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+
+[ Upstream commit 984a4afdc87a1fc226fd657b1cd8255c13d3fc1a ]
+
+Currently, noinc writes are cached as if they were standard incrementing
+writes, overwriting unrelated register values in the cache. Instead, we
+want to cache the last value written to the register, as is done in the
+accelerated noinc handler (regmap_noinc_readwrite).
+
+Fixes: cdf6b11daa77 ("regmap: Add regmap_noinc_write API")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Link: https://lore.kernel.org/r/20231101142926.2722603-2-ben.wolsieffer@hefring.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regmap.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
+index 617d51a278497..7621b54975b57 100644
+--- a/drivers/base/regmap/regmap.c
++++ b/drivers/base/regmap/regmap.c
+@@ -1683,17 +1683,19 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
+       }
+       if (!map->cache_bypass && map->format.parse_val) {
+-              unsigned int ival;
++              unsigned int ival, offset;
+               int val_bytes = map->format.val_bytes;
+-              for (i = 0; i < val_len / val_bytes; i++) {
+-                      ival = map->format.parse_val(val + (i * val_bytes));
+-                      ret = regcache_write(map,
+-                                           reg + regmap_get_offset(map, i),
+-                                           ival);
++
++              /* Cache the last written value for noinc writes */
++              i = noinc ? val_len - val_bytes : 0;
++              for (; i < val_len; i += val_bytes) {
++                      ival = map->format.parse_val(val + i);
++                      offset = noinc ? 0 : regmap_get_offset(map, i / val_bytes);
++                      ret = regcache_write(map, reg + offset, ival);
+                       if (ret) {
+                               dev_err(map->dev,
+                                       "Error in caching of register: %x ret: %d\n",
+-                                      reg + regmap_get_offset(map, i), ret);
++                                      reg + offset, ret);
+                               return ret;
+                       }
+               }
+-- 
+2.42.0
+
diff --git a/queue-5.15/revert-hid-logitech-hidpp-add-a-module-parameter-to-.patch b/queue-5.15/revert-hid-logitech-hidpp-add-a-module-parameter-to-.patch
new file mode 100644 (file)
index 0000000..15e8026
--- /dev/null
@@ -0,0 +1,59 @@
+From 1a2cbb57a00114d1acfdf051523abb3ca0b22e3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Dec 2022 16:43:43 +0100
+Subject: Revert "HID: logitech-hidpp: add a module parameter to keep firmware
+ gestures"
+
+From: Bastien Nocera <hadess@hadess.net>
+
+[ Upstream commit cae253d6033da885e71c29c1591b22838a52de76 ]
+
+Now that we're in 2022, and the majority of desktop environments can and
+should support touchpad gestures through libinput, remove the legacy
+module parameter that made it possible to use gestures implemented in
+firmware.
+
+This will eventually allow simplifying the driver's initialisation code.
+
+This reverts commit 9188dbaed68a4b23dc96eba165265c08caa7dc2a.
+
+Signed-off-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Link: https://lore.kernel.org/r/20221220154345.474596-1-hadess@hadess.net
+Stable-dep-of: 11ca0322a419 ("HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 25fa235934880..7681a3fa67dab 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -31,11 +31,6 @@ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+ MODULE_AUTHOR("Nestor Lopez Casado <nlopezcasad@logitech.com>");
+-static bool disable_raw_mode;
+-module_param(disable_raw_mode, bool, 0644);
+-MODULE_PARM_DESC(disable_raw_mode,
+-      "Disable Raw mode reporting for touchpads and keep firmware gestures.");
+-
+ static bool disable_tap_to_click;
+ module_param(disable_tap_to_click, bool, 0644);
+ MODULE_PARM_DESC(disable_tap_to_click,
+@@ -4137,11 +4132,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
+           hidpp_application_equals(hdev, HID_GD_KEYBOARD))
+               hidpp->quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS;
+-      if (disable_raw_mode) {
+-              hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
+-              hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT;
+-      }
+-
+       if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
+               ret = wtp_allocate(hdev, id);
+               if (ret)
+-- 
+2.42.0
+
diff --git a/queue-5.15/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch b/queue-5.15/rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch
new file mode 100644 (file)
index 0000000..455c288
--- /dev/null
@@ -0,0 +1,43 @@
+From 5e8708a4c644e752b5fe7edda7a5e96864282124 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Oct 2023 16:34:21 +0200
+Subject: rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits
+ call
+
+From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+
+[ Upstream commit 2be36c09b6b07306be33519e1aa70d2e2a2161bb ]
+
+The current implementation passes PIN_IO_INTA_OUT (2) as a mask and
+PIN_IO_INTAPM (GENMASK(1, 0)) as a value.
+Swap the variables to assign mask and value the right way.
+
+This error was first introduced with the alarm support. For better or
+worse it worked as expected because 0x02 was applied as a mask to 0x03,
+resulting 0x02 anyway. This will of course not work for any other value.
+
+Fixes: e5aac267a10a ("rtc: pcf85363: add alarm support")
+Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
+Link: https://lore.kernel.org/r/20231013-topic-pcf85363_regmap_update_bits-v1-1-c454f016f71f@gmail.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/rtc-pcf85363.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
+index bb3e9ba75f6c6..80e3839e1e86a 100644
+--- a/drivers/rtc/rtc-pcf85363.c
++++ b/drivers/rtc/rtc-pcf85363.c
+@@ -403,7 +403,7 @@ static int pcf85363_probe(struct i2c_client *client,
+       if (client->irq > 0) {
+               regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
+               regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO,
+-                                 PIN_IO_INTA_OUT, PIN_IO_INTAPM);
++                                 PIN_IO_INTAPM, PIN_IO_INTA_OUT);
+               ret = devm_request_threaded_irq(&client->dev, client->irq,
+                                               NULL, pcf85363_rtc_handle_irq,
+                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+-- 
+2.42.0
+
diff --git a/queue-5.15/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch b/queue-5.15/sched-fix-stop_one_cpu_nowait-vs-hotplug.patch
new file mode 100644 (file)
index 0000000..8eb3ee4
--- /dev/null
@@ -0,0 +1,211 @@
+From 22d4391b5f37f0131cd523bb129bf339f547e629 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 20:57:39 +0200
+Subject: sched: Fix stop_one_cpu_nowait() vs hotplug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit f0498d2a54e7966ce23cd7c7ff42c64fa0059b07 ]
+
+Kuyo reported sporadic failures on a sched_setaffinity() vs CPU
+hotplug stress-test -- notably affine_move_task() remains stuck in
+wait_for_completion(), leading to a hung-task detector warning.
+
+Specifically, it was reported that stop_one_cpu_nowait(.fn =
+migration_cpu_stop) returns false -- this stopper is responsible for
+the matching complete().
+
+The race scenario is:
+
+       CPU0                                    CPU1
+
+                                       // doing _cpu_down()
+
+  __set_cpus_allowed_ptr()
+    task_rq_lock();
+                                       takedown_cpu()
+                                         stop_machine_cpuslocked(take_cpu_down..)
+
+                                       <PREEMPT: cpu_stopper_thread()
+                                         MULTI_STOP_PREPARE
+                                         ...
+    __set_cpus_allowed_ptr_locked()
+      affine_move_task()
+        task_rq_unlock();
+
+  <PREEMPT: cpu_stopper_thread()\>
+    ack_state()
+                                         MULTI_STOP_RUN
+                                           take_cpu_down()
+                                             __cpu_disable();
+                                             stop_machine_park();
+                                               stopper->enabled = false;
+                                        />
+   />
+       stop_one_cpu_nowait(.fn = migration_cpu_stop);
+          if (stopper->enabled) // false!!!
+
+That is, by doing stop_one_cpu_nowait() after dropping rq-lock, the
+stopper thread gets a chance to preempt and allows the cpu-down for
+the target CPU to complete.
+
+OTOH, since stop_one_cpu_nowait() / cpu_stop_queue_work() needs to
+issue a wakeup, it must not be ran under the scheduler locks.
+
+Solve this apparent contradiction by keeping preemption disabled over
+the unlock + queue_stopper combination:
+
+       preempt_disable();
+       task_rq_unlock(...);
+       if (!stop_pending)
+         stop_one_cpu_nowait(...)
+       preempt_enable();
+
+This respects the lock ordering contraints while still avoiding the
+above race. That is, if we find the CPU is online under rq-lock, the
+targeted stop_one_cpu_nowait() must succeed.
+
+Apply this pattern to all similar stop_one_cpu_nowait() invocations.
+
+Fixes: 6d337eab041d ("sched: Fix migrate_disable() vs set_cpus_allowed_ptr()")
+Reported-by: "Kuyo Chang (張建文)" <Kuyo.Chang@mediatek.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: "Kuyo Chang (張建文)" <Kuyo.Chang@mediatek.com>
+Link: https://lkml.kernel.org/r/20231010200442.GA16515@noisy.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c     | 10 ++++++++--
+ kernel/sched/deadline.c |  2 ++
+ kernel/sched/fair.c     |  4 +++-
+ kernel/sched/rt.c       |  4 ++++
+ 4 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 2324b7055260a..25b8ea91168ea 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -2377,9 +2377,11 @@ static int migration_cpu_stop(void *data)
+                * it.
+                */
+               WARN_ON_ONCE(!pending->stop_pending);
++              preempt_disable();
+               task_rq_unlock(rq, p, &rf);
+               stop_one_cpu_nowait(task_cpu(p), migration_cpu_stop,
+                                   &pending->arg, &pending->stop_work);
++              preempt_enable();
+               return 0;
+       }
+ out:
+@@ -2660,12 +2662,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
+                       complete = true;
+               }
++              preempt_disable();
+               task_rq_unlock(rq, p, rf);
+-
+               if (push_task) {
+                       stop_one_cpu_nowait(rq->cpu, push_cpu_stop,
+                                           p, &rq->push_work);
+               }
++              preempt_enable();
+               if (complete)
+                       complete_all(&pending->done);
+@@ -2731,12 +2734,13 @@ static int affine_move_task(struct rq *rq, struct task_struct *p, struct rq_flag
+               if (flags & SCA_MIGRATE_ENABLE)
+                       p->migration_flags &= ~MDF_PUSH;
++              preempt_disable();
+               task_rq_unlock(rq, p, rf);
+-
+               if (!stop_pending) {
+                       stop_one_cpu_nowait(cpu_of(rq), migration_cpu_stop,
+                                           &pending->arg, &pending->stop_work);
+               }
++              preempt_enable();
+               if (flags & SCA_MIGRATE_ENABLE)
+                       return 0;
+@@ -8961,9 +8965,11 @@ static void balance_push(struct rq *rq)
+        * Temporarily drop rq->lock such that we can wake-up the stop task.
+        * Both preemption and IRQs are still disabled.
+        */
++      preempt_disable();
+       raw_spin_rq_unlock(rq);
+       stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task,
+                           this_cpu_ptr(&push_work));
++      preempt_enable();
+       /*
+        * At this point need_resched() is true and we'll take the loop in
+        * schedule(). The next pick is obviously going to be the stop task
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index de45e4d2c61fa..0a6d6899be5bd 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -2308,9 +2308,11 @@ static void pull_dl_task(struct rq *this_rq)
+               double_unlock_balance(this_rq, src_rq);
+               if (push_task) {
++                      preempt_disable();
+                       raw_spin_rq_unlock(this_rq);
+                       stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop,
+                                           push_task, &src_rq->push_work);
++                      preempt_enable();
+                       raw_spin_rq_lock(this_rq);
+               }
+       }
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index e9ea3244fa4d1..fd8b5656641b7 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -10364,13 +10364,15 @@ static int load_balance(int this_cpu, struct rq *this_rq,
+                               busiest->push_cpu = this_cpu;
+                               active_balance = 1;
+                       }
+-                      raw_spin_rq_unlock_irqrestore(busiest, flags);
++                      preempt_disable();
++                      raw_spin_rq_unlock_irqrestore(busiest, flags);
+                       if (active_balance) {
+                               stop_one_cpu_nowait(cpu_of(busiest),
+                                       active_load_balance_cpu_stop, busiest,
+                                       &busiest->active_balance_work);
+                       }
++                      preempt_enable();
+               }
+       } else {
+               sd->nr_balance_failed = 0;
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 4b9281e6b1ccd..7045595aacac6 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -1951,9 +1951,11 @@ static int push_rt_task(struct rq *rq, bool pull)
+                */
+               push_task = get_push_task(rq);
+               if (push_task) {
++                      preempt_disable();
+                       raw_spin_rq_unlock(rq);
+                       stop_one_cpu_nowait(rq->cpu, push_cpu_stop,
+                                           push_task, &rq->push_work);
++                      preempt_enable();
+                       raw_spin_rq_lock(rq);
+               }
+@@ -2290,9 +2292,11 @@ static void pull_rt_task(struct rq *this_rq)
+               double_unlock_balance(this_rq, src_rq);
+               if (push_task) {
++                      preempt_disable();
+                       raw_spin_rq_unlock(this_rq);
+                       stop_one_cpu_nowait(src_rq->cpu, push_cpu_stop,
+                                           push_task, &src_rq->push_work);
++                      preempt_enable();
+                       raw_spin_rq_lock(this_rq);
+               }
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch b/queue-5.15/sched-uclamp-ignore-util-0-optimization-in-feec-when.patch
new file mode 100644 (file)
index 0000000..09ccb59
--- /dev/null
@@ -0,0 +1,73 @@
+From b9941c37b8c431cbc36a1690a001706f049d2841 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Sep 2023 00:29:54 +0100
+Subject: sched/uclamp: Ignore (util == 0) optimization in feec() when
+ p_util_max = 0
+
+From: Qais Yousef <qyousef@layalina.io>
+
+[ Upstream commit 23c9519def98ee0fa97ea5871535e9b136f522fc ]
+
+find_energy_efficient_cpu() bails out early if effective util of the
+task is 0 as the delta at this point will be zero and there's nothing
+for EAS to do. When uclamp is being used, this could lead to wrong
+decisions when uclamp_max is set to 0. In this case the task is capped
+to performance point 0, but it is actually running and consuming energy
+and we can benefit from EAS energy calculations.
+
+Rework the condition so that it bails out when both util and uclamp_min
+are 0.
+
+We can do that without needing to use uclamp_task_util(); remove it.
+
+Fixes: d81304bc6193 ("sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()'s early exit condition")
+Signed-off-by: Qais Yousef (Google) <qyousef@layalina.io>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20230916232955.2099394-3-qyousef@layalina.io
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 646a6ae4b2509..e9ea3244fa4d1 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -3987,22 +3987,6 @@ static inline unsigned long task_util_est(struct task_struct *p)
+       return max(task_util(p), _task_util_est(p));
+ }
+-#ifdef CONFIG_UCLAMP_TASK
+-static inline unsigned long uclamp_task_util(struct task_struct *p,
+-                                           unsigned long uclamp_min,
+-                                           unsigned long uclamp_max)
+-{
+-      return clamp(task_util_est(p), uclamp_min, uclamp_max);
+-}
+-#else
+-static inline unsigned long uclamp_task_util(struct task_struct *p,
+-                                           unsigned long uclamp_min,
+-                                           unsigned long uclamp_max)
+-{
+-      return task_util_est(p);
+-}
+-#endif
+-
+ static inline void util_est_enqueue(struct cfs_rq *cfs_rq,
+                                   struct task_struct *p)
+ {
+@@ -7037,7 +7021,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+       target = prev_cpu;
+       sync_entity_load_avg(&p->se);
+-      if (!uclamp_task_util(p, p_util_min, p_util_max))
++      if (!task_util_est(p) && p_util_min == 0)
+               goto unlock;
+       for (; pd; pd = pd->next) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch b/queue-5.15/scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch
new file mode 100644 (file)
index 0000000..1d54004
--- /dev/null
@@ -0,0 +1,51 @@
+From af7a97175d47ce62f77cd7a452552b5a8e76b1d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 17:54:28 -0500
+Subject: scsi: ibmvfc: Fix erroneous use of rtas_busy_delay with hcall return
+ code
+
+From: Tyrel Datwyler <tyreld@linux.ibm.com>
+
+[ Upstream commit 670106eb4c8b23475f8c2b3416005a312afa622f ]
+
+Commit 0217a272fe13 ("scsi: ibmvfc: Store return code of H_FREE_SUB_CRQ
+during cleanup") wrongly changed the busy loop check to use
+rtas_busy_delay() instead of H_BUSY and H_IS_LONG_BUSY(). The busy return
+codes for RTAS and hypercalls are not the same.
+
+Fix this issue by restoring the use of H_BUSY and H_IS_LONG_BUSY().
+
+Fixes: 0217a272fe13 ("scsi: ibmvfc: Store return code of H_FREE_SUB_CRQ  during cleanup")
+Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230921225435.3537728-5-tyreld@linux.ibm.com
+Reviewed-by: Brian King <brking@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ibmvscsi/ibmvfc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
+index 45ef78f388dc9..d169ba772450f 100644
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -22,7 +22,6 @@
+ #include <linux/bsg-lib.h>
+ #include <asm/firmware.h>
+ #include <asm/irq.h>
+-#include <asm/rtas.h>
+ #include <asm/vio.h>
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_cmnd.h>
+@@ -5802,7 +5801,7 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
+ irq_failed:
+       do {
+               rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
+-      } while (rtas_busy_delay(rc));
++      } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+ reg_failed:
+       LEAVE;
+       return rc;
+-- 
+2.42.0
+
diff --git a/queue-5.15/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch b/queue-5.15/scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch
new file mode 100644 (file)
index 0000000..8afb6f4
--- /dev/null
@@ -0,0 +1,48 @@
+From 28c867debc183b2773635a065525148a79533e91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 11:20:26 -0700
+Subject: scsi: ufs: core: Leave space for '\0' in utf8 desc string
+
+From: Daniel Mentz <danielmentz@google.com>
+
+[ Upstream commit a75a16c62a2540f11eeae4f2b50e95deefb652ea ]
+
+utf16s_to_utf8s does not NULL terminate the output string. For us to be
+able to add a NULL character when utf16s_to_utf8s returns, we need to make
+sure that there is space for such NULL character at the end of the output
+buffer. We can achieve this by passing an output buffer size to
+utf16s_to_utf8s that is one character less than what we allocated.
+
+Other call sites of utf16s_to_utf8s appear to be using the same technique
+where they artificially reduce the buffer size by one to leave space for a
+NULL character or line feed character.
+
+Fixes: 4b828fe156a6 ("scsi: ufs: revamp string descriptor reading")
+Reviewed-by: Mars Cheng <marscheng@google.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Yen-lin Lai <yenlinlai@google.com>
+Signed-off-by: Daniel Mentz <danielmentz@google.com>
+Link: https://lore.kernel.org/r/20231017182026.2141163-1-danielmentz@google.com
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index f48036f09eab5..e78461f66400c 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -3465,7 +3465,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
+                */
+               ret = utf16s_to_utf8s(uc_str->uc,
+                                     uc_str->len - QUERY_DESC_HDR_SIZE,
+-                                    UTF16_BIG_ENDIAN, str, ascii_len);
++                                    UTF16_BIG_ENDIAN, str, ascii_len - 1);
+               /* replace non-printable or non-ASCII characters with spaces */
+               for (i = 0; i < ret; i++)
+-- 
+2.42.0
+
diff --git a/queue-5.15/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch b/queue-5.15/selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch
new file mode 100644 (file)
index 0000000..0e3a456
--- /dev/null
@@ -0,0 +1,121 @@
+From ca6b75eaf16ab2394cf8f037f509b6bad7e59b3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 23:42:56 +0800
+Subject: selftests/bpf: Correct map_fd to data_fd in tailcalls
+
+From: Leon Hwang <hffilwlqm@gmail.com>
+
+[ Upstream commit 96daa9874211d5497aa70fa409b67afc29f0cb86 ]
+
+Get and check data_fd. It should not check map_fd again.
+
+Meanwhile, correct some 'return' to 'goto out'.
+
+Thank the suggestion from Maciej in "bpf, x64: Fix tailcall infinite
+loop"[0] discussions.
+
+[0] https://lore.kernel.org/bpf/e496aef8-1f80-0f8e-dcdd-25a8c300319a@gmail.com/T/#m7d3b601066ba66400d436b7e7579b2df4a101033
+
+Fixes: 79d49ba048ec ("bpf, testing: Add various tail call test cases")
+Fixes: 3b0379111197 ("selftests/bpf: Add tailcall_bpf2bpf tests")
+Fixes: 5e0b0a4c52d3 ("selftests/bpf: Test tail call counting with bpf2bpf and data on stack")
+Signed-off-by: Leon Hwang <hffilwlqm@gmail.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://lore.kernel.org/r/20230906154256.95461-1-hffilwlqm@gmail.com
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/tailcalls.c      | 32 +++++++++----------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+index b7b9f28e1c3dd..28e30ad4a30e8 100644
+--- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c
++++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+@@ -272,11 +272,11 @@ static void test_tailcall_3(void)
+       data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
+       if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
+-              return;
++              goto out;
+       data_fd = bpf_map__fd(data_map);
+-      if (CHECK_FAIL(map_fd < 0))
+-              return;
++      if (CHECK_FAIL(data_fd < 0))
++              goto out;
+       i = 0;
+       err = bpf_map_lookup_elem(data_fd, &i, &val);
+@@ -334,11 +334,11 @@ static void test_tailcall_4(void)
+       data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
+       if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
+-              return;
++              goto out;
+       data_fd = bpf_map__fd(data_map);
+-      if (CHECK_FAIL(map_fd < 0))
+-              return;
++      if (CHECK_FAIL(data_fd < 0))
++              goto out;
+       for (i = 0; i < bpf_map__def(prog_array)->max_entries; i++) {
+               snprintf(prog_name, sizeof(prog_name), "classifier/%i", i);
+@@ -422,11 +422,11 @@ static void test_tailcall_5(void)
+       data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
+       if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
+-              return;
++              goto out;
+       data_fd = bpf_map__fd(data_map);
+-      if (CHECK_FAIL(map_fd < 0))
+-              return;
++      if (CHECK_FAIL(data_fd < 0))
++              goto out;
+       for (i = 0; i < bpf_map__def(prog_array)->max_entries; i++) {
+               snprintf(prog_name, sizeof(prog_name), "classifier/%i", i);
+@@ -610,11 +610,11 @@ static void test_tailcall_bpf2bpf_2(void)
+       data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
+       if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
+-              return;
++              goto out;
+       data_fd = bpf_map__fd(data_map);
+-      if (CHECK_FAIL(map_fd < 0))
+-              return;
++      if (CHECK_FAIL(data_fd < 0))
++              goto out;
+       i = 0;
+       err = bpf_map_lookup_elem(data_fd, &i, &val);
+@@ -783,11 +783,11 @@ static void test_tailcall_bpf2bpf_4(bool noise)
+       data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
+       if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
+-              return;
++              goto out;
+       data_fd = bpf_map__fd(data_map);
+-      if (CHECK_FAIL(map_fd < 0))
+-              return;
++      if (CHECK_FAIL(data_fd < 0))
++              goto out;
+       i = 0;
+       val.noise = noise;
+@@ -851,7 +851,7 @@ static void test_tailcall_bpf2bpf_6(void)
+       ASSERT_EQ(topts.retval, 0, "tailcall retval");
+       data_fd = bpf_map__fd(obj->maps.bss);
+-      if (!ASSERT_GE(map_fd, 0, "bss map fd"))
++      if (!ASSERT_GE(data_fd, 0, "bss map fd"))
+               goto out;
+       i = 0;
+-- 
+2.42.0
+
diff --git a/queue-5.15/selftests-bpf-test-tail-call-counting-with-bpf2bpf-a.patch b/queue-5.15/selftests-bpf-test-tail-call-counting-with-bpf2bpf-a.patch
new file mode 100644 (file)
index 0000000..28bb297
--- /dev/null
@@ -0,0 +1,146 @@
+From 77b5a4342528531848fa52864d6ff0dde588a1cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 18:20:37 +0200
+Subject: selftests/bpf: Test tail call counting with bpf2bpf and data on stack
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit 5e0b0a4c52d30bb09659446f40b77a692361600d ]
+
+Cover the case when tail call count needs to be passed from BPF function to
+BPF function, and the caller has data on stack. Specifically when the size
+of data allocated on BPF stack is not a multiple on 8.
+
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20220616162037.535469-3-jakub@cloudflare.com
+Stable-dep-of: 96daa9874211 ("selftests/bpf: Correct map_fd to data_fd in tailcalls")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/tailcalls.c      | 55 +++++++++++++++++++
+ .../selftests/bpf/progs/tailcall_bpf2bpf6.c   | 42 ++++++++++++++
+ 2 files changed, 97 insertions(+)
+ create mode 100644 tools/testing/selftests/bpf/progs/tailcall_bpf2bpf6.c
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+index b5940e6ca67cb..b7b9f28e1c3dd 100644
+--- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c
++++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c
+@@ -810,6 +810,59 @@ static void test_tailcall_bpf2bpf_4(bool noise)
+       bpf_object__close(obj);
+ }
++#include "tailcall_bpf2bpf6.skel.h"
++
++/* Tail call counting works even when there is data on stack which is
++ * not aligned to 8 bytes.
++ */
++static void test_tailcall_bpf2bpf_6(void)
++{
++      struct tailcall_bpf2bpf6 *obj;
++      int err, map_fd, prog_fd, main_fd, data_fd, i, val;
++      LIBBPF_OPTS(bpf_test_run_opts, topts,
++              .data_in = &pkt_v4,
++              .data_size_in = sizeof(pkt_v4),
++              .repeat = 1,
++      );
++
++      obj = tailcall_bpf2bpf6__open_and_load();
++      if (!ASSERT_OK_PTR(obj, "open and load"))
++              return;
++
++      main_fd = bpf_program__fd(obj->progs.entry);
++      if (!ASSERT_GE(main_fd, 0, "entry prog fd"))
++              goto out;
++
++      map_fd = bpf_map__fd(obj->maps.jmp_table);
++      if (!ASSERT_GE(map_fd, 0, "jmp_table map fd"))
++              goto out;
++
++      prog_fd = bpf_program__fd(obj->progs.classifier_0);
++      if (!ASSERT_GE(prog_fd, 0, "classifier_0 prog fd"))
++              goto out;
++
++      i = 0;
++      err = bpf_map_update_elem(map_fd, &i, &prog_fd, BPF_ANY);
++      if (!ASSERT_OK(err, "jmp_table map update"))
++              goto out;
++
++      err = bpf_prog_test_run_opts(main_fd, &topts);
++      ASSERT_OK(err, "entry prog test run");
++      ASSERT_EQ(topts.retval, 0, "tailcall retval");
++
++      data_fd = bpf_map__fd(obj->maps.bss);
++      if (!ASSERT_GE(map_fd, 0, "bss map fd"))
++              goto out;
++
++      i = 0;
++      err = bpf_map_lookup_elem(data_fd, &i, &val);
++      ASSERT_OK(err, "bss map lookup");
++      ASSERT_EQ(val, 1, "done flag is set");
++
++out:
++      tailcall_bpf2bpf6__destroy(obj);
++}
++
+ void test_tailcalls(void)
+ {
+       if (test__start_subtest("tailcall_1"))
+@@ -832,4 +885,6 @@ void test_tailcalls(void)
+               test_tailcall_bpf2bpf_4(false);
+       if (test__start_subtest("tailcall_bpf2bpf_5"))
+               test_tailcall_bpf2bpf_4(true);
++      if (test__start_subtest("tailcall_bpf2bpf_6"))
++              test_tailcall_bpf2bpf_6();
+ }
+diff --git a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf6.c b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf6.c
+new file mode 100644
+index 0000000000000..41ce83da78e8b
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf6.c
+@@ -0,0 +1,42 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/bpf.h>
++#include <bpf/bpf_helpers.h>
++
++#define __unused __attribute__((unused))
++
++struct {
++      __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
++      __uint(max_entries, 1);
++      __uint(key_size, sizeof(__u32));
++      __uint(value_size, sizeof(__u32));
++} jmp_table SEC(".maps");
++
++int done = 0;
++
++SEC("tc")
++int classifier_0(struct __sk_buff *skb __unused)
++{
++      done = 1;
++      return 0;
++}
++
++static __noinline
++int subprog_tail(struct __sk_buff *skb)
++{
++      /* Don't propagate the constant to the caller */
++      volatile int ret = 1;
++
++      bpf_tail_call_static(skb, &jmp_table, 0);
++      return ret;
++}
++
++SEC("tc")
++int entry(struct __sk_buff *skb)
++{
++      /* Have data on stack which size is not a multiple of 8 */
++      volatile char arr[1] = {};
++
++      return subprog_tail(skb);
++}
++
++char __license[] SEC("license") = "GPL";
+-- 
+2.42.0
+
diff --git a/queue-5.15/selftests-pidfd-fix-ksft-print-formats.patch b/queue-5.15/selftests-pidfd-fix-ksft-print-formats.patch
new file mode 100644 (file)
index 0000000..6bf8c3d
--- /dev/null
@@ -0,0 +1,102 @@
+From 26cca3cb737c6bf3a9956c7157705f24f08505ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Oct 2023 13:36:28 +0200
+Subject: selftests/pidfd: Fix ksft print formats
+
+From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
+
+[ Upstream commit 4d7f4e8158b62f63031510cdc24acc520956c091 ]
+
+Compiling pidfd selftest after adding a __printf() attribute to
+ksft_print_msg() and ksft_test_result_pass() exposes -Wformat warnings
+in error_report(), test_pidfd_poll_exec_thread(),
+child_poll_exec_test(), test_pidfd_poll_leader_exit_thread(),
+child_poll_leader_exit_test().
+
+The ksft_test_result_pass() in error_report() expects a string but
+doesn't provide any argument after the format string. All the other
+calls to ksft_print_msg() in the functions mentioned above have format
+strings that don't match with other passed arguments.
+
+Fix format specifiers so they match the passed variables.
+
+Add a missing variable to ksft_test_result_pass() inside
+error_report() so it matches other cases in the switch statement.
+
+Fixes: 2def297ec7fb ("pidfd: add tests for NSpid info in fdinfo")
+
+Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/pidfd/pidfd_fdinfo_test.c |  2 +-
+ tools/testing/selftests/pidfd/pidfd_test.c        | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
+index 3fd8e903118f5..3bc46d6151f44 100644
+--- a/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
++++ b/tools/testing/selftests/pidfd/pidfd_fdinfo_test.c
+@@ -62,7 +62,7 @@ static void error_report(struct error *err, const char *test_name)
+               break;
+       case PIDFD_PASS:
+-              ksft_test_result_pass("%s test: Passed\n");
++              ksft_test_result_pass("%s test: Passed\n", test_name);
+               break;
+       default:
+diff --git a/tools/testing/selftests/pidfd/pidfd_test.c b/tools/testing/selftests/pidfd/pidfd_test.c
+index 9a2d64901d591..79f543ad394c2 100644
+--- a/tools/testing/selftests/pidfd/pidfd_test.c
++++ b/tools/testing/selftests/pidfd/pidfd_test.c
+@@ -380,13 +380,13 @@ static int test_pidfd_send_signal_syscall_support(void)
+ static void *test_pidfd_poll_exec_thread(void *priv)
+ {
+-      ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
++      ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
+                       getpid(), syscall(SYS_gettid));
+       ksft_print_msg("Child Thread: doing exec of sleep\n");
+       execl("/bin/sleep", "sleep", str(CHILD_THREAD_MIN_WAIT), (char *)NULL);
+-      ksft_print_msg("Child Thread: DONE. pid %d tid %d\n",
++      ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n",
+                       getpid(), syscall(SYS_gettid));
+       return NULL;
+ }
+@@ -426,7 +426,7 @@ static int child_poll_exec_test(void *args)
+ {
+       pthread_t t1;
+-      ksft_print_msg("Child (pidfd): starting. pid %d tid %d\n", getpid(),
++      ksft_print_msg("Child (pidfd): starting. pid %d tid %ld\n", getpid(),
+                       syscall(SYS_gettid));
+       pthread_create(&t1, NULL, test_pidfd_poll_exec_thread, NULL);
+       /*
+@@ -477,10 +477,10 @@ static void test_pidfd_poll_exec(int use_waitpid)
+ static void *test_pidfd_poll_leader_exit_thread(void *priv)
+ {
+-      ksft_print_msg("Child Thread: starting. pid %d tid %d ; and sleeping\n",
++      ksft_print_msg("Child Thread: starting. pid %d tid %ld ; and sleeping\n",
+                       getpid(), syscall(SYS_gettid));
+       sleep(CHILD_THREAD_MIN_WAIT);
+-      ksft_print_msg("Child Thread: DONE. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
++      ksft_print_msg("Child Thread: DONE. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
+       return NULL;
+ }
+@@ -489,7 +489,7 @@ static int child_poll_leader_exit_test(void *args)
+ {
+       pthread_t t1, t2;
+-      ksft_print_msg("Child: starting. pid %d tid %d\n", getpid(), syscall(SYS_gettid));
++      ksft_print_msg("Child: starting. pid %d tid %ld\n", getpid(), syscall(SYS_gettid));
+       pthread_create(&t1, NULL, test_pidfd_poll_leader_exit_thread, NULL);
+       pthread_create(&t2, NULL, test_pidfd_poll_leader_exit_thread, NULL);
+-- 
+2.42.0
+
diff --git a/queue-5.15/selftests-resctrl-ensure-the-benchmark-commands-fits.patch b/queue-5.15/selftests-resctrl-ensure-the-benchmark-commands-fits.patch
new file mode 100644 (file)
index 0000000..fabefe3
--- /dev/null
@@ -0,0 +1,55 @@
+From 955fee01b3b81a9193909804e6c64f481679c2b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:53:32 +0300
+Subject: selftests/resctrl: Ensure the benchmark commands fits to its array
+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 4a28c7665c2a1ac0400864eabb0c641e135f61aa ]
+
+Benchmark command is copied into an array in the stack. The array is
+BENCHMARK_ARGS items long but the command line could try to provide a
+longer command. Argument size is also fixed by BENCHMARK_ARG_SIZE (63
+bytes of space after fitting the terminating \0 character) and user
+could have inputted argument longer than that.
+
+Return error in case the benchmark command does not fit to the space
+allocated for it.
+
+Fixes: ecdbb911f22d ("selftests/resctrl: Add MBM test")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/resctrl_tests.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 3e7cdf1125df4..e9895ebd2a2d0 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -224,9 +224,14 @@ int main(int argc, char **argv)
+               return ksft_exit_fail_msg("Not running as root, abort testing.\n");
+       if (has_ben) {
++              if (argc - ben_ind >= BENCHMARK_ARGS)
++                      ksft_exit_fail_msg("Too long benchmark command.\n");
++
+               /* Extract benchmark command from command line. */
+               for (i = ben_ind; i < argc; i++) {
+                       benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
++                      if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE)
++                              ksft_exit_fail_msg("Too long benchmark command argument.\n");
+                       sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
+               }
+               benchmark_cmd[ben_count] = NULL;
+-- 
+2.42.0
+
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bd3d51018377eecefcc8b26b96c0731e798c5492 100644 (file)
@@ -0,0 +1,231 @@
+iov_iter-x86-be-consistent-about-the-__user-tag-on-c.patch
+sched-uclamp-ignore-util-0-optimization-in-feec-when.patch
+sched-fix-stop_one_cpu_nowait-vs-hotplug.patch
+vfs-fix-readahead-2-on-block-devices.patch
+writeback-cgroup-switch-inodes-with-dirty-timestamps.patch
+x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch
+futex-don-t-include-process-mm-in-futex-key-on-no-mm.patch
+x86-share-definition-of-__is_canonical_address.patch
+x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch
+x86-boot-fix-incorrect-startup_gdt_descr.size.patch
+pstore-platform-add-check-for-kstrdup.patch
+genirq-matrix-exclude-managed-interrupts-in-irq_matr.patch
+i40e-fix-potential-memory-leaks-in-i40e_remove.patch
+selftests-bpf-test-tail-call-counting-with-bpf2bpf-a.patch
+selftests-bpf-correct-map_fd-to-data_fd-in-tailcalls.patch
+wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch
+udp-add-missing-write_once-around-up-encap_rcv.patch
+tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch
+gve-use-size_add-in-call-to-struct_size.patch
+mlxsw-use-size_mul-in-call-to-struct_size.patch
+tipc-use-size_add-in-calls-to-struct_size.patch
+net-spider_net-use-size_add-in-call-to-struct_size.patch
+wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch
+wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch
+mt76-dma-use-kzalloc-instead-of-devm_kzalloc-for-txw.patch
+mt76-add-support-for-overriding-the-device-used-for-.patch
+mt76-pass-original-queue-id-from-__mt76_tx_queue_skb.patch
+wifi-mt76-mt7603-improve-stuck-beacon-handling.patch
+tcp_metrics-add-missing-barriers-on-delete.patch
+tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch
+tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch
+wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch
+can-dev-can_restart-don-t-crash-kernel-if-carrier-is.patch
+can-dev-can_restart-fix-race-condition-between-contr.patch
+can-dev-can_put_echo_skb-don-t-crash-kernel-if-can_p.patch
+pm-devfreq-rockchip-dfi-make-pmu-regmap-mandatory.patch
+netfilter-nf_tables-drop-pointless-memset-when-dumpi.patch
+thermal-core-prevent-potential-string-overflow.patch
+r8169-use-tp_to_dev-instead-of-open-code.patch
+r8169-fix-rare-issue-with-broken-rx-after-link-down-.patch
+chtls-fix-tp-rcv_tstamp-initialization.patch
+tcp-fix-cookie_init_timestamp-overflows.patch
+iwlwifi-pcie-adjust-to-bz-completion-descriptor.patch
+wifi-iwlwifi-call-napi_synchronize-before-freeing-rx.patch
+wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch
+iwlwifi-remove-contact-information.patch
+wifi-iwlwifi-empty-overflow-queue-during-flush.patch
+acpi-sysfs-fix-create_pnp_modalias-and-create_of_mod.patch
+ipv6-avoid-atomic-fragment-on-gso-packets.patch
+net-add-dev_stats_read-helper.patch
+ipvlan-properly-track-tx_errors.patch
+regmap-debugfs-fix-a-erroneous-check-after-snprintf.patch
+spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch
+clk-qcom-gcc-msm8996-use-array_size-instead-of-speci.patch
+clk-qcom-gcc-msm8996-drop-unsupported-clock-sources.patch
+clk-qcom-gcc-msm8996-move-clock-parent-tables-down.patch
+clk-qcom-gcc-msm8996-use-parent_hws-_data-instead-of.patch
+clk-qcom-gcc-msm8996-remove-rpm-bus-clocks.patch
+clk-qcom-clk-rcg2-fix-clock-rate-overflow-for-high-p.patch
+clk-qcom-mmcc-msm8998-don-t-check-halt-bit-on-some-b.patch
+clk-qcom-mmcc-msm8998-fix-the-smmu-gdsc.patch
+clk-qcom-gcc-sm8150-fix-gcc_sdcc2_apps_clk_src.patch
+clk-imx-select-mxc_clk-for-clk_imx8qxp.patch
+clk-imx-imx8mq-correct-error-handling-path.patch
+clk-imx-imx8qxp-fix-elcdif_pll-clock.patch
+clk-renesas-rzg2l-simplify-multiplication-shift-logi.patch
+clk-renesas-rzg2l-use-field_get-for-pll-register-fie.patch
+clk-renesas-rzg2l-fix-computation-formula.patch
+spi-nxp-fspi-use-the-correct-ioremap-function.patch
+clk-keystone-pll-fix-a-couple-null-vs-is_err-checks.patch
+clk-ti-add-ti_dt_clk_name-helper-to-use-clock-output.patch
+clk-ti-update-pll-and-clockdomain-clocks-to-use-ti_d.patch
+clk-ti-update-component-clocks-to-use-ti_dt_clk_name.patch
+clk-ti-change-ti_clk_register-_omap_hw-api.patch
+clk-ti-fix-double-free-in-of_ti_divider_clk_setup.patch
+clk-npcm7xx-fix-incorrect-kfree.patch
+clk-mediatek-clk-mt6765-add-check-for-mtk_alloc_clk_.patch
+clk-mediatek-clk-mt6779-add-check-for-mtk_alloc_clk_.patch
+clk-mediatek-clk-mt6797-add-check-for-mtk_alloc_clk_.patch
+clk-mediatek-clk-mt7629-eth-add-check-for-mtk_alloc_.patch
+clk-mediatek-clk-mt7629-add-check-for-mtk_alloc_clk_.patch
+clk-mediatek-clk-mt2701-add-check-for-mtk_alloc_clk_.patch
+clk-qcom-config-ipq_apss_6018-should-depend-on-qcom_.patch
+platform-x86-wmi-fix-probe-failure-when-failing-to-r.patch
+platform-x86-wmi-remove-unnecessary-initializations.patch
+platform-x86-wmi-fix-opening-of-char-device.patch
+hwmon-axi-fan-control-fix-possible-null-pointer-dere.patch
+hwmon-coretemp-fix-potentially-truncated-sysfs-attri.patch
+drm-rockchip-vop-fix-reset-of-state-in-duplicate-sta.patch
+drm-rockchip-vop-fix-call-to-crtc-reset-helper.patch
+drm-radeon-possible-buffer-overflow.patch
+drm-mipi-dsi-create-devm-device-registration.patch
+drm-mipi-dsi-create-devm-device-attachment.patch
+drm-bridge-lt8912b-switch-to-devm-mipi-dsi-helpers.patch
+drm-bridge-lt8912b-register-and-attach-our-dsi-devic.patch
+drm-bridge-lt8912b-add-hot-plug-detection.patch
+drm-bridge-lt8912b-fix-bridge_detach.patch
+drm-bridge-lt8912b-fix-crash-on-bridge-detach.patch
+drm-bridge-lt8912b-manually-disable-hpd-only-if-it-w.patch
+drm-bridge-lt8912b-add-missing-drm_bridge_attach-cal.patch
+drm-bridge-tc358768-fix-use-of-uninitialized-variabl.patch
+drm-bridge-tc358768-disable-non-continuous-clock-mod.patch
+drm-bridge-tc358768-fix-bit-updates.patch
+drm-amdkfd-fix-some-race-conditions-in-vram-buffer-a.patch
+drm-mediatek-fix-iommu-fault-by-swapping-fbs-after-u.patch
+drm-mediatek-fix-iommu-fault-during-crtc-enabling.patch
+drm-rockchip-cdn-dp-fix-some-error-handling-paths-in.patch
+drm-bridge-lt9611uxc-switch-to-devm-mipi-dsi-helpers.patch
+drm-bridge-lt9611uxc-register-and-attach-our-dsi-dev.patch
+drm-bridge-lt9611uxc-fix-the-race-in-the-error-path.patch
+arm64-arm-xen-enlighten-fix-kpti-checks.patch
+drm-rockchip-fix-type-promotion-bug-in-rockchip_gem_.patch
+xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch
+drm-msm-dsi-use-msm_gem_kernel_put-to-free-tx-buffer.patch
+drm-mediatek-mtk_dsi-fix-no_eot_packet-settings-hand.patch
+perf-hisi-fix-use-after-free-when-register-pmu-fails.patch
+arm-dts-renesas-blanche-fix-typo-in-gp_11_2-pin-name.patch
+arm64-dts-qcom-msm8916-fix-iommu-local-address-range.patch
+arm64-dts-qcom-msm8992-libra-drop-duplicated-reserve.patch
+arm64-dts-qcom-sc7280-add-missing-lmh-interrupts.patch
+arm64-dts-qcom-sdm845-mtp-fix-wifi-configuration.patch
+arm64-dts-marvell-cn9310-use-appropriate-label-for-s.patch
+arm64-dts-qcom-apq8016-sbc-add-missing-adv7533-regul.patch
+arm-dts-qcom-mdm9615-populate-vsdcc-fixed-regulator.patch
+soc-qcom-llcc-handle-a-second-device-without-data-co.patch
+firmware-ti_sci-mark-driver-as-non-removable.patch
+firmware-arm_ffa-assign-the-missing-idr-allocation-i.patch
+clk-scmi-free-scmi_clk-allocated-when-the-clocks-wit.patch
+arm64-dts-imx8qm-ss-img-fix-jpegenc-compatible-entry.patch
+arm64-dts-imx8mm-add-sound-dai-cells-to-micfil-node.patch
+arm64-dts-imx8mn-add-sound-dai-cells-to-micfil-node.patch
+selftests-pidfd-fix-ksft-print-formats.patch
+selftests-resctrl-ensure-the-benchmark-commands-fits.patch
+crypto-hisilicon-hpre-fix-a-erroneous-check-after-sn.patch
+hwrng-geode-fix-accessing-registers.patch
+rdma-core-use-size_-add-sub-mul-in-calls-to-struct_s.patch
+scsi-ibmvfc-fix-erroneous-use-of-rtas_busy_delay-wit.patch
+libnvdimm-of_pmem-use-devm_kstrdup-instead-of-kstrdu.patch
+nd_btt-make-btt-lanes-preemptible.patch
+crypto-caam-qi2-fix-chacha20-poly1305-self-test-fail.patch
+crypto-caam-jr-fix-chacha20-poly1305-self-test-failu.patch
+crypto-qat-increase-size-of-buffers.patch
+hid-cp2112-fix-duplicate-workqueue-initialization.patch
+arm-9321-1-memset-cast-the-constant-byte-to-unsigned.patch
+ext4-move-ix-sanity-check-to-corrent-position.patch
+asoc-fsl-mpc5200_dma.c-fix-warning-of-function-param.patch
+ib-mlx5-fix-rdma-counter-binding-for-raw-qp.patch
+rdma-hns-fix-uninitialized-ucmd-in-hns_roce_create_q.patch
+rdma-hns-fix-signed-unsigned-mixed-comparisons.patch
+rdma-hns-the-ud-mode-can-only-be-configured-with-dcq.patch
+asoc-fsl-fix-pm-disable-depth-imbalance-in-fsl_easrc.patch
+scsi-ufs-core-leave-space-for-0-in-utf8-desc-string.patch
+rdma-hfi1-workaround-truncation-compilation-error.patch
+gpio-don-t-fiddle-with-irqchips-marked-as-immutable.patch
+gpio-expose-the-gpiochip_irq_re-ql-res-helpers.patch
+gpio-add-helpers-to-ease-the-transition-towards-immu.patch
+hid-cp2112-make-irq_chip-immutable.patch
+hid-cp2112-fix-irq-shutdown-stopping-polling-for-all.patch
+sh-bios-revive-earlyprintk-support.patch
+revert-hid-logitech-hidpp-add-a-module-parameter-to-.patch
+hid-logitech-hidpp-remove-hidpp_quirk_no_hidinput-qu.patch
+hid-logitech-hidpp-don-t-restart-io-instead-defer-hi.patch
+hid-logitech-hidpp-revert-don-t-restart-communicatio.patch
+hid-logitech-hidpp-move-get_wireless_feature_index-c.patch
+asoc-intel-skylake-fix-mem-leak-when-parsing-uuids-f.patch
+padata-fix-refcnt-handling-in-padata_free_shell.patch
+crypto-qat-fix-deadlock-in-backlog-processing.patch
+asoc-ams-delta.c-use-component-after-check.patch
+mfd-core-un-constify-mfd_cell.of_reg.patch
+mfd-core-ensure-disabled-devices-are-skipped-without.patch
+mfd-dln2-fix-double-put-in-dln2_probe.patch
+mfd-arizona-spi-set-pdata.hpdet_channel-for-acpi-enu.patch
+leds-turris-omnia-drop-unnecessary-mutex-locking.patch
+leds-turris-omnia-do-not-use-smbus-calls.patch
+leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch
+leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch
+f2fs-introduce-memory-mode.patch
+f2fs-handle-decompress-only-post-processing-in-softi.patch
+f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch
+f2fs-compress-fix-to-avoid-redundant-compress-extens.patch
+tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch
+livepatch-fix-missing-newline-character-in-klp_resol.patch
+perf-evlist-add-evlist__add_dummy_on_all_cpus.patch
+perf-tools-get-rid-of-evlist__add_on_all_cpus.patch
+perf-evlist-avoid-frequency-mode-for-the-dummy-event.patch
+dmaengine-idxd-register-dsa_bus_type-before-register.patch
+usb-dwc2-fix-possible-null-pointer-dereference-cause.patch
+usb-chipidea-fix-dma-overwrite-for-tegra.patch
+usb-chipidea-simplify-tegra-dma-alignment-code.patch
+dmaengine-ti-edma-handle-irq_of_parse_and_map-errors.patch
+misc-st_core-do-not-call-kfree_skb-under-spin_lock_i.patch
+tools-iio-iio_generic_buffer-ensure-alignment.patch
+usb-usbip-fix-stub_dev-hub-disconnect.patch
+dmaengine-pxa_dma-remove-an-erroneous-bug_on-in-pxad.patch
+f2fs-fix-to-initialize-map.m_pblk-in-f2fs_precache_e.patch
+powerpc-only-define-__parse_fpscr-when-required.patch
+modpost-fix-tee-module_device_table-built-on-big-end.patch
+powerpc-40x-remove-stale-pte_atomic_updates-macro.patch
+powerpc-xive-fix-endian-conversion-size.patch
+powerpc-imc-pmu-use-the-correct-spinlock-initializer.patch
+powerpc-pseries-fix-potential-memory-leak-in-init_cp.patch
+xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch
+usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch
+perf-machine-avoid-out-of-bounds-lbr-memory-read.patch
+perf-hist-add-missing-puts-to-hist__account_cycles.patch
+9p-net-fix-possible-memory-leak-in-p9_check_errors.patch
+i3c-fix-potential-refcount-leak-in-i3c_master_regist.patch
+cxl-pci-make-struct-cxl_mem-device-type-generic.patch
+cxl-pci-clean-up-cxl_mem_get_partition_info.patch
+cxl-mbox-introduce-the-mbox_send-operation.patch
+cxl-pci-drop-idr.h.patch
+cxl-mbox-move-mailbox-and-other-non-pci-specific-inf.patch
+cxl-mem-fix-shutdown-order.patch
+rtc-pcf85363-fix-wrong-mask-val-parameters-in-regmap.patch
+pcmcia-cs-fix-possible-hung-task-and-memory-leak-pcc.patch
+pcmcia-ds-fix-refcount-leak-in-pcmcia_device_add.patch
+pcmcia-ds-fix-possible-name-leak-in-error-path-in-pc.patch
+media-i2c-max9286-fix-some-redundant-of_node_put-cal.patch
+media-bttv-fix-use-after-free-error-due-to-btv-timeo.patch
+media-s3c-camif-avoid-inappropriate-kfree.patch
+media-vidtv-psi-add-check-for-kstrdup.patch
+media-vidtv-mux-add-check-and-kfree-for-kstrdup.patch
+media-cedrus-fix-clock-reset-sequence.patch
+media-rcar-vin-refactor-controls-creation-for-video-.patch
+media-rcar-vin-improve-async-notifier-cleanup-paths.patch
+media-rcar-vin-rename-array-storing-subdevice-inform.patch
+media-rcar-vin-move-group-async-notifier.patch
+media-v4l-async-rename-async-nf-functions-clean-up-l.patch
+media-cadence-csi2rx-unregister-v4l2-async-notifier.patch
+media-dvb-usb-v2-af9035-fix-missing-unlock.patch
+regmap-prevent-noinc-writes-from-clobbering-cache.patch
diff --git a/queue-5.15/sh-bios-revive-earlyprintk-support.patch b/queue-5.15/sh-bios-revive-earlyprintk-support.patch
new file mode 100644 (file)
index 0000000..052f7e8
--- /dev/null
@@ -0,0 +1,52 @@
+From 5f5603f7a36845d0b7a7ff9579c5b377a7741fd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Oct 2023 11:46:43 +0200
+Subject: sh: bios: Revive earlyprintk support
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 553f7ac78fbb41b2c93ab9b9d78e42274d27daa9 ]
+
+The SuperH BIOS earlyprintk code is protected by CONFIG_EARLY_PRINTK.
+However, when this protection was added, it was missed that SuperH no
+longer defines an EARLY_PRINTK config symbol since commit
+e76fe57447e88916 ("sh: Remove old early serial console code V2"), so
+BIOS earlyprintk can no longer be used.
+
+Fix this by reviving the EARLY_PRINTK config symbol.
+
+Fixes: d0380e6c3c0f6edb ("early_printk: consolidate random copies of identical code")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Link: https://lore.kernel.org/r/c40972dfec3dcc6719808d5df388857360262878.1697708489.git.geert+renesas@glider.be
+Signed-off-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sh/Kconfig.debug | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
+index c449e7c1b20ff..8bcd6c1431a95 100644
+--- a/arch/sh/Kconfig.debug
++++ b/arch/sh/Kconfig.debug
+@@ -22,6 +22,17 @@ config STACK_DEBUG
+         every function call and will therefore incur a major
+         performance hit. Most users should say N.
++config EARLY_PRINTK
++      bool "Early printk"
++      depends on SH_STANDARD_BIOS
++      help
++        Say Y here to redirect kernel printk messages to the serial port
++        used by the SH-IPL bootloader, starting very early in the boot
++        process and ending when the kernel's serial console is initialised.
++        This option is only useful while porting the kernel to a new machine,
++        when the kernel may crash or hang before the serial console is
++        initialised.  If unsure, say N.
++
+ config 4KSTACKS
+       bool "Use 4Kb for kernel stacks instead of 8Kb"
+       depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB
+-- 
+2.42.0
+
diff --git a/queue-5.15/soc-qcom-llcc-handle-a-second-device-without-data-co.patch b/queue-5.15/soc-qcom-llcc-handle-a-second-device-without-data-co.patch
new file mode 100644 (file)
index 0000000..384d9ee
--- /dev/null
@@ -0,0 +1,42 @@
+From 7f47cdd199a68ad3bbf04fec0b990e40892e0cad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 10:32:29 +0200
+Subject: soc: qcom: llcc: Handle a second device without data corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit f1a1bc8775b26345aba2be278118999e7f661d3d ]
+
+Usually there is only one llcc device. But if there were a second, even
+a failed probe call would modify the global drv_data pointer. So check
+if drv_data is valid before overwriting it.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Fixes: a3134fb09e0b ("drivers: soc: Add LLCC driver")
+Link: https://lore.kernel.org/r/20230926083229.2073890-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/llcc-qcom.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 47d41804fdf67..fabc5ce828af3 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -537,6 +537,9 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+       u32 sz;
+       u32 version;
++      if (!IS_ERR(drv_data))
++              return -EBUSY;
++
+       drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
+       if (!drv_data) {
+               ret = -ENOMEM;
+-- 
+2.42.0
+
diff --git a/queue-5.15/spi-nxp-fspi-use-the-correct-ioremap-function.patch b/queue-5.15/spi-nxp-fspi-use-the-correct-ioremap-function.patch
new file mode 100644 (file)
index 0000000..4483ab7
--- /dev/null
@@ -0,0 +1,38 @@
+From 4a6264aa637e6b8cae9ab9297a9738a610bfbbe3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Oct 2023 15:15:24 -0500
+Subject: spi: nxp-fspi: use the correct ioremap function
+
+From: Han Xu <han.xu@nxp.com>
+
+[ Upstream commit c3aa5cb264a38ae9bbcce32abca4c155af0456df ]
+
+AHB memory as MMIO should be mapped with ioremap rather than ioremap_wc,
+which should have been used initially just to handle unaligned access as
+a workaround.
+
+Fixes: d166a73503ef ("spi: fspi: dynamically alloc AHB memory")
+Signed-off-by: Han Xu <han.xu@nxp.com>
+Link: https://lore.kernel.org/r/20231010201524.2021340-1-han.xu@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-nxp-fspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
+index 23e4c30e6a60a..45961249c976e 100644
+--- a/drivers/spi/spi-nxp-fspi.c
++++ b/drivers/spi/spi-nxp-fspi.c
+@@ -708,7 +708,7 @@ static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
+               f->memmap_len = len > NXP_FSPI_MIN_IOMAP ?
+                               len : NXP_FSPI_MIN_IOMAP;
+-              f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start,
++              f->ahb_addr = ioremap(f->memmap_phy + f->memmap_start,
+                                        f->memmap_len);
+               if (!f->ahb_addr) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch b/queue-5.15/spi-tegra-fix-missing-irq-check-in-tegra_slink_probe.patch
new file mode 100644 (file)
index 0000000..9902c13
--- /dev/null
@@ -0,0 +1,41 @@
+From 5b2c41ee1809edfa8dd1602343fb0f2a0aad77a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Aug 2023 18:02:54 +0800
+Subject: spi: tegra: Fix missing IRQ check in tegra_slink_probe()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit eb9913b511f10968a02cfa5329a896855dd152a3 ]
+
+This func misses checking for platform_get_irq()'s call and may passes the
+negative error codes to request_irq(), which takes unsigned IRQ #,
+causing it to fail with -EINVAL, overriding an original error code.
+
+Fix this by stop calling request_irq() with invalid IRQ #s.
+
+Fixes: dc4dc3605639 ("spi: tegra: add spi driver for SLINK controller")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Reviewed-by: Helen Koike <helen.koike@collabora.com>
+Link: https://lore.kernel.org/r/tencent_73FCC06A3D1C14EE5175253C6FB46A07B709@qq.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra20-slink.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
+index cf61bf302a059..c611fedda7de9 100644
+--- a/drivers/spi/spi-tegra20-slink.c
++++ b/drivers/spi/spi-tegra20-slink.c
+@@ -1087,6 +1087,8 @@ static int tegra_slink_probe(struct platform_device *pdev)
+       reset_control_deassert(tspi->rst);
+       spi_irq = platform_get_irq(pdev, 0);
++      if (spi_irq < 0)
++              return spi_irq;
+       tspi->irq = spi_irq;
+       ret = request_threaded_irq(tspi->irq, tegra_slink_isr,
+                                  tegra_slink_isr_thread, IRQF_ONESHOT,
+-- 
+2.42.0
+
diff --git a/queue-5.15/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch b/queue-5.15/tcp-call-tcp_try_undo_recovery-when-an-rtod-tfo-syna.patch
new file mode 100644 (file)
index 0000000..4624572
--- /dev/null
@@ -0,0 +1,71 @@
+From d9021c6cfc3509d3da7704eb68d927f1df9f450c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 14:36:20 +0000
+Subject: tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed
+
+From: Aananth V <aananthv@google.com>
+
+[ Upstream commit e326578a21414738de45f77badd332fb00bd0f58 ]
+
+For passive TCP Fast Open sockets that had SYN/ACK timeout and did not
+send more data in SYN_RECV, upon receiving the final ACK in 3WHS, the
+congestion state may awkwardly stay in CA_Loss mode unless the CA state
+was undone due to TCP timestamp checks. However, if
+tcp_rcv_synrecv_state_fastopen() decides not to undo, then we should
+enter CA_Open, because at that point we have received an ACK covering
+the retransmitted SYNACKs. Currently, the icsk_ca_state is only set to
+CA_Open after we receive an ACK for a data-packet. This is because
+tcp_ack does not call tcp_fastretrans_alert (and tcp_process_loss) if
+!prior_packets
+
+Note that tcp_process_loss() calls tcp_try_undo_recovery(), so having
+tcp_rcv_synrecv_state_fastopen() decide that if we're in CA_Loss we
+should call tcp_try_undo_recovery() is consistent with that, and
+low risk.
+
+Fixes: dad8cea7add9 ("tcp: fix TFO SYNACK undo to avoid double-timestamp-undo")
+Signed-off-by: Aananth V <aananthv@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 8e4b42d394bed..a3453b4ac339c 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -6376,22 +6376,23 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
+ static void tcp_rcv_synrecv_state_fastopen(struct sock *sk)
+ {
++      struct tcp_sock *tp = tcp_sk(sk);
+       struct request_sock *req;
+       /* If we are still handling the SYNACK RTO, see if timestamp ECR allows
+        * undo. If peer SACKs triggered fast recovery, we can't undo here.
+        */
+-      if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss)
+-              tcp_try_undo_loss(sk, false);
++      if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out)
++              tcp_try_undo_recovery(sk);
+       /* Reset rtx states to prevent spurious retransmits_timed_out() */
+-      tcp_sk(sk)->retrans_stamp = 0;
++      tp->retrans_stamp = 0;
+       inet_csk(sk)->icsk_retransmits = 0;
+       /* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1,
+        * we no longer need req so release it.
+        */
+-      req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk,
++      req = rcu_dereference_protected(tp->fastopen_rsk,
+                                       lockdep_sock_is_held(sk));
+       reqsk_fastopen_remove(sk, req, false);
+-- 
+2.42.0
+
diff --git a/queue-5.15/tcp-fix-cookie_init_timestamp-overflows.patch b/queue-5.15/tcp-fix-cookie_init_timestamp-overflows.patch
new file mode 100644 (file)
index 0000000..a03cef4
--- /dev/null
@@ -0,0 +1,102 @@
+From cd5bb3844366e4f6ef3c63785007bc85f8e78c5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Oct 2023 12:57:37 +0000
+Subject: tcp: fix cookie_init_timestamp() overflows
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 73ed8e03388d16c12fc577e5c700b58a29045a15 ]
+
+cookie_init_timestamp() is supposed to return a 64bit timestamp
+suitable for both TSval determination and setting of skb->tstamp.
+
+Unfortunately it uses 32bit fields and overflows after
+2^32 * 10^6 nsec (~49 days) of uptime.
+
+Generated TSval are still correct, but skb->tstamp might be set
+far away in the past, potentially confusing other layers.
+
+tcp_ns_to_ts() is changed to return a full 64bit value,
+ts and ts_now variables are changed to u64 type,
+and TSMASK is removed in favor of shifts operations.
+
+While we are at it, change this sequence:
+               ts >>= TSBITS;
+               ts--;
+               ts <<= TSBITS;
+               ts |= options;
+to:
+               ts -= (1UL << TSBITS);
+
+Fixes: 9a568de4818d ("tcp: switch TCP TS option (RFC 7323) to 1ms clock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h     |  2 +-
+ net/ipv4/syncookies.c | 20 +++++++-------------
+ 2 files changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 3aee02ad0116b..fe9fc568b2888 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -786,7 +786,7 @@ static inline u32 tcp_time_stamp(const struct tcp_sock *tp)
+ }
+ /* Convert a nsec timestamp into TCP TSval timestamp (ms based currently) */
+-static inline u32 tcp_ns_to_ts(u64 ns)
++static inline u64 tcp_ns_to_ts(u64 ns)
+ {
+       return div_u64(ns, NSEC_PER_SEC / TCP_TS_HZ);
+ }
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 3aab914eb1039..03b0505178f9a 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -43,7 +43,6 @@ static siphash_key_t syncookie_secret[2] __read_mostly;
+  * requested/supported by the syn/synack exchange.
+  */
+ #define TSBITS        6
+-#define TSMASK        (((__u32)1 << TSBITS) - 1)
+ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
+                      u32 count, int c)
+@@ -64,27 +63,22 @@ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
+  */
+ u64 cookie_init_timestamp(struct request_sock *req, u64 now)
+ {
+-      struct inet_request_sock *ireq;
+-      u32 ts, ts_now = tcp_ns_to_ts(now);
++      const struct inet_request_sock *ireq = inet_rsk(req);
++      u64 ts, ts_now = tcp_ns_to_ts(now);
+       u32 options = 0;
+-      ireq = inet_rsk(req);
+-
+       options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK;
+       if (ireq->sack_ok)
+               options |= TS_OPT_SACK;
+       if (ireq->ecn_ok)
+               options |= TS_OPT_ECN;
+-      ts = ts_now & ~TSMASK;
++      ts = (ts_now >> TSBITS) << TSBITS;
+       ts |= options;
+-      if (ts > ts_now) {
+-              ts >>= TSBITS;
+-              ts--;
+-              ts <<= TSBITS;
+-              ts |= options;
+-      }
+-      return (u64)ts * (NSEC_PER_SEC / TCP_TS_HZ);
++      if (ts > ts_now)
++              ts -= (1UL << TSBITS);
++
++      return ts * (NSEC_PER_SEC / TCP_TS_HZ);
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/tcp_metrics-add-missing-barriers-on-delete.patch b/queue-5.15/tcp_metrics-add-missing-barriers-on-delete.patch
new file mode 100644 (file)
index 0000000..6dba3ce
--- /dev/null
@@ -0,0 +1,47 @@
+From fce31316e4b550cc8672727e129b28d0fb4f8079 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 22:03:53 +0000
+Subject: tcp_metrics: add missing barriers on delete
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit cbc3a153222805d65f821e10f4f78b6afce06f86 ]
+
+When removing an item from RCU protected list, we must prevent
+store-tearing, using rcu_assign_pointer() or WRITE_ONCE().
+
+Fixes: 04f721c671656 ("tcp_metrics: Rewrite tcp_metrics_flush_all")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_metrics.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 5df97aaac252e..0275bf7570b4c 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -908,7 +908,7 @@ static void tcp_metrics_flush_all(struct net *net)
+                       match = net ? net_eq(tm_net(tm), net) :
+                               !refcount_read(&tm_net(tm)->ns.count);
+                       if (match) {
+-                              *pp = tm->tcpm_next;
++                              rcu_assign_pointer(*pp, tm->tcpm_next);
+                               kfree_rcu(tm, rcu_head);
+                       } else {
+                               pp = &tm->tcpm_next;
+@@ -949,7 +949,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
+               if (addr_same(&tm->tcpm_daddr, &daddr) &&
+                   (!src || addr_same(&tm->tcpm_saddr, &saddr)) &&
+                   net_eq(tm_net(tm), net)) {
+-                      *pp = tm->tcpm_next;
++                      rcu_assign_pointer(*pp, tm->tcpm_next);
+                       kfree_rcu(tm, rcu_head);
+                       found = true;
+               } else {
+-- 
+2.42.0
+
diff --git a/queue-5.15/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch b/queue-5.15/tcp_metrics-do-not-create-an-entry-from-tcp_init_met.patch
new file mode 100644 (file)
index 0000000..90c9a72
--- /dev/null
@@ -0,0 +1,39 @@
+From 420dc90fe28f010a1da43274d71055c403080e5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 22:03:55 +0000
+Subject: tcp_metrics: do not create an entry from tcp_init_metrics()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a135798e6e200ecb2f864cecca6d257ba278370c ]
+
+tcp_init_metrics() only wants to get metrics if they were
+previously stored in the cache. Creating an entry is adding
+useless costs, especially when tcp_no_metrics_save is set.
+
+Fixes: 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_metrics.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 940f75df19358..def337f72c860 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -478,7 +478,7 @@ void tcp_init_metrics(struct sock *sk)
+               goto reset;
+       rcu_read_lock();
+-      tm = tcp_get_metrics(sk, dst, true);
++      tm = tcp_get_metrics(sk, dst, false);
+       if (!tm) {
+               rcu_read_unlock();
+               goto reset;
+-- 
+2.42.0
+
diff --git a/queue-5.15/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch b/queue-5.15/tcp_metrics-properly-set-tp-snd_ssthresh-in-tcp_init.patch
new file mode 100644 (file)
index 0000000..b11ba93
--- /dev/null
@@ -0,0 +1,52 @@
+From 1fb52480f7dc4a585d4960194fd0dc276f683d48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Sep 2023 22:03:54 +0000
+Subject: tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 081480014a64a69d901f8ef1ffdd56d6085cf87e ]
+
+We need to set tp->snd_ssthresh to TCP_INFINITE_SSTHRESH
+in the case tcp_get_metrics() fails for some reason.
+
+Fixes: 9ad7c049f0f7 ("tcp: RFC2988bis + taking RTT sample from 3WHS for the passive open side")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_metrics.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 0275bf7570b4c..940f75df19358 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -470,6 +470,10 @@ void tcp_init_metrics(struct sock *sk)
+       u32 val, crtt = 0; /* cached RTT scaled by 8 */
+       sk_dst_confirm(sk);
++      /* ssthresh may have been reduced unnecessarily during.
++       * 3WHS. Restore it back to its initial default.
++       */
++      tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+       if (!dst)
+               goto reset;
+@@ -489,11 +493,6 @@ void tcp_init_metrics(struct sock *sk)
+               tp->snd_ssthresh = val;
+               if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
+                       tp->snd_ssthresh = tp->snd_cwnd_clamp;
+-      } else {
+-              /* ssthresh may have been reduced unnecessarily during.
+-               * 3WHS. Restore it back to its initial default.
+-               */
+-              tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+       }
+       val = tcp_metric_get(tm, TCP_METRIC_REORDERING);
+       if (val && tp->reordering != val)
+-- 
+2.42.0
+
diff --git a/queue-5.15/thermal-core-prevent-potential-string-overflow.patch b/queue-5.15/thermal-core-prevent-potential-string-overflow.patch
new file mode 100644 (file)
index 0000000..6d815af
--- /dev/null
@@ -0,0 +1,47 @@
+From 021b8603e7b5364da65b188690f275f7e8fe072e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Oct 2023 11:59:39 +0300
+Subject: thermal: core: prevent potential string overflow
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit c99626092efca3061b387043d4a7399bf75fbdd5 ]
+
+The dev->id value comes from ida_alloc() so it's a number between zero
+and INT_MAX.  If it's too high then these sprintf()s will overflow.
+
+Fixes: 203d3d4aa482 ("the generic thermal sysfs driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 052e8e8fbb21e..ce748e03e4331 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -671,7 +671,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
+       if (result)
+               goto release_ida;
+-      sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
++      snprintf(dev->attr_name, sizeof(dev->attr_name), "cdev%d_trip_point",
++               dev->id);
+       sysfs_attr_init(&dev->attr.attr);
+       dev->attr.attr.name = dev->attr_name;
+       dev->attr.attr.mode = 0444;
+@@ -680,7 +681,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
+       if (result)
+               goto remove_symbol_link;
+-      sprintf(dev->weight_attr_name, "cdev%d_weight", dev->id);
++      snprintf(dev->weight_attr_name, sizeof(dev->weight_attr_name),
++               "cdev%d_weight", dev->id);
+       sysfs_attr_init(&dev->weight_attr.attr);
+       dev->weight_attr.attr.name = dev->weight_attr_name;
+       dev->weight_attr.attr.mode = S_IWUSR | S_IRUGO;
+-- 
+2.42.0
+
diff --git a/queue-5.15/tipc-use-size_add-in-calls-to-struct_size.patch b/queue-5.15/tipc-use-size_add-in-calls-to-struct_size.patch
new file mode 100644 (file)
index 0000000..5dad8f0
--- /dev/null
@@ -0,0 +1,48 @@
+From 11b6cb694766a9f679c6dd5037e08d675cbb83cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 13:16:26 -0600
+Subject: tipc: Use size_add() in calls to struct_size()
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 2506a91734754de690869824fb0d1ac592ec1266 ]
+
+If, for any reason, the open-coded arithmetic causes a wraparound,
+the protection that `struct_size()` adds against potential integer
+overflows is defeated. Fix this by hardening call to `struct_size()`
+with `size_add()`.
+
+Fixes: e034c6d23bc4 ("tipc: Use struct_size() helper")
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/link.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/tipc/link.c b/net/tipc/link.c
+index 655a2e1b6dfe4..d13a85b9cdb2d 100644
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -1445,7 +1445,7 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l,
+               p = (struct tipc_gap_ack_blks *)msg_data(hdr);
+               sz = ntohs(p->len);
+               /* Sanity check */
+-              if (sz == struct_size(p, gacks, p->ugack_cnt + p->bgack_cnt)) {
++              if (sz == struct_size(p, gacks, size_add(p->ugack_cnt, p->bgack_cnt))) {
+                       /* Good, check if the desired type exists */
+                       if ((uc && p->ugack_cnt) || (!uc && p->bgack_cnt))
+                               goto ok;
+@@ -1532,7 +1532,7 @@ static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr)
+                       __tipc_build_gap_ack_blks(ga, l, ga->bgack_cnt) : 0;
+       /* Total len */
+-      len = struct_size(ga, gacks, ga->bgack_cnt + ga->ugack_cnt);
++      len = struct_size(ga, gacks, size_add(ga->bgack_cnt, ga->ugack_cnt));
+       ga->len = htons(len);
+       return len;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/tools-iio-iio_generic_buffer-ensure-alignment.patch b/queue-5.15/tools-iio-iio_generic_buffer-ensure-alignment.patch
new file mode 100644 (file)
index 0000000..4135985
--- /dev/null
@@ -0,0 +1,65 @@
+From b82cf78c2f77bcdf6586f25ab6e05730161f2c60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Oct 2023 12:57:47 +0300
+Subject: tools: iio: iio_generic_buffer ensure alignment
+
+From: Matti Vaittinen <mazziesaccount@gmail.com>
+
+[ Upstream commit 2d3dff577dd0ea8fe9637a13822f7603c4a881c8 ]
+
+The iio_generic_buffer can return garbage values when the total size of
+scan data is not a multiple of the largest element in the scan. This can be
+demonstrated by reading a scan, consisting, for example of one 4-byte and
+one 2-byte element, where the 4-byte element is first in the buffer.
+
+The IIO generic buffer code does not take into account the last two
+padding bytes that are needed to ensure that the 4-byte data for next
+scan is correctly aligned.
+
+Add the padding bytes required to align the next sample with the scan size.
+
+Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Fixes: e58537ccce73 ("staging: iio: update example application.")
+Link: https://lore.kernel.org/r/ZRvlm4ktNLu+qmlf@dc78bmyyyyyyyyyyyyydt-3.rev.dnainternet.fi
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/iio/iio_generic_buffer.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
+index 44bbf80f0cfdd..0d0a7a19d6f95 100644
+--- a/tools/iio/iio_generic_buffer.c
++++ b/tools/iio/iio_generic_buffer.c
+@@ -54,9 +54,12 @@ enum autochan {
+ static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
+ {
+       unsigned int bytes = 0;
+-      int i = 0;
++      int i = 0, max = 0;
++      unsigned int misalignment;
+       while (i < num_channels) {
++              if (channels[i].bytes > max)
++                      max = channels[i].bytes;
+               if (bytes % channels[i].bytes == 0)
+                       channels[i].location = bytes;
+               else
+@@ -66,6 +69,14 @@ static unsigned int size_from_channelarray(struct iio_channel_info *channels, in
+               bytes = channels[i].location + channels[i].bytes;
+               i++;
+       }
++      /*
++       * We want the data in next sample to also be properly aligned so
++       * we'll add padding at the end if needed. Adding padding only
++       * works for channel data which size is 2^n bytes.
++       */
++      misalignment = bytes % max;
++      if (misalignment)
++              bytes += max - misalignment;
+       return bytes;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch b/queue-5.15/tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch
new file mode 100644 (file)
index 0000000..48b652d
--- /dev/null
@@ -0,0 +1,117 @@
+From 53981e27429c5077c12c761c7621818010d57f74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 10:33:29 +0800
+Subject: tty: tty_jobctrl: fix pid memleak in disassociate_ctty()
+
+From: Yi Yang <yiyang13@huawei.com>
+
+[ Upstream commit 11e7f27b79757b6586645d87b95d5b78375ecdfc ]
+
+There is a pid leakage:
+------------------------------
+unreferenced object 0xffff88810c181940 (size 224):
+  comm "sshd", pid 8191, jiffies 4294946950 (age 524.570s)
+  hex dump (first 32 bytes):
+    01 00 00 00 00 00 00 00 00 00 00 00 ad 4e ad de  .............N..
+    ff ff ff ff 6b 6b 6b 6b ff ff ff ff ff ff ff ff  ....kkkk........
+  backtrace:
+    [<ffffffff814774e6>] kmem_cache_alloc+0x5c6/0x9b0
+    [<ffffffff81177342>] alloc_pid+0x72/0x570
+    [<ffffffff81140ac4>] copy_process+0x1374/0x2470
+    [<ffffffff81141d77>] kernel_clone+0xb7/0x900
+    [<ffffffff81142645>] __se_sys_clone+0x85/0xb0
+    [<ffffffff8114269b>] __x64_sys_clone+0x2b/0x30
+    [<ffffffff83965a72>] do_syscall_64+0x32/0x80
+    [<ffffffff83a00085>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+It turns out that there is a race condition between disassociate_ctty() and
+tty_signal_session_leader(), which caused this leakage.
+
+The pid memleak is triggered by the following race:
+task[sshd]                     task[bash]
+-----------------------        -----------------------
+                               disassociate_ctty();
+                               spin_lock_irq(&current->sighand->siglock);
+                               put_pid(current->signal->tty_old_pgrp);
+                               current->signal->tty_old_pgrp = NULL;
+                               tty = tty_kref_get(current->signal->tty);
+                               spin_unlock_irq(&current->sighand->siglock);
+tty_vhangup();
+tty_lock(tty);
+...
+tty_signal_session_leader();
+spin_lock_irq(&p->sighand->siglock);
+...
+if (tty->ctrl.pgrp) //tty->ctrl.pgrp is not NULL
+p->signal->tty_old_pgrp = get_pid(tty->ctrl.pgrp); //An extra get
+spin_unlock_irq(&p->sighand->siglock);
+...
+tty_unlock(tty);
+                               if (tty) {
+                                   tty_lock(tty);
+                                   ...
+                                   put_pid(tty->ctrl.pgrp);
+                                   tty->ctrl.pgrp = NULL; //It's too late
+                                   ...
+                                   tty_unlock(tty);
+                               }
+
+The issue is believed to be introduced by commit c8bcd9c5be24 ("tty:
+Fix ->session locking") who moves the unlock of siglock in
+disassociate_ctty() above "if (tty)", making a small window allowing
+tty_signal_session_leader() to kick in. It can be easily reproduced by
+adding a delay before "if (tty)" and at the entrance of
+tty_signal_session_leader().
+
+To fix this issue, we move "put_pid(current->signal->tty_old_pgrp)" after
+"tty->ctrl.pgrp = NULL".
+
+Fixes: c8bcd9c5be24 ("tty: Fix ->session locking")
+Signed-off-by: Yi Yang <yiyang13@huawei.com>
+Co-developed-by: GUO Zihua <guozihua@huawei.com>
+Signed-off-by: GUO Zihua <guozihua@huawei.com>
+Link: https://lore.kernel.org/r/20230831023329.165737-1-yiyang13@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_jobctrl.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c
+index 80b86a7992b50..8ede78488c5b0 100644
+--- a/drivers/tty/tty_jobctrl.c
++++ b/drivers/tty/tty_jobctrl.c
+@@ -300,12 +300,7 @@ void disassociate_ctty(int on_exit)
+               return;
+       }
+-      spin_lock_irq(&current->sighand->siglock);
+-      put_pid(current->signal->tty_old_pgrp);
+-      current->signal->tty_old_pgrp = NULL;
+-      tty = tty_kref_get(current->signal->tty);
+-      spin_unlock_irq(&current->sighand->siglock);
+-
++      tty = get_current_tty();
+       if (tty) {
+               unsigned long flags;
+@@ -320,6 +315,16 @@ void disassociate_ctty(int on_exit)
+               tty_kref_put(tty);
+       }
++      /* If tty->ctrl.pgrp is not NULL, it may be assigned to
++       * current->signal->tty_old_pgrp in a race condition, and
++       * cause pid memleak. Release current->signal->tty_old_pgrp
++       * after tty->ctrl.pgrp set to NULL.
++       */
++      spin_lock_irq(&current->sighand->siglock);
++      put_pid(current->signal->tty_old_pgrp);
++      current->signal->tty_old_pgrp = NULL;
++      spin_unlock_irq(&current->sighand->siglock);
++
+       /* Now clear signal->tty under the lock */
+       read_lock(&tasklist_lock);
+       session_clear_tty(task_session(current));
+-- 
+2.42.0
+
diff --git a/queue-5.15/udp-add-missing-write_once-around-up-encap_rcv.patch b/queue-5.15/udp-add-missing-write_once-around-up-encap_rcv.patch
new file mode 100644 (file)
index 0000000..839d46b
--- /dev/null
@@ -0,0 +1,43 @@
+From 4fa35740ebd4b5ba6682f8337655b8e954afd6be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 09:17:25 +0000
+Subject: udp: add missing WRITE_ONCE() around up->encap_rcv
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 6d5a12eb91224d707f8691dccb40a5719fe5466d ]
+
+UDP_ENCAP_ESPINUDP_NON_IKE setsockopt() writes over up->encap_rcv
+while other cpus read it.
+
+Fixes: 067b207b281d ("[UDP]: Cleanup UDP encapsulation code")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 198d8e07413d3..c454daa78a2f8 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2711,10 +2711,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
+               case UDP_ENCAP_ESPINUDP_NON_IKE:
+ #if IS_ENABLED(CONFIG_IPV6)
+                       if (sk->sk_family == AF_INET6)
+-                              up->encap_rcv = ipv6_stub->xfrm6_udp_encap_rcv;
++                              WRITE_ONCE(up->encap_rcv,
++                                         ipv6_stub->xfrm6_udp_encap_rcv);
+                       else
+ #endif
+-                              up->encap_rcv = xfrm4_udp_encap_rcv;
++                              WRITE_ONCE(up->encap_rcv,
++                                         xfrm4_udp_encap_rcv);
+ #endif
+                       fallthrough;
+               case UDP_ENCAP_L2TPINUDP:
+-- 
+2.42.0
+
diff --git a/queue-5.15/usb-chipidea-fix-dma-overwrite-for-tegra.patch b/queue-5.15/usb-chipidea-fix-dma-overwrite-for-tegra.patch
new file mode 100644 (file)
index 0000000..c06be15
--- /dev/null
@@ -0,0 +1,102 @@
+From a7585e98da4b84f04295759e4587280593f4b1e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 23:06:03 +0200
+Subject: usb: chipidea: Fix DMA overwrite for Tegra
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 7ab8716713c931ac79988f2592e1cf8b2e4fec1b ]
+
+Tegra USB controllers seem to issue DMA in full 32-bit words only and thus
+may overwrite unevenly-sized buffers.  One such occurrence is detected by
+SLUB when receiving a reply to a 1-byte buffer (below).  Fix this by
+allocating a bounce buffer also for buffers with sizes not a multiple of 4.
+
+=============================================================================
+BUG kmalloc-64 (Tainted: G    B             ): kmalloc Redzone overwritten
+-----------------------------------------------------------------------------
+
+0x8555cd02-0x8555cd03 @offset=3330. First byte 0x0 instead of 0xcc
+Allocated in usb_get_status+0x2b/0xac age=1 cpu=3 pid=41
+ __kmem_cache_alloc_node+0x12f/0x1e4
+ __kmalloc+0x33/0x8c
+ usb_get_status+0x2b/0xac
+ hub_probe+0x5e9/0xcec
+ usb_probe_interface+0xbf/0x21c
+ really_probe+0xa5/0x2c4
+ __driver_probe_device+0x75/0x174
+ driver_probe_device+0x31/0x94
+ __device_attach_driver+0x65/0xc0
+ bus_for_each_drv+0x4b/0x74
+ __device_attach+0x69/0x120
+ bus_probe_device+0x65/0x6c
+ device_add+0x48b/0x5f8
+ usb_set_configuration+0x37b/0x6b4
+ usb_generic_driver_probe+0x37/0x68
+ usb_probe_device+0x35/0xb4
+Slab 0xbf622b80 objects=21 used=18 fp=0x8555cdc0 flags=0x800(slab|zone=0)
+Object 0x8555cd00 @offset=3328 fp=0x00000000
+
+Redzone  8555ccc0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Redzone  8555ccd0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Redzone  8555cce0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Redzone  8555ccf0: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Object   8555cd00: 01 00 00 00 cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Object   8555cd10: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Object   8555cd20: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Object   8555cd30: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
+Redzone  8555cd40: cc cc cc cc                                      ....
+Padding  8555cd74: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a              ZZZZZZZZZZZZ
+CPU: 3 PID: 41 Comm: kworker/3:1 Tainted: G    B              6.6.0-rc1mq-00118-g59786f827ea1 #1115
+Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
+Workqueue: usb_hub_wq hub_event
+[<8010ca28>] (unwind_backtrace) from [<801090a5>] (show_stack+0x11/0x14)
+[<801090a5>] (show_stack) from [<805da2fb>] (dump_stack_lvl+0x4d/0x7c)
+[<805da2fb>] (dump_stack_lvl) from [<8026464f>] (check_bytes_and_report+0xb3/0xe4)
+[<8026464f>] (check_bytes_and_report) from [<802648e1>] (check_object+0x261/0x290)
+[<802648e1>] (check_object) from [<802671b1>] (free_to_partial_list+0x105/0x3f8)
+[<802671b1>] (free_to_partial_list) from [<80268613>] (__kmem_cache_free+0x103/0x128)
+[<80268613>] (__kmem_cache_free) from [<80425a67>] (usb_get_status+0x73/0xac)
+[<80425a67>] (usb_get_status) from [<80421b31>] (hub_probe+0x5e9/0xcec)
+[<80421b31>] (hub_probe) from [<80428bbb>] (usb_probe_interface+0xbf/0x21c)
+[<80428bbb>] (usb_probe_interface) from [<803ee13d>] (really_probe+0xa5/0x2c4)
+[<803ee13d>] (really_probe) from [<803ee3d1>] (__driver_probe_device+0x75/0x174)
+[<803ee3d1>] (__driver_probe_device) from [<803ee501>] (driver_probe_device+0x31/0x94)
+usb 1-1: device descriptor read/8, error -71
+
+Fixes: fc53d5279094 ("usb: chipidea: tegra: Support host mode")
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/ef8466b834c1726f5404c95c3e192e90460146f8.1695934946.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/host.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
+index bdc3885c0d493..de1e7a4322ada 100644
+--- a/drivers/usb/chipidea/host.c
++++ b/drivers/usb/chipidea/host.c
+@@ -403,12 +403,13 @@ static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
+       const unsigned int ci_hdrc_usb_dma_align = 32;
+       size_t kmalloc_size;
+-      if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0 ||
+-          !((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)))
++      if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0)
++              return 0;
++      if (!((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)) && !(urb->transfer_buffer_length & 3))
+               return 0;
+       /* Allocate a buffer with enough padding for alignment */
+-      kmalloc_size = urb->transfer_buffer_length +
++      kmalloc_size = ALIGN(urb->transfer_buffer_length, 4) +
+                      sizeof(struct ci_hdrc_dma_aligned_buffer) +
+                      ci_hdrc_usb_dma_align - 1;
+-- 
+2.42.0
+
diff --git a/queue-5.15/usb-chipidea-simplify-tegra-dma-alignment-code.patch b/queue-5.15/usb-chipidea-simplify-tegra-dma-alignment-code.patch
new file mode 100644 (file)
index 0000000..147bdd1
--- /dev/null
@@ -0,0 +1,138 @@
+From ce3e3ad8261597a12d609dad27dda4bd3132cdfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 23:06:03 +0200
+Subject: usb: chipidea: Simplify Tegra DMA alignment code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+[ Upstream commit 2ae61a2562c0d1720545b0845829a65fb6a9c2c6 ]
+
+The USB host on Tegra3 works with 32-bit alignment. Previous code tried
+to align the buffer, but it did align the wrapper struct instead, so
+the buffer was at a constant offset of 8 bytes (two pointers) from
+expected alignment.  Since kmalloc() guarantees at least 8-byte
+alignment already, the alignment-extending is removed.
+
+Fixes: fc53d5279094 ("usb: chipidea: tegra: Support host mode")
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Link: https://lore.kernel.org/r/a0d917d492b1f91ee0019e68b8e8bca9c585393f.1695934946.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/host.c | 45 +++++++++++++++----------------------
+ 1 file changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
+index de1e7a4322ada..786ddb3c32899 100644
+--- a/drivers/usb/chipidea/host.c
++++ b/drivers/usb/chipidea/host.c
+@@ -30,8 +30,7 @@ struct ehci_ci_priv {
+ };
+ struct ci_hdrc_dma_aligned_buffer {
+-      void *kmalloc_ptr;
+-      void *old_xfer_buffer;
++      void *original_buffer;
+       u8 data[];
+ };
+@@ -372,60 +371,52 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
+       return 0;
+ }
+-static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb)
++static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back)
+ {
+       struct ci_hdrc_dma_aligned_buffer *temp;
+-      size_t length;
+       if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
+               return;
++      urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
+       temp = container_of(urb->transfer_buffer,
+                           struct ci_hdrc_dma_aligned_buffer, data);
++      urb->transfer_buffer = temp->original_buffer;
++
++      if (copy_back && usb_urb_dir_in(urb)) {
++              size_t length;
+-      if (usb_urb_dir_in(urb)) {
+               if (usb_pipeisoc(urb->pipe))
+                       length = urb->transfer_buffer_length;
+               else
+                       length = urb->actual_length;
+-              memcpy(temp->old_xfer_buffer, temp->data, length);
++              memcpy(temp->original_buffer, temp->data, length);
+       }
+-      urb->transfer_buffer = temp->old_xfer_buffer;
+-      kfree(temp->kmalloc_ptr);
+-      urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
++      kfree(temp);
+ }
+ static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
+ {
+-      struct ci_hdrc_dma_aligned_buffer *temp, *kmalloc_ptr;
+-      const unsigned int ci_hdrc_usb_dma_align = 32;
+-      size_t kmalloc_size;
++      struct ci_hdrc_dma_aligned_buffer *temp;
+       if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0)
+               return 0;
+-      if (!((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)) && !(urb->transfer_buffer_length & 3))
++      if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4)
++          && IS_ALIGNED(urb->transfer_buffer_length, 4))
+               return 0;
+-      /* Allocate a buffer with enough padding for alignment */
+-      kmalloc_size = ALIGN(urb->transfer_buffer_length, 4) +
+-                     sizeof(struct ci_hdrc_dma_aligned_buffer) +
+-                     ci_hdrc_usb_dma_align - 1;
+-
+-      kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
+-      if (!kmalloc_ptr)
++      temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags);
++      if (!temp)
+               return -ENOMEM;
+-      /* Position our struct dma_aligned_buffer such that data is aligned */
+-      temp = PTR_ALIGN(kmalloc_ptr + 1, ci_hdrc_usb_dma_align) - 1;
+-      temp->kmalloc_ptr = kmalloc_ptr;
+-      temp->old_xfer_buffer = urb->transfer_buffer;
+       if (usb_urb_dir_out(urb))
+               memcpy(temp->data, urb->transfer_buffer,
+                      urb->transfer_buffer_length);
+-      urb->transfer_buffer = temp->data;
++      temp->original_buffer = urb->transfer_buffer;
++      urb->transfer_buffer = temp->data;
+       urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
+       return 0;
+@@ -442,7 +433,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+       ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+       if (ret)
+-              ci_hdrc_free_dma_aligned_buffer(urb);
++              ci_hdrc_free_dma_aligned_buffer(urb, false);
+       return ret;
+ }
+@@ -450,7 +441,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+ {
+       usb_hcd_unmap_urb_for_dma(hcd, urb);
+-      ci_hdrc_free_dma_aligned_buffer(urb);
++      ci_hdrc_free_dma_aligned_buffer(urb, true);
+ }
+ int ci_hdrc_host_init(struct ci_hdrc *ci)
+-- 
+2.42.0
+
diff --git a/queue-5.15/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch b/queue-5.15/usb-dwc2-fix-possible-null-pointer-dereference-cause.patch
new file mode 100644 (file)
index 0000000..583c386
--- /dev/null
@@ -0,0 +1,69 @@
+From dfa86a5a32e52280c0dfe2858e28e466ce4eb57a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 10:44:04 +0800
+Subject: usb: dwc2: fix possible NULL pointer dereference caused by driver
+ concurrency
+
+From: Jia-Ju Bai <baijiaju@buaa.edu.cn>
+
+[ Upstream commit ef307bc6ef04e8c1ea843231db58e3afaafa9fa6 ]
+
+In _dwc2_hcd_urb_enqueue(), "urb->hcpriv = NULL" is executed without
+holding the lock "hsotg->lock". In _dwc2_hcd_urb_dequeue():
+
+    spin_lock_irqsave(&hsotg->lock, flags);
+    ...
+       if (!urb->hcpriv) {
+               dev_dbg(hsotg->dev, "## urb->hcpriv is NULL ##\n");
+               goto out;
+       }
+    rc = dwc2_hcd_urb_dequeue(hsotg, urb->hcpriv); // Use urb->hcpriv
+    ...
+out:
+    spin_unlock_irqrestore(&hsotg->lock, flags);
+
+When _dwc2_hcd_urb_enqueue() and _dwc2_hcd_urb_dequeue() are
+concurrently executed, the NULL check of "urb->hcpriv" can be executed
+before "urb->hcpriv = NULL". After urb->hcpriv is NULL, it can be used
+in the function call to dwc2_hcd_urb_dequeue(), which can cause a NULL
+pointer dereference.
+
+This possible bug is found by an experimental static analysis tool
+developed by myself. This tool analyzes the locking APIs to extract
+function pairs that can be concurrently executed, and then analyzes the
+instructions in the paired functions to identify possible concurrency
+bugs including data races and atomicity violations. The above possible
+bug is reported, when my tool analyzes the source code of Linux 6.5.
+
+To fix this possible bug, "urb->hcpriv = NULL" should be executed with
+holding the lock "hsotg->lock". After using this patch, my tool never
+reports the possible bug, with the kernelconfiguration allyesconfig for
+x86_64. Because I have no associated hardware, I cannot test the patch
+in runtime testing, and just verify it according to the code logic.
+
+Fixes: 33ad261aa62b ("usb: dwc2: host: spinlock urb_enqueue")
+Signed-off-by: Jia-Ju Bai <baijiaju@buaa.edu.cn>
+Link: https://lore.kernel.org/r/20230926024404.832096-1-baijiaju@buaa.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc2/hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
+index 82322696b903b..d17a1dd6d0d93 100644
+--- a/drivers/usb/dwc2/hcd.c
++++ b/drivers/usb/dwc2/hcd.c
+@@ -4802,8 +4802,8 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+       if (qh_allocated && qh->channel && qh->channel->qh == qh)
+               qh->channel->qh = NULL;
+ fail2:
+-      spin_unlock_irqrestore(&hsotg->lock, flags);
+       urb->hcpriv = NULL;
++      spin_unlock_irqrestore(&hsotg->lock, flags);
+       kfree(qtd);
+ fail1:
+       if (qh_allocated) {
+-- 
+2.42.0
+
diff --git a/queue-5.15/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch b/queue-5.15/usb-host-xhci-plat-fix-possible-kernel-oops-while-re.patch
new file mode 100644 (file)
index 0000000..b4349a3
--- /dev/null
@@ -0,0 +1,80 @@
+From 1d6dc3db9e9b0ecc2fd795aac35e6b479386f6b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Oct 2023 13:29:23 +0300
+Subject: usb: host: xhci-plat: fix possible kernel oops while resuming
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit a5f928db59519a15e82ecba4ae3e7cbf5a44715a ]
+
+If this driver enables the xHC clocks while resuming from sleep, it calls
+clk_prepare_enable() without checking for errors and blithely goes on to
+read/write the xHC's registers -- which, with the xHC not being clocked,
+at least on ARM32 usually causes an imprecise external abort exceptions
+which cause kernel oops.  Currently, the chips for which the driver does
+the clock dance on suspend/resume seem to be the Broadcom STB SoCs, based
+on ARM32 CPUs, as it seems...
+
+Found by Linux Verification Center (linuxtesting.org) with the Svace static
+analysis tool.
+
+Fixes: 8bd954c56197 ("usb: host: xhci-plat: suspend and resume clocks")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20231019102924.2797346-19-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-plat.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index 972a44b2a7f12..e56a1fb9715a7 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -466,23 +466,38 @@ static int __maybe_unused xhci_plat_resume(struct device *dev)
+       int ret;
+       if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
+-              clk_prepare_enable(xhci->clk);
+-              clk_prepare_enable(xhci->reg_clk);
++              ret = clk_prepare_enable(xhci->clk);
++              if (ret)
++                      return ret;
++
++              ret = clk_prepare_enable(xhci->reg_clk);
++              if (ret) {
++                      clk_disable_unprepare(xhci->clk);
++                      return ret;
++              }
+       }
+       ret = xhci_priv_resume_quirk(hcd);
+       if (ret)
+-              return ret;
++              goto disable_clks;
+       ret = xhci_resume(xhci, 0);
+       if (ret)
+-              return ret;
++              goto disable_clks;
+       pm_runtime_disable(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+       return 0;
++
++disable_clks:
++      if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
++              clk_disable_unprepare(xhci->clk);
++              clk_disable_unprepare(xhci->reg_clk);
++      }
++
++      return ret;
+ }
+ static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
+-- 
+2.42.0
+
diff --git a/queue-5.15/usb-usbip-fix-stub_dev-hub-disconnect.patch b/queue-5.15/usb-usbip-fix-stub_dev-hub-disconnect.patch
new file mode 100644 (file)
index 0000000..05fc6c5
--- /dev/null
@@ -0,0 +1,46 @@
+From dd3452b179005743b4c2a4490a20b3d7d97b8f25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 11:28:10 +0200
+Subject: USB: usbip: fix stub_dev hub disconnect
+
+From: Jonas Blixt <jonas.blixt@actia.se>
+
+[ Upstream commit 97475763484245916735a1aa9a3310a01d46b008 ]
+
+If a hub is disconnected that has device(s) that's attached to the usbip layer
+the disconnect function might fail because it tries to release the port
+on an already disconnected hub.
+
+Fixes: 6080cd0e9239 ("staging: usbip: claim ports used by shared devices")
+Signed-off-by: Jonas Blixt <jonas.blixt@actia.se>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20230615092810.1215490-1-jonas.blixt@actia.se
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/usbip/stub_dev.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
+index 3c6d452e3bf40..4104eea03e806 100644
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -462,8 +462,13 @@ static void stub_disconnect(struct usb_device *udev)
+       /* release port */
+       rc = usb_hub_release_port(udev->parent, udev->portnum,
+                                 (struct usb_dev_state *) udev);
+-      if (rc) {
+-              dev_dbg(&udev->dev, "unable to release port\n");
++      /*
++       * NOTE: If a HUB disconnect triggered disconnect of the down stream
++       * device usb_hub_release_port will return -ENODEV so we can safely ignore
++       * that error here.
++       */
++      if (rc && (rc != -ENODEV)) {
++              dev_dbg(&udev->dev, "unable to release port (%i)\n", rc);
+               return;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/vfs-fix-readahead-2-on-block-devices.patch b/queue-5.15/vfs-fix-readahead-2-on-block-devices.patch
new file mode 100644 (file)
index 0000000..fd19067
--- /dev/null
@@ -0,0 +1,43 @@
+From 8ca31451a374146f5664b0f0ecac349b71459ccc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Oct 2023 20:57:04 -0500
+Subject: vfs: fix readahead(2) on block devices
+
+From: Reuben Hawkins <reubenhwk@gmail.com>
+
+[ Upstream commit 7116c0af4b8414b2f19fdb366eea213cbd9d91c2 ]
+
+Readahead was factored to call generic_fadvise.  That refactor added an
+S_ISREG restriction which broke readahead on block devices.
+
+In addition to S_ISREG, this change checks S_ISBLK to fix block device
+readahead.  There is no change in behavior with any file type besides block
+devices in this change.
+
+Fixes: 3d8f7615319b ("vfs: implement readahead(2) using POSIX_FADV_WILLNEED")
+Signed-off-by: Reuben Hawkins <reubenhwk@gmail.com>
+Link: https://lore.kernel.org/r/20231003015704.2415-1-reubenhwk@gmail.com
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/readahead.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mm/readahead.c b/mm/readahead.c
+index 41b75d76d36e1..a8f7e4e550f43 100644
+--- a/mm/readahead.c
++++ b/mm/readahead.c
+@@ -627,7 +627,8 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
+        */
+       ret = -EINVAL;
+       if (!f.file->f_mapping || !f.file->f_mapping->a_ops ||
+-          !S_ISREG(file_inode(f.file)->i_mode))
++          (!S_ISREG(file_inode(f.file)->i_mode) &&
++          !S_ISBLK(file_inode(f.file)->i_mode)))
+               goto out;
+       ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED);
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-iwlwifi-call-napi_synchronize-before-freeing-rx.patch b/queue-5.15/wifi-iwlwifi-call-napi_synchronize-before-freeing-rx.patch
new file mode 100644 (file)
index 0000000..97d2171
--- /dev/null
@@ -0,0 +1,100 @@
+From 5ee571844915fa6aee9cbffedf96b7fc018c4da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Apr 2023 15:47:26 +0300
+Subject: wifi: iwlwifi: call napi_synchronize() before freeing rx/tx queues
+
+From: Gregory Greenman <gregory.greenman@intel.com>
+
+[ Upstream commit 5af2bb3168db6b0af9988eb25cccf2e3bc4455e2 ]
+
+When rx/tx queues are being freed, on a different CPU there could be
+still rx flow running. Call napi_synchronize() to prevent such a race.
+
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Co-developed-by: Benjamin Berg <benjamin.berg@intel.com>
+Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
+Link: https://lore.kernel.org/r/20230416154301.5171ee44dcc1.Iff18718540da412e084e7d8266447d40730600ed@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 37fb29bd1f90 ("wifi: iwlwifi: pcie: synchronize IRQs before NAPI")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/intel/iwlwifi/pcie/internal.h |  1 +
+ drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 18 +++++++++++++++++-
+ .../wireless/intel/iwlwifi/pcie/trans-gen2.c   |  1 +
+ .../net/wireless/intel/iwlwifi/pcie/trans.c    |  1 +
+ 4 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+index 775ee03e5b128..74959de9d7002 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+@@ -480,6 +480,7 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans);
+ void iwl_pcie_rx_free(struct iwl_trans *trans);
+ void iwl_pcie_free_rbs_pool(struct iwl_trans *trans);
+ void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq);
++void iwl_pcie_rx_napi_sync(struct iwl_trans *trans);
+ void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority,
+                           struct iwl_rxq *rxq);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+index 74b4280221e0f..df201d40f6c95 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+ /*
+- * Copyright (C) 2003-2014, 2018-2022 Intel Corporation
++ * Copyright (C) 2003-2014, 2018-2023 Intel Corporation
+  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
+  * Copyright (C) 2016-2017 Intel Deutschland GmbH
+  */
+@@ -1050,6 +1050,22 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget)
+       return ret;
+ }
++void iwl_pcie_rx_napi_sync(struct iwl_trans *trans)
++{
++      struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
++      int i;
++
++      if (unlikely(!trans_pcie->rxq))
++              return;
++
++      for (i = 0; i < trans->num_rx_queues; i++) {
++              struct iwl_rxq *rxq = &trans_pcie->rxq[i];
++
++              if (rxq && rxq->napi.poll)
++                      napi_synchronize(&rxq->napi);
++      }
++}
++
+ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
+ {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+index a9c19be29e92e..69e2c2c98281f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -165,6 +165,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
+       if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+               IWL_DEBUG_INFO(trans,
+                              "DEVICE_ENABLED bit was set and is now cleared\n");
++              iwl_pcie_rx_napi_sync(trans);
+               iwl_txq_gen2_tx_free(trans);
+               iwl_pcie_rx_stop(trans);
+       }
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index 4456aef930cf4..337f26e725315 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -1197,6 +1197,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
+       if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+               IWL_DEBUG_INFO(trans,
+                              "DEVICE_ENABLED bit was set and is now cleared\n");
++              iwl_pcie_rx_napi_sync(trans);
+               iwl_pcie_tx_stop(trans);
+               iwl_pcie_rx_stop(trans);
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-iwlwifi-empty-overflow-queue-during-flush.patch b/queue-5.15/wifi-iwlwifi-empty-overflow-queue-during-flush.patch
new file mode 100644 (file)
index 0000000..d53a906
--- /dev/null
@@ -0,0 +1,169 @@
+From b06b261a4be64d97fef63f2490b947ba976a08ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Oct 2023 17:55:51 +0300
+Subject: wifi: iwlwifi: empty overflow queue during flush
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit 658939fc68d3241f9a0019e224cd7154438c23f2 ]
+
+If a TX queue has no space for new TX frames, the driver will keep
+these frames in the overflow queue, and during reclaim flow it
+will retry to send the frames from that queue.
+But if the reclaim flow was invoked from TX queue flush, we will also
+TX these frames, which is wrong as we don't want to TX anything
+after flush.
+This might also cause assert 0x125F when removing the queue,
+saying that the driver removes a non-empty queue
+Fix this by TXing the overflow queue's frames only if we are
+not in flush queue flow.
+
+Fixes: a44509805895 ("iwlwifi: move reclaim flows to the queue file")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20231022173519.caf06c8709d9.Ibf664ccb3f952e836f8fa461ea58fc08e5c46e88@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/dvm/tx.c    | 5 +++--
+ drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 7 ++++---
+ drivers/net/wireless/intel/iwlwifi/mvm/tx.c    | 4 ++--
+ drivers/net/wireless/intel/iwlwifi/queue/tx.c  | 9 +++++----
+ drivers/net/wireless/intel/iwlwifi/queue/tx.h  | 2 +-
+ 5 files changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+index 60a7b61d59aa3..ca1daec641c4f 100644
+--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+@@ -3,6 +3,7 @@
+  *
+  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+  * Copyright (C) 2019 Intel Corporation
++ * Copyright (C) 2023 Intel Corporation
+  *****************************************************************************/
+ #include <linux/kernel.h>
+@@ -1169,7 +1170,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)
+                       iwlagn_check_ratid_empty(priv, sta_id, tid);
+               }
+-              iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
++              iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs, false);
+               freed = 0;
+@@ -1315,7 +1316,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
+        * block-ack window (we assume that they've been successfully
+        * transmitted ... if not, it's too late anyway). */
+       iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn,
+-                        &reclaimed_skbs);
++                        &reclaimed_skbs, false);
+       IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
+                          "sta_id = %d\n",
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+index 8f0ff540f4398..a2919a32d7081 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+@@ -539,7 +539,7 @@ struct iwl_trans_ops {
+       int (*tx)(struct iwl_trans *trans, struct sk_buff *skb,
+                 struct iwl_device_tx_cmd *dev_cmd, int queue);
+       void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
+-                      struct sk_buff_head *skbs);
++                      struct sk_buff_head *skbs, bool is_flush);
+       void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr);
+@@ -1122,14 +1122,15 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
+ }
+ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
+-                                   int ssn, struct sk_buff_head *skbs)
++                                   int ssn, struct sk_buff_head *skbs,
++                                   bool is_flush)
+ {
+       if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
+               IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
+               return;
+       }
+-      trans->ops->reclaim(trans, queue, ssn, skbs);
++      trans->ops->reclaim(trans, queue, ssn, skbs, is_flush);
+ }
+ static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index 5304edd351db2..08dd227bad4b1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -1436,7 +1436,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
+       seq_ctl = le16_to_cpu(tx_resp->seq_ctl);
+       /* we can free until ssn % q.n_bd not inclusive */
+-      iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs);
++      iwl_trans_reclaim(mvm->trans, txq_id, ssn, &skbs, false);
+       while (!skb_queue_empty(&skbs)) {
+               struct sk_buff *skb = __skb_dequeue(&skbs);
+@@ -1781,7 +1781,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
+        * block-ack window (we assume that they've been successfully
+        * transmitted ... if not, it's too late anyway).
+        */
+-      iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs);
++      iwl_trans_reclaim(mvm->trans, txq, index, &reclaimed_skbs, is_flush);
+       skb_queue_walk(&reclaimed_skbs, skb) {
+               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+index 8522cdfc9e5d3..cd852b95d8125 100644
+--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+@@ -1520,7 +1520,7 @@ void iwl_txq_progress(struct iwl_txq *txq)
+ /* Frees buffers until index _not_ inclusive */
+ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
+-                   struct sk_buff_head *skbs)
++                   struct sk_buff_head *skbs, bool is_flush)
+ {
+       struct iwl_txq *txq = trans->txqs.txq[txq_id];
+       int tfd_num = iwl_txq_get_cmd_index(txq, ssn);
+@@ -1591,9 +1591,11 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
+       if (iwl_txq_space(trans, txq) > txq->low_mark &&
+           test_bit(txq_id, trans->txqs.queue_stopped)) {
+               struct sk_buff_head overflow_skbs;
++              struct sk_buff *skb;
+               __skb_queue_head_init(&overflow_skbs);
+-              skb_queue_splice_init(&txq->overflow_q, &overflow_skbs);
++              skb_queue_splice_init(&txq->overflow_q,
++                                    is_flush ? skbs : &overflow_skbs);
+               /*
+                * We are going to transmit from the overflow queue.
+@@ -1613,8 +1615,7 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
+                */
+               spin_unlock_bh(&txq->lock);
+-              while (!skb_queue_empty(&overflow_skbs)) {
+-                      struct sk_buff *skb = __skb_dequeue(&overflow_skbs);
++              while ((skb = __skb_dequeue(&overflow_skbs))) {
+                       struct iwl_device_tx_cmd *dev_cmd_ptr;
+                       dev_cmd_ptr = *(void **)((u8 *)skb->cb +
+diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.h b/drivers/net/wireless/intel/iwlwifi/queue/tx.h
+index 19178c88bb229..f488fc9f6b83e 100644
+--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.h
++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.h
+@@ -174,7 +174,7 @@ void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans,
+                                     struct iwl_txq *txq, u16 byte_cnt,
+                                     int num_tbs);
+ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
+-                   struct sk_buff_head *skbs);
++                   struct sk_buff_head *skbs, bool is_flush);
+ void iwl_txq_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr);
+ void iwl_trans_txq_freeze_timer(struct iwl_trans *trans, unsigned long txqs,
+                               bool freeze);
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch b/queue-5.15/wifi-iwlwifi-pcie-synchronize-irqs-before-napi.patch
new file mode 100644 (file)
index 0000000..fede7ea
--- /dev/null
@@ -0,0 +1,55 @@
+From d3102f071138f3aeaa76a38b5e1d64371320fce3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Oct 2023 12:16:43 +0300
+Subject: wifi: iwlwifi: pcie: synchronize IRQs before NAPI
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 37fb29bd1f90f16d1abc95c0e9f0ff8eec9829ad ]
+
+When we want to synchronize the NAPI, which was added in
+commit 5af2bb3168db ("wifi: iwlwifi: call napi_synchronize()
+before freeing rx/tx queues"), we also need to make sure we
+can't actually reschedule the NAPI. Yes, this happens while
+interrupts are disabled, but interrupts may still be running
+or pending. Also call iwl_pcie_synchronize_irqs() to ensure
+we won't reschedule the NAPI.
+
+Fixes: 4cf2f5904d97 ("iwlwifi: queue: avoid memory leak in reset flow")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20231017115047.a0f4104b479a.Id5c50a944f709092aa6256e32d8c63b2b8d8d3ac@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 1 +
+ drivers/net/wireless/intel/iwlwifi/pcie/trans.c      | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+index 69e2c2c98281f..1b25a6627e5c7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -165,6 +165,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
+       if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+               IWL_DEBUG_INFO(trans,
+                              "DEVICE_ENABLED bit was set and is now cleared\n");
++              iwl_pcie_synchronize_irqs(trans);
+               iwl_pcie_rx_napi_sync(trans);
+               iwl_txq_gen2_tx_free(trans);
+               iwl_pcie_rx_stop(trans);
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+index 337f26e725315..b7b2d28b3e436 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+@@ -1197,6 +1197,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
+       if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+               IWL_DEBUG_INFO(trans,
+                              "DEVICE_ENABLED bit was set and is now cleared\n");
++              iwl_pcie_synchronize_irqs(trans);
+               iwl_pcie_rx_napi_sync(trans);
+               iwl_pcie_tx_stop(trans);
+               iwl_pcie_rx_stop(trans);
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch b/queue-5.15/wifi-iwlwifi-use-fw-rate-for-non-data-frames.patch
new file mode 100644 (file)
index 0000000..dbbccec
--- /dev/null
@@ -0,0 +1,64 @@
+From e6fd3bc394c77358025424a510f61d5c0184e39b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 14:56:45 +0300
+Subject: wifi: iwlwifi: Use FW rate for non-data frames
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit 499d02790495958506a64f37ceda7e97345a50a8 ]
+
+Currently we are setting the rate in the tx cmd for
+mgmt frames (e.g. during connection establishment).
+This was problematic when sending mgmt frames in eSR mode,
+as we don't know what link this frame will be sent on
+(This is decided by the FW), so we don't know what is the
+lowest rate.
+Fix this by not setting the rate in tx cmd and rely
+on FW to choose the right one.
+Set rate only for injected frames with fixed rate,
+or when no sta is given.
+Also set for important frames (EAPOL etc.) the High Priority flag.
+
+Fixes: 055b22e770dd ("iwlwifi: mvm: Set Tx rate and flags when there is not station")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://lore.kernel.org/r/20230913145231.6c7e59620ee0.I6eaed3ccdd6dd62b9e664facc484081fc5275843@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index b127e0b527ce0..5304edd351db2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -479,16 +479,20 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
+                       flags |= IWL_TX_FLAGS_ENCRYPT_DIS;
+               /*
+-               * For data packets rate info comes from the fw. Only
+-               * set rate/antenna during connection establishment or in case
+-               * no station is given.
++               * For data and mgmt packets rate info comes from the fw. Only
++               * set rate/antenna for injected frames with fixed rate, or
++               * when no sta is given.
+                */
+-              if (!sta || !ieee80211_is_data(hdr->frame_control) ||
+-                  mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) {
++              if (unlikely(!sta ||
++                           info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
+                       flags |= IWL_TX_FLAGS_CMD_RATE;
+                       rate_n_flags =
+                               iwl_mvm_get_tx_rate_n_flags(mvm, info, sta,
+                                                           hdr->frame_control);
++              } else if (!ieee80211_is_data(hdr->frame_control) ||
++                         mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) {
++                      /* These are important frames */
++                      flags |= IWL_TX_FLAGS_HIGH_PRI;
+               }
+               if (mvm->trans->trans_cfg->device_family >=
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch b/queue-5.15/wifi-mt76-mt7603-improve-stuck-beacon-handling.patch
new file mode 100644 (file)
index 0000000..d5db2fd
--- /dev/null
@@ -0,0 +1,177 @@
+From 96730d9a1dcbb0718c555443e8b8a9d4875ecdd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 16:21:18 +0200
+Subject: wifi: mt76: mt7603: improve stuck beacon handling
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit 3176205933494bd184c6acd70e796c382bc729b5 ]
+
+Before preparing the new beacon, check the queue status, flush out all
+previous beacons and buffered multicast packets, then (if necessary)
+try to recover more gracefully from a stuck beacon condition by making a
+less invasive attempt at getting the MAC un-stuck.
+
+Fixes: c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt7603/beacon.c    | 76 ++++++++++++++-----
+ .../net/wireless/mediatek/mt76/mt7603/regs.h  |  5 ++
+ 2 files changed, 60 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+index e35e0a68c6e48..7fa6b0ed9d478 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+@@ -9,6 +9,23 @@ struct beacon_bc_data {
+       int count[MT7603_MAX_INTERFACES];
+ };
++static void
++mt7603_mac_stuck_beacon_recovery(struct mt7603_dev *dev)
++{
++      if (dev->beacon_check % 5 != 4)
++              return;
++
++      mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN);
++      mt76_set(dev, MT_SCH_4, MT_SCH_4_RESET);
++      mt76_clear(dev, MT_SCH_4, MT_SCH_4_RESET);
++      mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN);
++
++      mt76_set(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS);
++      mt76_set(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE);
++      mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_TX_DISABLE);
++      mt76_clear(dev, MT_WF_CFG_OFF_WOCCR, MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS);
++}
++
+ static void
+ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ {
+@@ -16,6 +33,8 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+       struct mt76_dev *mdev = &dev->mt76;
+       struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
+       struct sk_buff *skb = NULL;
++      u32 om_idx = mvif->idx;
++      u32 val;
+       if (!(mdev->beacon_mask & BIT(mvif->idx)))
+               return;
+@@ -24,20 +43,33 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+       if (!skb)
+               return;
+-      mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON],
+-                        MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
++      if (om_idx)
++              om_idx |= 0x10;
++      val = MT_DMA_FQCR0_BUSY | MT_DMA_FQCR0_MODE |
++              FIELD_PREP(MT_DMA_FQCR0_TARGET_BSS, om_idx) |
++              FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
++              FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8);
+       spin_lock_bh(&dev->ps_lock);
+-      mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY |
+-              FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) |
+-              FIELD_PREP(MT_DMA_FQCR0_TARGET_QID,
+-                         dev->mphy.q_tx[MT_TXQ_CAB]->hw_idx) |
+-              FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
+-              FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8));
+-      if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000))
++      mt76_wr(dev, MT_DMA_FQCR0, val |
++              FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BCN));
++      if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
+               dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
++              goto out;
++      }
++
++      mt76_wr(dev, MT_DMA_FQCR0, val |
++              FIELD_PREP(MT_DMA_FQCR0_TARGET_QID, MT_TX_HW_QUEUE_BMC));
++      if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000)) {
++              dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
++              goto out;
++      }
++      mt76_tx_queue_skb(dev, dev->mphy.q_tx[MT_TXQ_BEACON],
++                        MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
++
++out:
+       spin_unlock_bh(&dev->ps_lock);
+ }
+@@ -81,6 +113,18 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
+       data.dev = dev;
+       __skb_queue_head_init(&data.q);
++      /* Flush all previous CAB queue packets and beacons */
++      mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
++
++      mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false);
++      mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false);
++
++      if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > 0)
++              dev->beacon_check++;
++      else
++              dev->beacon_check = 0;
++      mt7603_mac_stuck_beacon_recovery(dev);
++
+       q = dev->mphy.q_tx[MT_TXQ_BEACON];
+       spin_lock_bh(&q->lock);
+       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+@@ -89,14 +133,9 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
+       mt76_queue_kick(dev, q);
+       spin_unlock_bh(&q->lock);
+-      /* Flush all previous CAB queue packets */
+-      mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
+-
+-      mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_CAB], false);
+-
+       mt76_csa_check(mdev);
+       if (mdev->csa_complete)
+-              goto out;
++              return;
+       q = dev->mphy.q_tx[MT_TXQ_CAB];
+       do {
+@@ -108,7 +147,7 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
+                skb_queue_len(&data.q) < 8);
+       if (skb_queue_empty(&data.q))
+-              goto out;
++              return;
+       for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
+               if (!data.tail[i])
+@@ -136,11 +175,6 @@ void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t)
+               MT_WF_ARB_CAB_START_BSSn(0) |
+               (MT_WF_ARB_CAB_START_BSS0n(1) *
+                ((1 << (MT7603_MAX_INTERFACES - 1)) - 1)));
+-
+-out:
+-      mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BEACON], false);
+-      if (dev->mphy.q_tx[MT_TXQ_BEACON]->queued > hweight8(mdev->beacon_mask))
+-              dev->beacon_check++;
+ }
+ void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
+index 3b901090b29c6..9b84db233aceb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h
+@@ -462,6 +462,11 @@ enum {
+ #define MT_WF_SEC_BASE                        0x21a00
+ #define MT_WF_SEC(ofs)                        (MT_WF_SEC_BASE + (ofs))
++#define MT_WF_CFG_OFF_BASE            0x21e00
++#define MT_WF_CFG_OFF(ofs)            (MT_WF_CFG_OFF_BASE + (ofs))
++#define MT_WF_CFG_OFF_WOCCR           MT_WF_CFG_OFF(0x004)
++#define MT_WF_CFG_OFF_WOCCR_TMAC_GC_DIS       BIT(4)
++
+ #define MT_SEC_SCR                    MT_WF_SEC(0x004)
+ #define MT_SEC_SCR_MASK_ORDER         GENMASK(1, 0)
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch b/queue-5.15/wifi-mt76-mt7603-rework-fix-rx-pse-hang-check.patch
new file mode 100644 (file)
index 0000000..8eb942e
--- /dev/null
@@ -0,0 +1,87 @@
+From 6682a4eabf184dc9531c06caa13c870603d23080 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 09:51:01 +0200
+Subject: wifi: mt76: mt7603: rework/fix rx pse hang check
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit baa19b2e4b7bbb509a7ca7939c8785477dcd40ee ]
+
+It turns out that the code in mt7603_rx_pse_busy() does not detect actual
+hardware hangs, it only checks for busy conditions in PSE.
+A reset should only be performed if these conditions are true and if there
+is no rx activity as well.
+Reset the counter whenever a rx interrupt occurs. In order to also deal with
+a fully loaded CPU that leaves interrupts disabled with continuous NAPI
+polling, also check for pending rx interrupts in the function itself.
+
+Fixes: c8846e101502 ("mt76: add driver for MT7603E and MT7628/7688")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7603/core.c  |  2 ++
+ .../net/wireless/mediatek/mt76/mt7603/mac.c   | 23 +++++++++++++------
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
+index 60a996b63c0c0..915b8349146af 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c
+@@ -42,11 +42,13 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance)
+       }
+       if (intr & MT_INT_RX_DONE(0)) {
++              dev->rx_pse_check = 0;
+               mt7603_irq_disable(dev, MT_INT_RX_DONE(0));
+               napi_schedule(&dev->mt76.napi[0]);
+       }
+       if (intr & MT_INT_RX_DONE(1)) {
++              dev->rx_pse_check = 0;
+               mt7603_irq_disable(dev, MT_INT_RX_DONE(1));
+               napi_schedule(&dev->mt76.napi[1]);
+       }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+index 3745512b1eb3c..915a1043c869e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+@@ -1561,20 +1561,29 @@ static bool mt7603_rx_pse_busy(struct mt7603_dev *dev)
+ {
+       u32 addr, val;
+-      if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES)
+-              return true;
+-
+       if (mt7603_rx_fifo_busy(dev))
+-              return false;
++              goto out;
+       addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS);
+       mt76_wr(dev, addr, 3);
+       val = mt76_rr(dev, addr) >> 16;
+-      if (is_mt7628(dev) && (val & 0x4001) == 0x4001)
+-              return true;
++      if (!(val & BIT(0)))
++              return false;
++
++      if (is_mt7628(dev))
++              val &= 0xa000;
++      else
++              val &= 0x8000;
++      if (!val)
++              return false;
++
++out:
++      if (mt76_rr(dev, MT_INT_SOURCE_CSR) &
++          (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1)))
++              return false;
+-      return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001;
++      return true;
+ }
+ static bool
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch b/queue-5.15/wifi-rtlwifi-fix-edca-limit-set-by-bt-coexistence.patch
new file mode 100644 (file)
index 0000000..1c58ec6
--- /dev/null
@@ -0,0 +1,70 @@
+From 3b553ab3adb0cf95678bdfaf4e5a0b5bcc096ab1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Sep 2023 08:23:19 +0300
+Subject: wifi: rtlwifi: fix EDCA limit set by BT coexistence
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 3391ee7f9ea508c375d443cd712c2e699be235b4 ]
+
+In 'rtl92c_dm_check_edca_turbo()', 'rtl88e_dm_check_edca_turbo()',
+and 'rtl8723e_dm_check_edca_turbo()', the DL limit should be set
+from the corresponding field of 'rtlpriv->btcoexist' rather than
+UL. Compile tested only.
+
+Fixes: 0529c6b81761 ("rtlwifi: rtl8723ae: Update driver to match 06/28/14 Realtek version")
+Fixes: c151aed6aa14 ("rtlwifi: rtl8188ee: Update driver to match Realtek release of 06282014")
+Fixes: beb5bc402043 ("rtlwifi: rtl8192c-common: Convert common dynamic management routines for addition of rtl8192se and rtl8192de")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230928052327.120178-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c       | 2 +-
+ drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c | 2 +-
+ drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c       | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
+index 6f61d6a106272..5a34894a533be 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
+@@ -799,7 +799,7 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
+       }
+       if (rtlpriv->btcoexist.bt_edca_dl != 0) {
+-              edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
++              edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
+               bt_change_edca = true;
+       }
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c
+index 0b6a15c2e5ccd..d92aad60edfe9 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c
+@@ -640,7 +640,7 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
+       }
+       if (rtlpriv->btcoexist.bt_edca_dl != 0) {
+-              edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
++              edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
+               bt_change_edca = true;
+       }
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
+index 8ada31380efa4..0ff8e355c23a4 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
+@@ -466,7 +466,7 @@ static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw)
+       }
+       if (rtlpriv->btcoexist.bt_edca_dl != 0) {
+-              edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
++              edca_be_dl = rtlpriv->btcoexist.bt_edca_dl;
+               bt_change_edca = true;
+       }
+-- 
+2.42.0
+
diff --git a/queue-5.15/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch b/queue-5.15/wifi-rtw88-debug-fix-the-null-vs-is_err-bug-for-debu.patch
new file mode 100644 (file)
index 0000000..2521403
--- /dev/null
@@ -0,0 +1,42 @@
+From 4496cb8842faab5d630699152d5c4a4c6ba5ccaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 13:06:50 +0800
+Subject: wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for
+ debugfs_create_file()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 74f7957c9b1b95553faaf146a2553e023a9d1720 ]
+
+Since debugfs_create_file() return ERR_PTR and never return NULL, so use
+IS_ERR() to check it instead of checking NULL.
+
+Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230919050651.962694-1-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/debug.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
+index dfd52cff5d02f..1cc2b7b948044 100644
+--- a/drivers/net/wireless/realtek/rtw88/debug.c
++++ b/drivers/net/wireless/realtek/rtw88/debug.c
+@@ -1061,9 +1061,9 @@ static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = {
+ #define rtw_debugfs_add_core(name, mode, fopname, parent)             \
+       do {                                                            \
+               rtw_debug_priv_ ##name.rtwdev = rtwdev;                 \
+-              if (!debugfs_create_file(#name, mode,                   \
++              if (IS_ERR(debugfs_create_file(#name, mode,             \
+                                        parent, &rtw_debug_priv_ ##name,\
+-                                       &file_ops_ ##fopname))         \
++                                       &file_ops_ ##fopname)))        \
+                       pr_debug("Unable to initialize debugfs:%s\n",   \
+                              #name);                                  \
+       } while (0)
+-- 
+2.42.0
+
diff --git a/queue-5.15/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch b/queue-5.15/writeback-cgroup-switch-inodes-with-dirty-timestamps.patch
new file mode 100644 (file)
index 0000000..f557ae0
--- /dev/null
@@ -0,0 +1,103 @@
+From fe85b92bd3f43749108ec8f19c4c7d1627242f16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Oct 2023 20:55:11 +0800
+Subject: writeback, cgroup: switch inodes with dirty timestamps to release
+ dying cgwbs
+
+From: Jingbo Xu <jefflexu@linux.alibaba.com>
+
+[ Upstream commit 6654408a33e6297d8e1d2773409431d487399b95 ]
+
+The cgwb cleanup routine will try to release the dying cgwb by switching
+the attached inodes.  It fetches the attached inodes from wb->b_attached
+list, omitting the fact that inodes only with dirty timestamps reside in
+wb->b_dirty_time list, which is the case when lazytime is enabled.  This
+causes enormous zombie memory cgroup when lazytime is enabled, as inodes
+with dirty timestamps can not be switched to a live cgwb for a long time.
+
+It is reasonable not to switch cgwb for inodes with dirty data, as
+otherwise it may break the bandwidth restrictions.  However since the
+writeback of inode metadata is not accounted for, let's also switch
+inodes with dirty timestamps to avoid zombie memory and block cgroups
+when laztytime is enabled.
+
+Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20231014125511.102978-1-jefflexu@linux.alibaba.com
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fs-writeback.c | 41 +++++++++++++++++++++++++++++------------
+ 1 file changed, 29 insertions(+), 12 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 5f0abea107e46..672d176524f5c 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -609,6 +609,24 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
+       kfree(isw);
+ }
++static bool isw_prepare_wbs_switch(struct inode_switch_wbs_context *isw,
++                                 struct list_head *list, int *nr)
++{
++      struct inode *inode;
++
++      list_for_each_entry(inode, list, i_io_list) {
++              if (!inode_prepare_wbs_switch(inode, isw->new_wb))
++                      continue;
++
++              isw->inodes[*nr] = inode;
++              (*nr)++;
++
++              if (*nr >= WB_MAX_INODES_PER_ISW - 1)
++                      return true;
++      }
++      return false;
++}
++
+ /**
+  * cleanup_offline_cgwb - detach associated inodes
+  * @wb: target wb
+@@ -621,7 +639,6 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
+ {
+       struct cgroup_subsys_state *memcg_css;
+       struct inode_switch_wbs_context *isw;
+-      struct inode *inode;
+       int nr;
+       bool restart = false;
+@@ -643,17 +660,17 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
+       nr = 0;
+       spin_lock(&wb->list_lock);
+-      list_for_each_entry(inode, &wb->b_attached, i_io_list) {
+-              if (!inode_prepare_wbs_switch(inode, isw->new_wb))
+-                      continue;
+-
+-              isw->inodes[nr++] = inode;
+-
+-              if (nr >= WB_MAX_INODES_PER_ISW - 1) {
+-                      restart = true;
+-                      break;
+-              }
+-      }
++      /*
++       * In addition to the inodes that have completed writeback, also switch
++       * cgwbs for those inodes only with dirty timestamps. Otherwise, those
++       * inodes won't be written back for a long time when lazytime is
++       * enabled, and thus pinning the dying cgwbs. It won't break the
++       * bandwidth restrictions, as writeback of inode metadata is not
++       * accounted for.
++       */
++      restart = isw_prepare_wbs_switch(isw, &wb->b_attached, &nr);
++      if (!restart)
++              restart = isw_prepare_wbs_switch(isw, &wb->b_dirty_time, &nr);
+       spin_unlock(&wb->list_lock);
+       /* no attached inodes? bail out */
+-- 
+2.42.0
+
diff --git a/queue-5.15/x86-boot-fix-incorrect-startup_gdt_descr.size.patch b/queue-5.15/x86-boot-fix-incorrect-startup_gdt_descr.size.patch
new file mode 100644 (file)
index 0000000..3449f19
--- /dev/null
@@ -0,0 +1,42 @@
+From 5395bf30a449d855b798a6aa8b629d4a9b58c0bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 16:45:47 +0800
+Subject: x86/boot: Fix incorrect startup_gdt_descr.size
+
+From: Yuntao Wang <ytcoode@gmail.com>
+
+[ Upstream commit 001470fed5959d01faecbd57fcf2f60294da0de1 ]
+
+Since the size value is added to the base address to yield the last valid
+byte address of the GDT, the current size value of startup_gdt_descr is
+incorrect (too large by one), fix it.
+
+[ mingo: This probably never mattered, because startup_gdt[] is only used
+         in a very controlled fashion - but make it consistent nevertheless. ]
+
+Fixes: 866b556efa12 ("x86/head/64: Install startup GDT")
+Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Link: https://lore.kernel.org/r/20230807084547.217390-1-ytcoode@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/head64.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
+index 5036104d54707..2375f5f4f763f 100644
+--- a/arch/x86/kernel/head64.c
++++ b/arch/x86/kernel/head64.c
+@@ -79,7 +79,7 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] = {
+  * while the kernel still uses a direct mapping.
+  */
+ static struct desc_ptr startup_gdt_descr = {
+-      .size = sizeof(startup_gdt),
++      .size = sizeof(startup_gdt)-1,
+       .address = 0,
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.15/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch b/queue-5.15/x86-sev-es-allow-copy_from_kernel_nofault-in-earlier.patch
new file mode 100644 (file)
index 0000000..01c6366
--- /dev/null
@@ -0,0 +1,64 @@
+From f19374e16420910ac130ee121f442856fd76ee61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 17:27:02 -0700
+Subject: x86/sev-es: Allow copy_from_kernel_nofault() in earlier boot
+
+From: Adam Dunlap <acdunlap@google.com>
+
+[ Upstream commit f79936545fb122856bd78b189d3c7ee59928c751 ]
+
+Previously, if copy_from_kernel_nofault() was called before
+boot_cpu_data.x86_virt_bits was set up, then it would trigger undefined
+behavior due to a shift by 64.
+
+This ended up causing boot failures in the latest version of ubuntu2204
+in the gcp project when using SEV-SNP.
+
+Specifically, this function is called during an early #VC handler which
+is triggered by a CPUID to check if NX is implemented.
+
+Fixes: 1aa9aa8ee517 ("x86/sev-es: Setup GHCB-based boot #VC handler")
+Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Adam Dunlap <acdunlap@google.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Jacob Xu <jacobhxu@google.com>
+Link: https://lore.kernel.org/r/20230912002703.3924521-2-acdunlap@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/maccess.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c
+index 5a53c2cc169cc..6993f026adec9 100644
+--- a/arch/x86/mm/maccess.c
++++ b/arch/x86/mm/maccess.c
+@@ -9,12 +9,21 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+       unsigned long vaddr = (unsigned long)unsafe_src;
+       /*
+-       * Range covering the highest possible canonical userspace address
+-       * as well as non-canonical address range. For the canonical range
+-       * we also need to include the userspace guard page.
++       * Do not allow userspace addresses.  This disallows
++       * normal userspace and the userspace guard page:
+        */
+-      return vaddr >= TASK_SIZE_MAX + PAGE_SIZE &&
+-             __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
++      if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
++              return false;
++
++      /*
++       * Allow everything during early boot before 'x86_virt_bits'
++       * is initialized.  Needed for instruction decoding in early
++       * exception handlers.
++       */
++      if (!boot_cpu_data.x86_virt_bits)
++              return true;
++
++      return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
+ }
+ #else
+ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+-- 
+2.42.0
+
diff --git a/queue-5.15/x86-share-definition-of-__is_canonical_address.patch b/queue-5.15/x86-share-definition-of-__is_canonical_address.patch
new file mode 100644 (file)
index 0000000..087b35a
--- /dev/null
@@ -0,0 +1,165 @@
+From 783cca8b1d06919e09ca10f39d7b35c5098c9ee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jan 2022 09:24:50 +0200
+Subject: x86: Share definition of __is_canonical_address()
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 1fb85d06ad6754796cd1b920639ca9d8840abefd ]
+
+Reduce code duplication by moving canonical address code to a common header
+file.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220131072453.2839535-3-adrian.hunter@intel.com
+Stable-dep-of: f79936545fb1 ("x86/sev-es: Allow copy_from_kernel_nofault() in earlier boot")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/pt.c  | 14 ++------------
+ arch/x86/include/asm/page.h | 10 ++++++++++
+ arch/x86/kvm/emulate.c      |  4 ++--
+ arch/x86/kvm/x86.c          |  2 +-
+ arch/x86/kvm/x86.h          |  7 +------
+ arch/x86/mm/maccess.c       |  7 +------
+ 6 files changed, 17 insertions(+), 27 deletions(-)
+
+diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
+index d0295240c78a8..a85d3138839c5 100644
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -1360,20 +1360,10 @@ static void pt_addr_filters_fini(struct perf_event *event)
+ }
+ #ifdef CONFIG_X86_64
+-static u64 canonical_address(u64 vaddr, u8 vaddr_bits)
+-{
+-      return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
+-}
+-
+-static u64 is_canonical_address(u64 vaddr, u8 vaddr_bits)
+-{
+-      return canonical_address(vaddr, vaddr_bits) == vaddr;
+-}
+-
+ /* Clamp to a canonical address greater-than-or-equal-to the address given */
+ static u64 clamp_to_ge_canonical_addr(u64 vaddr, u8 vaddr_bits)
+ {
+-      return is_canonical_address(vaddr, vaddr_bits) ?
++      return __is_canonical_address(vaddr, vaddr_bits) ?
+              vaddr :
+              -BIT_ULL(vaddr_bits - 1);
+ }
+@@ -1381,7 +1371,7 @@ static u64 clamp_to_ge_canonical_addr(u64 vaddr, u8 vaddr_bits)
+ /* Clamp to a canonical address less-than-or-equal-to the address given */
+ static u64 clamp_to_le_canonical_addr(u64 vaddr, u8 vaddr_bits)
+ {
+-      return is_canonical_address(vaddr, vaddr_bits) ?
++      return __is_canonical_address(vaddr, vaddr_bits) ?
+              vaddr :
+              BIT_ULL(vaddr_bits - 1) - 1;
+ }
+diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h
+index 4d5810c8fab74..9cc82f305f4bf 100644
+--- a/arch/x86/include/asm/page.h
++++ b/arch/x86/include/asm/page.h
+@@ -71,6 +71,16 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
+ extern bool __virt_addr_valid(unsigned long kaddr);
+ #define virt_addr_valid(kaddr)        __virt_addr_valid((unsigned long) (kaddr))
++static __always_inline u64 __canonical_address(u64 vaddr, u8 vaddr_bits)
++{
++      return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
++}
++
++static __always_inline u64 __is_canonical_address(u64 vaddr, u8 vaddr_bits)
++{
++      return __canonical_address(vaddr, vaddr_bits) == vaddr;
++}
++
+ #endif        /* __ASSEMBLY__ */
+ #include <asm-generic/memory_model.h>
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index cb96e4354f317..98b25a7af8ce8 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -687,7 +687,7 @@ static inline u8 ctxt_virt_addr_bits(struct x86_emulate_ctxt *ctxt)
+ static inline bool emul_is_noncanonical_address(u64 la,
+                                               struct x86_emulate_ctxt *ctxt)
+ {
+-      return get_canonical(la, ctxt_virt_addr_bits(ctxt)) != la;
++      return !__is_canonical_address(la, ctxt_virt_addr_bits(ctxt));
+ }
+ /*
+@@ -737,7 +737,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
+       case X86EMUL_MODE_PROT64:
+               *linear = la;
+               va_bits = ctxt_virt_addr_bits(ctxt);
+-              if (get_canonical(la, va_bits) != la)
++              if (!__is_canonical_address(la, va_bits))
+                       goto bad;
+               *max_size = min_t(u64, ~0u, (1ull << va_bits) - la);
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index a26200c3e82b5..7e9b615653065 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1745,7 +1745,7 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data,
+                * value, and that something deterministic happens if the guest
+                * invokes 64-bit SYSENTER.
+                */
+-              data = get_canonical(data, vcpu_virt_addr_bits(vcpu));
++              data = __canonical_address(data, vcpu_virt_addr_bits(vcpu));
+               break;
+       case MSR_TSC_AUX:
+               if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX))
+diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
+index cd0c93ec72fad..f7854e742e8ce 100644
+--- a/arch/x86/kvm/x86.h
++++ b/arch/x86/kvm/x86.h
+@@ -211,14 +211,9 @@ static inline u8 vcpu_virt_addr_bits(struct kvm_vcpu *vcpu)
+       return kvm_read_cr4_bits(vcpu, X86_CR4_LA57) ? 57 : 48;
+ }
+-static inline u64 get_canonical(u64 la, u8 vaddr_bits)
+-{
+-      return ((int64_t)la << (64 - vaddr_bits)) >> (64 - vaddr_bits);
+-}
+-
+ static inline bool is_noncanonical_address(u64 la, struct kvm_vcpu *vcpu)
+ {
+-      return get_canonical(la, vcpu_virt_addr_bits(vcpu)) != la;
++      return !__is_canonical_address(la, vcpu_virt_addr_bits(vcpu));
+ }
+ static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
+diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c
+index 92ec176a72937..5a53c2cc169cc 100644
+--- a/arch/x86/mm/maccess.c
++++ b/arch/x86/mm/maccess.c
+@@ -4,11 +4,6 @@
+ #include <linux/kernel.h>
+ #ifdef CONFIG_X86_64
+-static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits)
+-{
+-      return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
+-}
+-
+ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+ {
+       unsigned long vaddr = (unsigned long)unsafe_src;
+@@ -19,7 +14,7 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+        * we also need to include the userspace guard page.
+        */
+       return vaddr >= TASK_SIZE_MAX + PAGE_SIZE &&
+-             canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr;
++             __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
+ }
+ #else
+ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+-- 
+2.42.0
+
diff --git a/queue-5.15/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch b/queue-5.15/x86-srso-fix-sbpb-enablement-for-possible-future-fix.patch
new file mode 100644 (file)
index 0000000..615377a
--- /dev/null
@@ -0,0 +1,39 @@
+From 21dde46cd1c49dd2047aab1ae01be2fe6c7d8be1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 22:04:49 -0700
+Subject: x86/srso: Fix SBPB enablement for (possible) future fixed HW
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 1d1142ac51307145dbb256ac3535a1d43a1c9800 ]
+
+Make the SBPB check more robust against the (possible) case where future
+HW has SRSO fixed but doesn't have the SRSO_NO bit set.
+
+Fixes: 1b5277c0ea0b ("x86/srso: Add SRSO_NO support")
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/cee5050db750b391c9f35f5334f8ff40e66c01b9.1693889988.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/bugs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 6322a08edbba5..d1ba55ea46a7b 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -2477,7 +2477,7 @@ static void __init srso_select_mitigation(void)
+       pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
+ pred_cmd:
+-      if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) &&
++      if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) &&
+            boot_cpu_has(X86_FEATURE_SBPB))
+               x86_pred_cmd = PRED_CMD_SBPB;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.15/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch b/queue-5.15/xen-pciback-consider-intx-disabled-when-msi-msi-x-is.patch
new file mode 100644 (file)
index 0000000..c730ea2
--- /dev/null
@@ -0,0 +1,131 @@
+From 47071c5ce4d324df14134b3191a0d79400903e2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Oct 2023 15:13:25 +0200
+Subject: xen-pciback: Consider INTx disabled when MSI/MSI-X is enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+
+[ Upstream commit 2c269f42d0f382743ab230308b836ffe5ae9b2ae ]
+
+Linux enables MSI-X before disabling INTx, but keeps MSI-X masked until
+the table is filled. Then it disables INTx just before clearing MASKALL
+bit. Currently this approach is rejected by xen-pciback.
+According to the PCIe spec, device cannot use INTx when MSI/MSI-X is
+enabled (in other words: enabling MSI/MSI-X implicitly disables INTx).
+
+Change the logic to consider INTx disabled if MSI/MSI-X is enabled. This
+applies to three places:
+ - checking currently enabled interrupts type,
+ - transition to MSI/MSI-X - where INTx would be implicitly disabled,
+ - clearing INTx disable bit - which can be allowed even if MSI/MSI-X is
+   enabled, as device should consider INTx disabled anyway in that case
+
+Fixes: 5e29500eba2a ("xen-pciback: Allow setting PCI_MSIX_FLAGS_MASKALL too")
+Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Acked-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20231016131348.1734721-1-marmarek@invisiblethingslab.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xen-pciback/conf_space.c          | 19 +++++++++++------
+ .../xen/xen-pciback/conf_space_capability.c   |  8 ++++++-
+ drivers/xen/xen-pciback/conf_space_header.c   | 21 +++----------------
+ 3 files changed, 23 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
+index 059de92aea7d0..d47eee6c51435 100644
+--- a/drivers/xen/xen-pciback/conf_space.c
++++ b/drivers/xen/xen-pciback/conf_space.c
+@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
+       u16 val;
+       int ret = 0;
+-      err = pci_read_config_word(dev, PCI_COMMAND, &val);
+-      if (err)
+-              return err;
+-      if (!(val & PCI_COMMAND_INTX_DISABLE))
+-              ret |= INTERRUPT_TYPE_INTX;
+-
+       /*
+        * Do not trust dev->msi(x)_enabled here, as enabling could be done
+        * bypassing the pci_*msi* functions, by the qemu.
+@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
+               if (val & PCI_MSIX_FLAGS_ENABLE)
+                       ret |= INTERRUPT_TYPE_MSIX;
+       }
++
++      /*
++       * PCIe spec says device cannot use INTx if MSI/MSI-X is enabled,
++       * so check for INTx only when both are disabled.
++       */
++      if (!ret) {
++              err = pci_read_config_word(dev, PCI_COMMAND, &val);
++              if (err)
++                      return err;
++              if (!(val & PCI_COMMAND_INTX_DISABLE))
++                      ret |= INTERRUPT_TYPE_INTX;
++      }
++
+       return ret ?: INTERRUPT_TYPE_NONE;
+ }
+diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
+index 097316a741268..1948a9700c8fa 100644
+--- a/drivers/xen/xen-pciback/conf_space_capability.c
++++ b/drivers/xen/xen-pciback/conf_space_capability.c
+@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+               return PCIBIOS_SET_FAILED;
+       if (new_value & field_config->enable_bit) {
+-              /* don't allow enabling together with other interrupt types */
++              /*
++               * Don't allow enabling together with other interrupt type, but do
++               * allow enabling MSI(-X) while INTx is still active to please Linuxes
++               * MSI(-X) startup sequence. It is safe to do, as according to PCI
++               * spec, device with enabled MSI(-X) shouldn't use INTx.
++               */
+               int int_type = xen_pcibk_get_interrupt_type(dev);
+               if (int_type == INTERRUPT_TYPE_NONE ||
++                  int_type == INTERRUPT_TYPE_INTX ||
+                   int_type == field_config->int_type)
+                       goto write;
+               return PCIBIOS_SET_FAILED;
+diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
+index ac45cdc38e859..fcaa050d692d2 100644
+--- a/drivers/xen/xen-pciback/conf_space_header.c
++++ b/drivers/xen/xen-pciback/conf_space_header.c
+@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
+               pci_clear_mwi(dev);
+       }
+-      if (dev_data && dev_data->allow_interrupt_control) {
+-              if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
+-                      if (value & PCI_COMMAND_INTX_DISABLE) {
+-                              pci_intx(dev, 0);
+-                      } else {
+-                              /* Do not allow enabling INTx together with MSI or MSI-X. */
+-                              switch (xen_pcibk_get_interrupt_type(dev)) {
+-                              case INTERRUPT_TYPE_NONE:
+-                                      pci_intx(dev, 1);
+-                                      break;
+-                              case INTERRUPT_TYPE_INTX:
+-                                      break;
+-                              default:
+-                                      return PCIBIOS_SET_FAILED;
+-                              }
+-                      }
+-              }
+-      }
++      if (dev_data && dev_data->allow_interrupt_control &&
++          ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))
++              pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));
+       cmd->val = value;
+-- 
+2.42.0
+
diff --git a/queue-5.15/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch b/queue-5.15/xhci-loosen-rpm-as-default-policy-to-cover-for-amd-x.patch
new file mode 100644 (file)
index 0000000..dd2469a
--- /dev/null
@@ -0,0 +1,47 @@
+From 9e1321cf0ac5aae326a44a0c07cd98ec3582a31b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Oct 2023 13:29:19 +0300
+Subject: xhci: Loosen RPM as default policy to cover for AMD xHC 1.1
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 4baf1218150985ee3ab0a27220456a1f027ea0ac ]
+
+The AMD USB host controller (1022:43f7) isn't going into PCI D3 by default
+without anything connected. This is because the policy that was introduced
+by commit a611bf473d1f ("xhci-pci: Set runtime PM as default policy on all
+xHC 1.2 or later devices") only covered 1.2 or later.
+
+The 1.1 specification also has the same requirement as the 1.2
+specification for D3 support. So expand the runtime PM as default policy
+to all AMD 1.1 devices as well.
+
+Fixes: a611bf473d1f ("xhci-pci: Set runtime PM as default policy on all xHC 1.2 or later devices")
+Link: https://composter.com.ua/documents/xHCI_Specification_for_USB.pdf
+Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20231019102924.2797346-15-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-pci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 29a442b621182..d0223facb92a1 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -349,6 +349,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+       /* xHC spec requires PCI devices to support D3hot and D3cold */
+       if (xhci->hci_version >= 0x120)
+               xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
++      else if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version >= 0x110)
++              xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+       if (xhci->quirks & XHCI_RESET_ON_RESUME)
+               xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+-- 
+2.42.0
+