cad384bd77
* remotes/origin/tmp-a63d3d432447: ABI file updates for 5.3-rc5 and 5.3-rc6 Linux 5.3-rc6 mm/kasan: fix false positive invalid-free reports with CONFIG_KASAN_SW_TAGS=y mm/zsmalloc.c: fix race condition in zs_destroy_pool mm/zsmalloc.c: migration can leave pages in ZS_EMPTY indefinitely mm, page_owner: handle THP splits correctly userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx psi: get poll_work to run when calling poll syscall next time mm: memcontrol: flush percpu vmevents before releasing memcg mm: memcontrol: flush percpu vmstats before releasing memcg parisc: fix compilation errrors mm, page_alloc: move_freepages should not examine struct page of reserved memory mm/z3fold.c: fix race between migration and destruction drm/mediatek: include dma-mapping header ANDROID: update ABI for CONFIG_TIPC ANDROID: gki_defconfig: enable CONFIG_TIPC KVM: arm/arm64: VGIC: Properly initialise private IRQ affinity RDMA/siw: Fix 64/32bit pointer inconsistency x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386 dm table: fix invalid memory accesses with too high sector number gpio: Fix irqchip initialization order xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT drm/nouveau: Don't retry infinitely when receiving no data on i2c over AUX drm/amdgpu/powerplay: silence a warning in smu_v11_0_setup_pptable timekeeping/vsyscall: Prevent math overflow in BOOTTIME update um: fix time travel mode io_uring: add need_resched() check in inner poll loop dm space map metadata: fix missing store of apply_bops() return value dm btree: fix order of block initialization in btree_split_beneath ubifs: Limit the number of pages in shrink_liability ubifs: Correctly initialize c->min_log_bytes ubifs: Fix double unlock around orphan_delete() jffs2: Remove C++ style comments from uapi header RDMA/siw: Fix SGL mapping issues RDMA/bnxt_re: Fix stack-out-of-bounds in bnxt_qplib_rcfw_send_message afs: use correct afs_call_type in yfs_fs_store_opaque_acl2 afs: Fix possible oops in afs_lookup trace event afs: Fix leak in afs_lookup_cell_rcu() KVM: arm/arm64: Only skip MMIO insn once libceph: fix PG split vs OSD (re)connect race ceph: don't try fill file_lock on unsuccessful GETFILELOCK reply ceph: clear page dirty before invalidate page ceph: fix buffer free while holding i_ceph_lock in fill_inode() ceph: fix buffer free while holding i_ceph_lock in __ceph_build_xattrs_blob() ceph: fix buffer free while holding i_ceph_lock in __ceph_setxattr() libceph: allow ceph_buffer_put() to receive a NULL ceph_buffer md: update MAINTAINERS info drm/amd/display: Calculate bpc based on max_requested_bpc drm/amdgpu: prevent memory leaks in AMDGPU_CS ioctl drm/amd/amdgpu: disable MMHUB PG for navi10 drm/amd/powerplay: remove duplicate macro smu_get_uclk_dpm_states in amdgpu_smu.h drm/amd/powerplay: fix variable type errors in smu_v11_0_setup_pptable drm/amdgpu/gfx9: update pg_flags after determining if gfx off is possible x86/boot: Fix boot regression caused by bootparam sanitizing selftests/kvm: make platform_info_test pass on AMD dm raid: add missing cleanup in raid_ctr() dm zoned: fix potential NULL dereference in dmz_do_reclaim() dm dust: use dust block size for badblocklist index drm/i915: Fix HW readout for crtc_clock in HDMI mode modules: page-align module section allocations only for arches supporting strict module rwx Revert "KVM: x86/mmu: Zap only the relevant pages when removing a memslot" selftests: kvm: fix state save/load on processors without XSAVE video: fbdev: acornfb: Mark expected switch fall-through scsi: libsas: sas_discover: Mark expected switch fall-through MIPS: Octeon: Mark expected switch fall-through power: supply: ab8500_charger: Mark expected switch fall-through watchdog: wdt285: Mark expected switch fall-through mtd: sa1100: Mark expected switch fall-through drm/sun4i: tcon: Mark expected switch fall-through drm/sun4i: sun6i_mipi_dsi: Mark expected switch fall-through ARM: riscpc: Mark expected switch fall-through dmaengine: fsldma: Mark expected switch fall-through dma-direct: fix zone selection after an unaddressable CMA allocation infiniband: hfi1: fix memory leaks infiniband: hfi1: fix a memory leak bug IB/mlx4: Fix memory leaks RDMA/cma: fix null-ptr-deref Read in cma_cleanup IB/mlx5: Block MR WR if UMR is not possible IB/mlx5: Fix MR re-registration flow to use UMR properly IB/mlx5: Report and handle ODP support properly IB/mlx5: Consolidate use_umr checks into single function RDMA/restrack: Rewrite PID namespace check to be reliable RDMA/counters: Properly implement PID checks IB/core: Fix NULL pointer dereference when bind QP to counter IB/hfi1: Drop stale TID RDMA packets that cause TIDErr IB/hfi1: Add additional checks when handling TID RDMA WRITE DATA packet IB/hfi1: Add additional checks when handling TID RDMA READ RESP packet IB/hfi1: Unsafe PSN checking for TID RDMA READ Resp packet IB/hfi1: Drop stale TID RDMA packets RDMA/siw: Fix potential NULL de-ref RDMA/mlx5: Fix MR npages calculation for IB_ACCESS_HUGETLB io_uring: don't enter poll loop if we have CQEs pending nvme: Add quirk for LiteON CL1 devices running FW 22301111 nvme: Fix cntlid validation when not using NVMEoF nvme-multipath: fix possible I/O hang when paths are updated io_uring: fix potential hang with polled IO Drivers: hv: vmbus: Fix virt_to_hvpfn() for X86_PAE ANDROID: fix kernelci build-break Tools: hv: kvp: eliminate 'may be used uninitialized' warning Input: hyperv-keyboard: Use in-place iterator API in the channel callback Drivers: hv: vmbus: Remove the unused "tsc_page" from struct hv_context auxdisplay: ht16k33: Make ht16k33_fb_fix and ht16k33_fb_var constant HID: wacom: correct misreported EKR ring values arm: select the dma-noncoherent symbols for all swiotlb builds scsi: lpfc: Mitigate high memory pre-allocation by SCSI-MQ ANDROID: staging: ion: Build fix for mips fs/xfs: Fix return code of xfs_break_leased_layouts() genirq: Properly pair kobject_del() with kobject_add() ABI: ion: Update ABI to match with ion core changes staging: ion: make system and contig heaps modular staging: ion: split system and system-contig heaps staging: ion: refactor ion's heap API into linux/ion.h staging: ion: Move ion heaps into their own directory staging: ion: refactor ion's heap manipulators into a separate file. staging: ion: refactor ion's dmabuf manipulators into a separate file. staging: ion: refactor ion's buffer manipulators into a separate file. x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h keys: Fix description size ANDROID: Remove unused cuttlefish build infra x86/boot/compressed/64: Fix boot on machines with broken E820 table HID: cp2112: prevent sleeping function called from invalid context HID: intel-ish-hid: ipc: add EHL device id HID: wacom: Correct distance scale for 2nd-gen Intuos devices signal: Allow cifs and drbd to receive their terminating signals x86/apic: Handle missing global clockevent gracefully kprobes: Fix potential deadlock in kprobe_optimizer() perf/x86: Fix typo in comment sched/core: Schedule new worker even if PI-blocked xfs: fix reflink source file racing with directio writes drm/mediatek: mtk_drm_drv.c: Add of_node_put() before goto Linux 5.3-rc5 ravb: Fix use-after-free ravb_tstamp_skb netfilter: nf_tables: map basechain priority to hardware priority net: sched: use major priority number as hardware priority wimax/i2400m: fix a memory leak bug net: cavium: fix driver name ibmvnic: Unmap DMA address of TX descriptor buffers after use bnxt_en: Fix to include flow direction in L2 key bnxt_en: Use correct src_fid to determine direction of the flow bnxt_en: Suppress HWRM errors for HWRM_NVM_GET_VARIABLE command bnxt_en: Fix handling FRAG_ERR when NVM_INSTALL_UPDATE cmd fails bnxt_en: Improve RX doorbell sequence. bnxt_en: Fix VNIC clearing logic for 57500 chips. net: kalmia: fix memory leaks cx82310_eth: fix a memory leak bug bnx2x: Fix VF's VLAN reconfiguration in reload. MAINTAINERS: Fix Hyperv vIOMMU driver file name tools: hv: Use the correct style for SPDX License Identifier tools: hv: fix typos in toolchain tools: hv: fix KVP and VSS daemons exit code tools: hv: fixed Python pep8/flake8 warnings for lsvmbus Bluetooth: Add debug setting for changing minimum encryption key size x86/cpu: Explain Intel model naming convention vfs: fix page locking deadlocks when deduping files xfs: compat_ioctl: use compat_ptr() xfs: fall back to native ioctls for unhandled compat ones tipc: fix false detection of retransmit failures gpio: of: fix Freescale SPI CS quirk handling lan78xx: Fix memory leaks MAINTAINERS: r8169: Update path to the driver MAINTAINERS: PHY LIBRARY: Update files in the record nfsd4: Fix kernel crash when reading proc file reply_cache_stats clk: Fix potential NULL dereference in clk_fetch_parent_index() clk: Fix falling back to legacy parent string matching arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side drm: rcar_lvds: Fix dual link mode operations x86/boot: Save fields explicitly, zero out everything else net/packet: fix race in tpacket_snd() nfsd: initialize i_private before d_add dm integrity: fix a crash due to BUG_ON in __journal_read_write() dm zoned: fix a few typos dm zoned: add SPDX license identifiers dm zoned: properly handle backing device failure dm zoned: improve error handling in i/o map code dm zoned: improve error handling in reclaim dm kcopyd: always complete failed jobs Revert "dm bufio: fix deadlock with loop device" ALSA: usb-audio: Fix a stack buffer overflow bug in check_input_term net: myri10ge: fix memory leaks net: tls, fix sk_write_space NULL write when tx disabled liquidio: add cleanup in octeon_setup_iq() nfsd: use i_wrlock instead of rcu for nfsdfs i_private nfsd: fix dentry leak upon mkdir failure. net/mlx5e: Fix compatibility issue with ethtool flash device net/mlx5e: Fix a race with XSKICOSQ in XSK wakeup flow selftests: net: tcp_fastopen_backup_key.sh: fix shellcheck issue io_uring: fix an issue when IOSQE_IO_LINK is inserted into defer list Documentation PCI: Fix pciebus-howto.rst filename typo block: remove REQ_NOWAIT_INLINE io_uring: fix manual setup of iov_iter for fixed buffers PCI: Reset both NVIDIA GPU and HDA in ThinkPad P50 workaround misc: xilinx-sdfec: fix dependency and build error usb: add a hcd_uses_dma helper usb: don't create dma pools for HCDs with a localmem_pool usb: chipidea: imx: fix EPROBE_DEFER support during driver probe usb: host: fotg2: restart hcd after port reset USB: CDC: fix sanity checks in CDC union parser usb: cdc-acm: make sure a refcount is taken early enough USB: serial: option: add the BroadMobi BM818 card USB: serial: option: Add Motorola modem UARTs MAINTAINERS, x86/CPU: Tony Luck will maintain asm/intel-family.h selftests: kvm: fix vmx_set_nested_state_test selftests: kvm: provide common function to enable eVMCS selftests: kvm: do not try running the VM in vmx_set_nested_state_test drm/nouveau: Only recalculate PBN/VCPI on mode/connector changes drm/ast: Fixed reboot test may cause system hanged cxgb4: fix a memory leak bug of: irq: fix a trivial typo in a doc comment dt-bindings: pinctrl: stm32: Fix 'st,syscfg' schema scsi: ufs: Fix NULL pointer dereference in ufshcd_config_vreg_hpm() scsi: target: tcmu: avoid use-after-free after command timeout scsi: qla2xxx: Fix gnl.l memory leak on adapter init failure drm/mediatek: set DMA max segment size drm/mediatek: use correct device to import PRIME buffers drm/scheduler: use job count instead of peek riscv: Make __fstate_clean() work correctly. riscv: Correct the initialized flow of FP register Adding GKI Ramdisk to gki config ALSA: usb-audio: Fix an OOB bug in parse_audio_mixer_unit clk: socfpga: stratix10: fix rate caclulationg for cnt_clks KVM: x86: svm: remove redundant assignment of var new_entry MAINTAINERS: add KVM x86 reviewers MAINTAINERS: change list for KVM/s390 kvm: x86: skip populating logical dest map if apic is not sw enabled Bluetooth: hci_qca: Skip 1 error print in device_want_to_sleep() i2c: stm32: Use the correct style for SPDX License Identifier i2c: emev2: avoid race when unregistering slave client i2c: rcar: avoid race when unregistering slave client rxrpc: Fix read-after-free in rxrpc_queue_local() rxrpc: Fix local endpoint replacement MAINTAINERS: i2c-imx: take over maintainership Revert "i2c: imx: improve the error handling in i2c_imx_dma_request()" netfilter: nft_flow_offload: skip tcp rst and fin packets gpio: Fix build error of function redefinition gpiolib: never report open-drain/source lines as 'input' to user-space ALSA: hda - Add a generic reboot_notify ALSA: hda - Let all conexant codec enter D3 when rebooting sctp: fix memleak in sctp_send_reset_streams netlink: Fix nlmsg_parse as a wrapper for strict message parsing net: phy: consider AN_RESTART status when reading link status net/mlx4_en: fix a memory leak bug ibmveth: Convert multicast list size for little-endian system s390/qeth: serialize cmd reply with concurrent timeout riscv: defconfig: Update the defconfig riscv: rv32_defconfig: Update the defconfig sctp: fix the transport error_count check ANDROID: Removed unnecessary modules from cuttlefish. hugetlbfs: fix hugetlb page migration/fault race causing SIGBUS mm, vmscan: do not special-case slab reclaim when watermarks are boosted Revert "mm, thp: restore node-local hugepage allocations" Revert "Revert "mm, thp: consolidate THP gfp handling into alloc_hugepage_direct_gfpmask"" include/asm-generic/5level-fixup.h: fix variable 'p4d' set but not used seq_file: fix problem when seeking mid-record mm: workingset: fix vmstat counters for shadow nodes mm/usercopy: use memory range to be accessed for wraparound check mm: kmemleak: disable early logging in case of error mm/vmalloc.c: fix percpu free VM area search criteria mm/memcontrol.c: fix use after free in mem_cgroup_iter() mm/z3fold.c: fix z3fold_destroy_pool() race condition mm/z3fold.c: fix z3fold_destroy_pool() ordering mm: mempolicy: handle vma with unmovable pages mapped correctly in mbind mm: mempolicy: make the behavior consistent when MPOL_MF_MOVE* and MPOL_MF_STRICT were specified mm/hmm: fix bad subpage pointer in try_to_unmap_one mm/hmm: fix ZONE_DEVICE anon page mapping reuse mm: document zone device struct page field usage riscv: fix flush_tlb_range() end address for flush_tlb_page() KEYS: trusted: allow module init if TPM is inactive or deactivated RDMA/siw: Change CQ flags from 64->32 bits netfilter: conntrack: Use consistent ct id hash calculation ALSA: hda/realtek - Add quirk for HP Envy x360 MAINTAINERS: iomap: Remove fs/iomap.c record HID: logitech-hidpp: remove support for the G700 over USB Revert "HID: logitech-hidpp: add USB PID for a few more supported mice" mtd: spi-nor: Fix the disabling of write protection at init arm64: cpufeature: Don't treat granule sizes as strict HID: wacom: add back changes dropped in merge commit drm/amd/display: use kvmalloc for dc_state (v2) drm/amdgpu: fix gfx9 soft recovery dt-bindings: fec: explicitly mark deprecated properties of: resolver: Add of_node_put() before return and break xtensa: add missing isync to the cpu_reset TLB code net: phy: at803x: stop switching phy delay config needlessly USB: core: Fix races in character device registration and deregistraion x86/fpu/math-emu: Address fallthrough warnings x86/apic/32: Fix yet another implicit fallthrough warning Bluetooth: btqca: Reset download type to default Bluetooth: btqca: release_firmware after qca_inject_cmd_complete_event xfs: don't crash on null attr fork xfs_bmapi_read xfs: remove more ondisk directory corruption asserts Bluetooth: hidp: Let hidp_send_message return number of queued bytes Bluetooth: hci_qca: Send VS pre shutdown command. Bluetooth: btqca: Use correct byte format for opcode of injected command Bluetooth: hci_qca: Use kfree_skb() instead of kfree() Bluetooth: btqca: Add a short delay before downloading the NVM Bluetooth: btusb: Fix error return code in btusb_mtk_setup_firmware() RDMA/core: Fix error code in stat_get_doit_qp() RDMA/siw: Fix a memory leak in siw_init_cpulist() IB/mlx5: Fix use-after-free error while accessing ev_file pointer staging: comedi: dt3000: Fix rounding up of timer divisor staging: comedi: dt3000: Fix signed integer overflow 'divider * base' xen/blkback: fix memory leaks blk-mq: move cancel of requeue_work to the front of blk_exit_queue drm/omap: ensure we have a valid dma_mask x86/umwait: Fix error handling in umwait_init() drm/komeda: Add support for 'memory-region' DT node property drm/komeda: Adds internal bpp computing for arm afbc only format YU08 YU10 efi-stub: Fix get_efi_config_table on mixed-mode setups nvme-pci: Allow PCI bus-level PM to be used if ASPM is disabled PCI/ASPM: Add pcie_aspm_enabled() habanalabs: fix device IRQ unmasking for BE host habanalabs: fix endianness handling for internal QMAN submission habanalabs: fix completion queue handling when host is BE habanalabs: fix endianness handling for packets from user habanalabs: fix DRAM usage accounting on context tear down habanalabs: Avoid double free in error flow usb: gadget: mass_storage: Fix races between fsg_disable and fsg_set_alt usb: gadget: composite: Clear "suspended" on reset/disconnect usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role" net: tc35815: Explicitly check NET_IP_ALIGN is not zero in tc35815_rx tipc: initialise addr_trail_end when setting node addresses net: dsa: Check existence of .port_mdb_add callback before calling it mlxsw: spectrum_ptp: Keep unmatched entries in a linked list net: nps_enet: Fix function names in doc comments rxrpc: Fix local refcounting netdevsim: Restore per-network namespace accounting for fib entries sh: kernel: hw_breakpoint: Fix missing break in switch statement sh: kernel: disassemble: Mark expected switch fall-throughs dma-mapping: fix page attributes for dma_mmap_* dma-direct: don't truncate dma_required_mask to bus addressing capabilities dma-direct: fix DMA_ATTR_NO_KERNEL_MAPPING cpufreq: schedutil: Don't skip freq update when limits change cpufreq: dev_pm_qos_update_request() can return 1 on success ALSA: hda - Fix a memory leak bug net/tls: swap sk_write_space on close hv_netvsc: Fix a warning of suspicious RCU usage ixgbe: fix possible deadlock in ixgbe_service_task() bpf: sync bpf.h to tools infrastructure sock: make cookie generation global instead of per netns tools: bpftool: add error message on pin failure tools: bpftool: fix error message (prog -> object) iommu/vt-d: Fix possible use-after-free of private domain iommu/vt-d: Detach domain before using a private one iommu/dma: Handle SG length overflow better iommu/vt-d: Correctly check format of page table in debugfs rxrpc: Don't bother generating maxSkew in the ACK packet rxrpc: Fix local endpoint refcounting netfilter: nf_flow_table: teardown flow timeout race netfilter: nf_flow_table: conntrack picks up expired flows netfilter: nf_tables: use-after-free in failing rule with bound set omap-dma/omap_vout_vrfb: fix off-by-one fi value ALSA: hda - Apply workaround for another AMD chip 1022:1487 drm/i915: Use after free in error path in intel_vgpu_create_workload() drm/komeda: Initialize and enable output polling on Komeda net: tundra: tsi108: use spin_lock_irqsave instead of spin_lock_irq in IRQ context team: Add vlan tx offload to hw_enc_features net/tls: prevent skb_orphan() from leaking TLS plain text with offload tc-testing: updated skbedit action tests with batch create/delete net sched: update skbedit action for batched events operations net: dsa: sja1105: remove set but not used variables 'tx_vid' and 'rx_vid' bonding: Add vlan tx offload to hw_enc_features net: sched: sch_taprio: fix memleak in error path for sched list parse soundwire: fix regmap dependencies and align with other serial links net: docs: replace IPX in tuntap documentation docs: admin-guide: remove references to IPX and token-ring xen/netback: Reset nr_frags before freeing skb inet: frags: re-introduce skb coalescing for local delivery clk: samsung: exynos542x: Move MSCL subsystem clocks to its sub-CMU clk: samsung: exynos5800: Move MAU subsystem clocks to MAU sub-CMU clk: samsung: Change signature of exynos5_subcmus_init() function net/mlx5e: Remove redundant check in CQE recovery flow of tx reporter net/mlx5e: Fix error flow of CQE recovery on tx reporter net/mlx5e: Fix false negative indication on tx reporter CQE recovery net/mlx5e: kTLS, Fix tisn field placement net/mlx5e: kTLS, Fix tisn field name net/mlx5e: kTLS, Fix progress params context WQE layout net/mlx5: kTLS, Fix wrong TIS opmod constants net/mlx5: crypto, Fix wrong offset in encryption key command net/mlx5e: ethtool, Avoid setting speed to 56GBASE when autoneg off net/mlx5e: Only support tx/rx pause setting for port owner net/mlx5: Support inner header match criteria for non decap flow action net/mlx5e: Use flow keys dissector to parse packets for ARFS auxdisplay: Fix a typo in cfag12864b-example.c auxdisplay: charlcd: add include guard to charlcd.h auxdisplay: charlcd: move charlcd.h to drivers/auxdisplay dmaengine: stm32-mdma: Fix a possible null-pointer dereference in stm32_mdma_irq_handler() scsi: lpfc: Fix crash when cpu count is 1 and null irq affinity mask IB/mlx5: Check the correct variable in error handling code RDMA/counter: Prevent QP counter binding if counters unsupported IB/mlx5: Fix implicit MR release flow btrfs: trim: Check the range passed into to prevent overflow Btrfs: fix sysfs warning and missing raid sysfs directories iommu/vt-d: Detach domain when move device out of group iommu/arm-smmu: Mark expected switch fall-through iommu/dma: Handle MSI mappings separately auxdisplay: charlcd: add help text for backlight initial state auxdisplay: panel: need to delete scan_timer when misc_register fails in panel_attach iio: adc: max9611: Fix temperature reading in probe iio: frequency: adf4371: Fix output frequency setting i2c: stm32: Use the correct style for SPDX License Identifier USB: serial: option: add D-Link DWM-222 device ID USB: serial: option: Add support for ZTE MF871A netfilter: nf_flow_table: fix offload for flows that are subject to xfrm selftests: netfilter: extend flowtable test script for ipsec fs: xfs: xfs_log: Don't use KM_MAYFAIL at xfs_log_reserve(). soundwire: cadence_master: fix definitions for INTSTAT0/1 soundwire: cadence_master: fix register definition for SLAVE_STATE selftests/bpf: tests for jmp to 1st insn bpf: fix x64 JIT code generation for jmp to 1st insn libbpf: set BTF FD for prog only when there is supported .BTF.ext data libbpf : make libbpf_num_possible_cpus function thread safe nvme-pci: Fix async probe remove race nvme: fix controller removal race with scan work nvme-rdma: fix possible use-after-free in connect error flow nvme: fix a possible deadlock when passthru commands sent to a multipath device nvme-core: Fix extra device_put() call on error path nvmet-file: fix nvmet_file_flush() always returning an error nvmet-loop: Flush nvme_delete_wq when removing the port nvmet: Fix use-after-free bug when a port is removed dt-bindings: Fix generated example files getting added to schemas intel_th: Use the correct style for SPDX License Identifier coccinelle: api/atomic_as_refcounter: add SPDX License Identifier kernel/configs: Replace GPL boilerplate code with SPDX identifier afs: Fix missing dentry data version updating afs: Only update d_fsdata if different in afs_d_revalidate() afs: Fix off-by-one in afs_rename() expected data version calculation fs: afs: Fix a possible null-pointer dereference in afs_put_read() afs: Fix loop index mixup in afs_deliver_vl_get_entry_by_name_u() afs: Fix the CB.ProbeUuid service handler to reply correctly nvme-multipath: revalidate nvme_ns_head gendisk in nvme_validate_ns modules: always page-align module section allocations platform/chrome: cros_ec_ishtp: fix crash during suspend libbpf: fix erroneous multi-closing of BTF FD dmaengine: tegra210-adma: Fix unused function warnings batman-adv: Fix deletion of RTR(4|6) mcast list entries batman-adv: Fix netlink dumping of all mcast_flags buckets dmaengine: ste_dma40: fix unneeded variable warning dmaengine: dw-edma: fix endianess confusion dmaengine: dw-edma: fix __iomem type confusion dmaengine: dw-edma: fix unnecessary stack usage Change-Id: I8326b536fd134e0684bd041e22e34409fe2f14c2 Signed-off-by: Raghavendra Rao Ananta <rananta@codeaurora.org>
699 lines
19 KiB
C
699 lines
19 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Derived from arch/i386/kernel/irq.c
|
|
* Copyright (C) 1992 Linus Torvalds
|
|
* Adapted from arch/i386 by Gary Thomas
|
|
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
|
* Updated and modified by Cort Dougan <cort@fsmlabs.com>
|
|
* Copyright (C) 1996-2001 Cort Dougan
|
|
* Adapted for Power Macintosh by Paul Mackerras
|
|
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
|
|
*
|
|
* This file contains the code used to make IRQ descriptions in the
|
|
* device tree to actual irq numbers on an interrupt controller
|
|
* driver.
|
|
*/
|
|
|
|
#define pr_fmt(fmt) "OF: " fmt
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/list.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_irq.h>
|
|
#include <linux/string.h>
|
|
#include <linux/slab.h>
|
|
|
|
/**
|
|
* irq_of_parse_and_map - Parse and map an interrupt into linux virq space
|
|
* @dev: Device node of the device whose interrupt is to be mapped
|
|
* @index: Index of the interrupt to map
|
|
*
|
|
* This function is a wrapper that chains of_irq_parse_one() and
|
|
* irq_create_of_mapping() to make things easier to callers
|
|
*/
|
|
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
|
{
|
|
struct of_phandle_args oirq;
|
|
|
|
if (of_irq_parse_one(dev, index, &oirq))
|
|
return 0;
|
|
|
|
return irq_create_of_mapping(&oirq);
|
|
}
|
|
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
|
|
|
/**
|
|
* of_irq_find_parent - Given a device node, find its interrupt parent node
|
|
* @child: pointer to device node
|
|
*
|
|
* Returns a pointer to the interrupt parent node, or NULL if the interrupt
|
|
* parent could not be determined.
|
|
*/
|
|
struct device_node *of_irq_find_parent(struct device_node *child)
|
|
{
|
|
struct device_node *p;
|
|
phandle parent;
|
|
|
|
if (!of_node_get(child))
|
|
return NULL;
|
|
|
|
do {
|
|
if (of_property_read_u32(child, "interrupt-parent", &parent)) {
|
|
p = of_get_parent(child);
|
|
} else {
|
|
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
|
p = of_node_get(of_irq_dflt_pic);
|
|
else
|
|
p = of_find_node_by_phandle(parent);
|
|
}
|
|
of_node_put(child);
|
|
child = p;
|
|
} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
|
|
|
|
return p;
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_find_parent);
|
|
|
|
/**
|
|
* of_irq_parse_raw - Low level interrupt tree parsing
|
|
* @addr: address specifier (start of "reg" property of the device) in be32 format
|
|
* @out_irq: structure of_phandle_args updated by this function
|
|
*
|
|
* Returns 0 on success and a negative number on error
|
|
*
|
|
* This function is a low-level interrupt tree walking function. It
|
|
* can be used to do a partial walk with synthetized reg and interrupts
|
|
* properties, for example when resolving PCI interrupts when no device
|
|
* node exist for the parent. It takes an interrupt specifier structure as
|
|
* input, walks the tree looking for any interrupt-map properties, translates
|
|
* the specifier for each map, and then returns the translated map.
|
|
*/
|
|
int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
|
|
{
|
|
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
|
|
__be32 initial_match_array[MAX_PHANDLE_ARGS];
|
|
const __be32 *match_array = initial_match_array;
|
|
const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = cpu_to_be32(~0) };
|
|
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
|
|
int imaplen, match, i, rc = -EINVAL;
|
|
|
|
#ifdef DEBUG
|
|
of_print_phandle_args("of_irq_parse_raw: ", out_irq);
|
|
#endif
|
|
|
|
ipar = of_node_get(out_irq->np);
|
|
|
|
/* First get the #interrupt-cells property of the current cursor
|
|
* that tells us how to interpret the passed-in intspec. If there
|
|
* is none, we are nice and just walk up the tree
|
|
*/
|
|
do {
|
|
if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize))
|
|
break;
|
|
tnode = ipar;
|
|
ipar = of_irq_find_parent(ipar);
|
|
of_node_put(tnode);
|
|
} while (ipar);
|
|
if (ipar == NULL) {
|
|
pr_debug(" -> no parent found !\n");
|
|
goto fail;
|
|
}
|
|
|
|
pr_debug("of_irq_parse_raw: ipar=%pOF, size=%d\n", ipar, intsize);
|
|
|
|
if (out_irq->args_count != intsize)
|
|
goto fail;
|
|
|
|
/* Look for this #address-cells. We have to implement the old linux
|
|
* trick of looking for the parent here as some device-trees rely on it
|
|
*/
|
|
old = of_node_get(ipar);
|
|
do {
|
|
tmp = of_get_property(old, "#address-cells", NULL);
|
|
tnode = of_get_parent(old);
|
|
of_node_put(old);
|
|
old = tnode;
|
|
} while (old && tmp == NULL);
|
|
of_node_put(old);
|
|
old = NULL;
|
|
addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);
|
|
|
|
pr_debug(" -> addrsize=%d\n", addrsize);
|
|
|
|
/* Range check so that the temporary buffer doesn't overflow */
|
|
if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) {
|
|
rc = -EFAULT;
|
|
goto fail;
|
|
}
|
|
|
|
/* Precalculate the match array - this simplifies match loop */
|
|
for (i = 0; i < addrsize; i++)
|
|
initial_match_array[i] = addr ? addr[i] : 0;
|
|
for (i = 0; i < intsize; i++)
|
|
initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
|
|
|
|
/* Now start the actual "proper" walk of the interrupt tree */
|
|
while (ipar != NULL) {
|
|
/* Now check if cursor is an interrupt-controller and if it is
|
|
* then we are done
|
|
*/
|
|
if (of_property_read_bool(ipar, "interrupt-controller")) {
|
|
pr_debug(" -> got it !\n");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* interrupt-map parsing does not work without a reg
|
|
* property when #address-cells != 0
|
|
*/
|
|
if (addrsize && !addr) {
|
|
pr_debug(" -> no reg passed in when needed !\n");
|
|
goto fail;
|
|
}
|
|
|
|
/* Now look for an interrupt-map */
|
|
imap = of_get_property(ipar, "interrupt-map", &imaplen);
|
|
/* No interrupt map, check for an interrupt parent */
|
|
if (imap == NULL) {
|
|
pr_debug(" -> no map, getting parent\n");
|
|
newpar = of_irq_find_parent(ipar);
|
|
goto skiplevel;
|
|
}
|
|
imaplen /= sizeof(u32);
|
|
|
|
/* Look for a mask */
|
|
imask = of_get_property(ipar, "interrupt-map-mask", NULL);
|
|
if (!imask)
|
|
imask = dummy_imask;
|
|
|
|
/* Parse interrupt-map */
|
|
match = 0;
|
|
while (imaplen > (addrsize + intsize + 1) && !match) {
|
|
/* Compare specifiers */
|
|
match = 1;
|
|
for (i = 0; i < (addrsize + intsize); i++, imaplen--)
|
|
match &= !((match_array[i] ^ *imap++) & imask[i]);
|
|
|
|
pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
|
|
|
|
/* Get the interrupt parent */
|
|
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
|
newpar = of_node_get(of_irq_dflt_pic);
|
|
else
|
|
newpar = of_find_node_by_phandle(be32_to_cpup(imap));
|
|
imap++;
|
|
--imaplen;
|
|
|
|
/* Check if not found */
|
|
if (newpar == NULL) {
|
|
pr_debug(" -> imap parent not found !\n");
|
|
goto fail;
|
|
}
|
|
|
|
if (!of_device_is_available(newpar))
|
|
match = 0;
|
|
|
|
/* Get #interrupt-cells and #address-cells of new
|
|
* parent
|
|
*/
|
|
if (of_property_read_u32(newpar, "#interrupt-cells",
|
|
&newintsize)) {
|
|
pr_debug(" -> parent lacks #interrupt-cells!\n");
|
|
goto fail;
|
|
}
|
|
if (of_property_read_u32(newpar, "#address-cells",
|
|
&newaddrsize))
|
|
newaddrsize = 0;
|
|
|
|
pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
|
|
newintsize, newaddrsize);
|
|
|
|
/* Check for malformed properties */
|
|
if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)
|
|
|| (imaplen < (newaddrsize + newintsize))) {
|
|
rc = -EFAULT;
|
|
goto fail;
|
|
}
|
|
|
|
imap += newaddrsize + newintsize;
|
|
imaplen -= newaddrsize + newintsize;
|
|
|
|
pr_debug(" -> imaplen=%d\n", imaplen);
|
|
}
|
|
if (!match)
|
|
goto fail;
|
|
|
|
/*
|
|
* Successfully parsed an interrrupt-map translation; copy new
|
|
* interrupt specifier into the out_irq structure
|
|
*/
|
|
match_array = imap - newaddrsize - newintsize;
|
|
for (i = 0; i < newintsize; i++)
|
|
out_irq->args[i] = be32_to_cpup(imap - newintsize + i);
|
|
out_irq->args_count = intsize = newintsize;
|
|
addrsize = newaddrsize;
|
|
|
|
skiplevel:
|
|
/* Iterate again with new parent */
|
|
out_irq->np = newpar;
|
|
pr_debug(" -> new parent: %pOF\n", newpar);
|
|
of_node_put(ipar);
|
|
ipar = newpar;
|
|
newpar = NULL;
|
|
}
|
|
rc = -ENOENT; /* No interrupt-map found */
|
|
|
|
fail:
|
|
of_node_put(ipar);
|
|
of_node_put(newpar);
|
|
|
|
return rc;
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_parse_raw);
|
|
|
|
/**
|
|
* of_irq_parse_one - Resolve an interrupt for a device
|
|
* @device: the device whose interrupt is to be resolved
|
|
* @index: index of the interrupt to resolve
|
|
* @out_irq: structure of_phandle_args filled by this function
|
|
*
|
|
* This function resolves an interrupt for a node by walking the interrupt tree,
|
|
* finding which interrupt controller node it is attached to, and returning the
|
|
* interrupt specifier that can be used to retrieve a Linux IRQ number.
|
|
*/
|
|
int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
|
|
{
|
|
struct device_node *p;
|
|
const __be32 *addr;
|
|
u32 intsize;
|
|
int i, res;
|
|
|
|
pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index);
|
|
|
|
/* OldWorld mac stuff is "special", handle out of line */
|
|
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
|
|
return of_irq_parse_oldworld(device, index, out_irq);
|
|
|
|
/* Get the reg property (if any) */
|
|
addr = of_get_property(device, "reg", NULL);
|
|
|
|
/* Try the new-style interrupts-extended first */
|
|
res = of_parse_phandle_with_args(device, "interrupts-extended",
|
|
"#interrupt-cells", index, out_irq);
|
|
if (!res)
|
|
return of_irq_parse_raw(addr, out_irq);
|
|
|
|
/* Look for the interrupt parent. */
|
|
p = of_irq_find_parent(device);
|
|
if (p == NULL)
|
|
return -EINVAL;
|
|
|
|
/* Get size of interrupt specifier */
|
|
if (of_property_read_u32(p, "#interrupt-cells", &intsize)) {
|
|
res = -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
pr_debug(" parent=%pOF, intsize=%d\n", p, intsize);
|
|
|
|
/* Copy intspec into irq structure */
|
|
out_irq->np = p;
|
|
out_irq->args_count = intsize;
|
|
for (i = 0; i < intsize; i++) {
|
|
res = of_property_read_u32_index(device, "interrupts",
|
|
(index * intsize) + i,
|
|
out_irq->args + i);
|
|
if (res)
|
|
goto out;
|
|
}
|
|
|
|
pr_debug(" intspec=%d\n", *out_irq->args);
|
|
|
|
|
|
/* Check if there are any interrupt-map translations to process */
|
|
res = of_irq_parse_raw(addr, out_irq);
|
|
out:
|
|
of_node_put(p);
|
|
return res;
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_parse_one);
|
|
|
|
/**
|
|
* of_irq_to_resource - Decode a node's IRQ and return it as a resource
|
|
* @dev: pointer to device tree node
|
|
* @index: zero-based index of the irq
|
|
* @r: pointer to resource structure to return result into.
|
|
*/
|
|
int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
|
{
|
|
int irq = of_irq_get(dev, index);
|
|
u32 trigger_type;
|
|
struct of_phandle_args oirq;
|
|
|
|
if (irq < 0)
|
|
return irq;
|
|
|
|
/* Only dereference the resource if both the
|
|
* resource and the irq are valid. */
|
|
if (r && irq) {
|
|
const char *name = NULL;
|
|
|
|
memset(r, 0, sizeof(*r));
|
|
/*
|
|
* Get optional "interrupt-names" property to add a name
|
|
* to the resource.
|
|
*/
|
|
of_property_read_string_index(dev, "interrupt-names", index,
|
|
&name);
|
|
|
|
trigger_type = irqd_get_trigger_type(irq_get_irq_data(irq));
|
|
|
|
of_irq_parse_one(dev, index, &oirq);
|
|
|
|
if (!trigger_type &&
|
|
of_device_is_compatible(oirq.np, "arm,gic-v3"))
|
|
pr_err("IRQ TYPE should not be NONE for %s\n",
|
|
dev->full_name);
|
|
|
|
r->start = r->end = irq;
|
|
r->flags = IORESOURCE_IRQ | trigger_type;
|
|
r->name = name ? name : of_node_full_name(dev);
|
|
}
|
|
|
|
return irq;
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
|
|
|
/**
|
|
* of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
|
|
* @dev: pointer to device tree node
|
|
* @index: zero-based index of the IRQ
|
|
*
|
|
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
|
|
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
|
|
* of any other failure.
|
|
*/
|
|
int of_irq_get(struct device_node *dev, int index)
|
|
{
|
|
int rc;
|
|
struct of_phandle_args oirq;
|
|
struct irq_domain *domain;
|
|
|
|
rc = of_irq_parse_one(dev, index, &oirq);
|
|
if (rc)
|
|
return rc;
|
|
|
|
domain = irq_find_host(oirq.np);
|
|
if (!domain)
|
|
return -EPROBE_DEFER;
|
|
|
|
return irq_create_of_mapping(&oirq);
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_get);
|
|
|
|
/**
|
|
* of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
|
|
* @dev: pointer to device tree node
|
|
* @name: IRQ name
|
|
*
|
|
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
|
|
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
|
|
* of any other failure.
|
|
*/
|
|
int of_irq_get_byname(struct device_node *dev, const char *name)
|
|
{
|
|
int index;
|
|
|
|
if (unlikely(!name))
|
|
return -EINVAL;
|
|
|
|
index = of_property_match_string(dev, "interrupt-names", name);
|
|
if (index < 0)
|
|
return index;
|
|
|
|
return of_irq_get(dev, index);
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_get_byname);
|
|
|
|
/**
|
|
* of_irq_count - Count the number of IRQs a node uses
|
|
* @dev: pointer to device tree node
|
|
*/
|
|
int of_irq_count(struct device_node *dev)
|
|
{
|
|
struct of_phandle_args irq;
|
|
int nr = 0;
|
|
|
|
while (of_irq_parse_one(dev, nr, &irq) == 0)
|
|
nr++;
|
|
|
|
return nr;
|
|
}
|
|
|
|
/**
|
|
* of_irq_to_resource_table - Fill in resource table with node's IRQ info
|
|
* @dev: pointer to device tree node
|
|
* @res: array of resources to fill in
|
|
* @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
|
|
*
|
|
* Returns the size of the filled in table (up to @nr_irqs).
|
|
*/
|
|
int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
|
|
int nr_irqs)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < nr_irqs; i++, res++)
|
|
if (of_irq_to_resource(dev, i, res) <= 0)
|
|
break;
|
|
|
|
return i;
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_irq_to_resource_table);
|
|
|
|
struct of_intc_desc {
|
|
struct list_head list;
|
|
of_irq_init_cb_t irq_init_cb;
|
|
struct device_node *dev;
|
|
struct device_node *interrupt_parent;
|
|
};
|
|
|
|
/**
|
|
* of_irq_init - Scan and init matching interrupt controllers in DT
|
|
* @matches: 0 terminated array of nodes to match and init function to call
|
|
*
|
|
* This function scans the device tree for matching interrupt controller nodes,
|
|
* and calls their initialization functions in order with parents first.
|
|
*/
|
|
void __init of_irq_init(const struct of_device_id *matches)
|
|
{
|
|
const struct of_device_id *match;
|
|
struct device_node *np, *parent = NULL;
|
|
struct of_intc_desc *desc, *temp_desc;
|
|
struct list_head intc_desc_list, intc_parent_list;
|
|
|
|
INIT_LIST_HEAD(&intc_desc_list);
|
|
INIT_LIST_HEAD(&intc_parent_list);
|
|
|
|
for_each_matching_node_and_match(np, matches, &match) {
|
|
if (!of_property_read_bool(np, "interrupt-controller") ||
|
|
!of_device_is_available(np))
|
|
continue;
|
|
|
|
if (WARN(!match->data, "of_irq_init: no init function for %s\n",
|
|
match->compatible))
|
|
continue;
|
|
|
|
/*
|
|
* Here, we allocate and populate an of_intc_desc with the node
|
|
* pointer, interrupt-parent device_node etc.
|
|
*/
|
|
desc = kzalloc(sizeof(*desc), GFP_KERNEL);
|
|
if (!desc) {
|
|
of_node_put(np);
|
|
goto err;
|
|
}
|
|
|
|
desc->irq_init_cb = match->data;
|
|
desc->dev = of_node_get(np);
|
|
desc->interrupt_parent = of_irq_find_parent(np);
|
|
if (desc->interrupt_parent == np)
|
|
desc->interrupt_parent = NULL;
|
|
list_add_tail(&desc->list, &intc_desc_list);
|
|
}
|
|
|
|
/*
|
|
* The root irq controller is the one without an interrupt-parent.
|
|
* That one goes first, followed by the controllers that reference it,
|
|
* followed by the ones that reference the 2nd level controllers, etc.
|
|
*/
|
|
while (!list_empty(&intc_desc_list)) {
|
|
/*
|
|
* Process all controllers with the current 'parent'.
|
|
* First pass will be looking for NULL as the parent.
|
|
* The assumption is that NULL parent means a root controller.
|
|
*/
|
|
list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
|
|
int ret;
|
|
|
|
if (desc->interrupt_parent != parent)
|
|
continue;
|
|
|
|
list_del(&desc->list);
|
|
|
|
of_node_set_flag(desc->dev, OF_POPULATED);
|
|
|
|
pr_debug("of_irq_init: init %pOF (%p), parent %p\n",
|
|
desc->dev,
|
|
desc->dev, desc->interrupt_parent);
|
|
ret = desc->irq_init_cb(desc->dev,
|
|
desc->interrupt_parent);
|
|
if (ret) {
|
|
of_node_clear_flag(desc->dev, OF_POPULATED);
|
|
kfree(desc);
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* This one is now set up; add it to the parent list so
|
|
* its children can get processed in a subsequent pass.
|
|
*/
|
|
list_add_tail(&desc->list, &intc_parent_list);
|
|
}
|
|
|
|
/* Get the next pending parent that might have children */
|
|
desc = list_first_entry_or_null(&intc_parent_list,
|
|
typeof(*desc), list);
|
|
if (!desc) {
|
|
pr_err("of_irq_init: children remain, but no parents\n");
|
|
break;
|
|
}
|
|
list_del(&desc->list);
|
|
parent = desc->dev;
|
|
kfree(desc);
|
|
}
|
|
|
|
list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
|
|
list_del(&desc->list);
|
|
kfree(desc);
|
|
}
|
|
err:
|
|
list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
|
|
list_del(&desc->list);
|
|
of_node_put(desc->dev);
|
|
kfree(desc);
|
|
}
|
|
}
|
|
|
|
static u32 __of_msi_map_rid(struct device *dev, struct device_node **np,
|
|
u32 rid_in)
|
|
{
|
|
struct device *parent_dev;
|
|
u32 rid_out = rid_in;
|
|
|
|
/*
|
|
* Walk up the device parent links looking for one with a
|
|
* "msi-map" property.
|
|
*/
|
|
for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent)
|
|
if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map",
|
|
"msi-map-mask", np, &rid_out))
|
|
break;
|
|
return rid_out;
|
|
}
|
|
|
|
/**
|
|
* of_msi_map_rid - Map a MSI requester ID for a device.
|
|
* @dev: device for which the mapping is to be done.
|
|
* @msi_np: device node of the expected msi controller.
|
|
* @rid_in: unmapped MSI requester ID for the device.
|
|
*
|
|
* Walk up the device hierarchy looking for devices with a "msi-map"
|
|
* property. If found, apply the mapping to @rid_in.
|
|
*
|
|
* Returns the mapped MSI requester ID.
|
|
*/
|
|
u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in)
|
|
{
|
|
return __of_msi_map_rid(dev, &msi_np, rid_in);
|
|
}
|
|
|
|
/**
|
|
* of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain
|
|
* @dev: device for which the mapping is to be done.
|
|
* @rid: Requester ID for the device.
|
|
*
|
|
* Walk up the device hierarchy looking for devices with a "msi-map"
|
|
* property.
|
|
*
|
|
* Returns: the MSI domain for this device (or NULL on failure)
|
|
*/
|
|
struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid)
|
|
{
|
|
struct device_node *np = NULL;
|
|
|
|
__of_msi_map_rid(dev, &np, rid);
|
|
return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
|
|
}
|
|
|
|
/**
|
|
* of_msi_get_domain - Use msi-parent to find the relevant MSI domain
|
|
* @dev: device for which the domain is requested
|
|
* @np: device node for @dev
|
|
* @token: bus type for this domain
|
|
*
|
|
* Parse the msi-parent property (both the simple and the complex
|
|
* versions), and returns the corresponding MSI domain.
|
|
*
|
|
* Returns: the MSI domain for this device (or NULL on failure).
|
|
*/
|
|
struct irq_domain *of_msi_get_domain(struct device *dev,
|
|
struct device_node *np,
|
|
enum irq_domain_bus_token token)
|
|
{
|
|
struct device_node *msi_np;
|
|
struct irq_domain *d;
|
|
|
|
/* Check for a single msi-parent property */
|
|
msi_np = of_parse_phandle(np, "msi-parent", 0);
|
|
if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) {
|
|
d = irq_find_matching_host(msi_np, token);
|
|
if (!d)
|
|
of_node_put(msi_np);
|
|
return d;
|
|
}
|
|
|
|
if (token == DOMAIN_BUS_PLATFORM_MSI) {
|
|
/* Check for the complex msi-parent version */
|
|
struct of_phandle_args args;
|
|
int index = 0;
|
|
|
|
while (!of_parse_phandle_with_args(np, "msi-parent",
|
|
"#msi-cells",
|
|
index, &args)) {
|
|
d = irq_find_matching_host(args.np, token);
|
|
if (d)
|
|
return d;
|
|
|
|
of_node_put(args.np);
|
|
index++;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* of_msi_configure - Set the msi_domain field of a device
|
|
* @dev: device structure to associate with an MSI irq domain
|
|
* @np: device node for that device
|
|
*/
|
|
void of_msi_configure(struct device *dev, struct device_node *np)
|
|
{
|
|
dev_set_msi_domain(dev,
|
|
of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
|
|
}
|
|
EXPORT_SYMBOL_GPL(of_msi_configure);
|