android_kernel_xiaomi_sm8450/drivers/remoteproc/qcom_q6v5_mss.c
Srinivasarao Pathipati c1db035d70 Merge keystone/android12-5.10-keystone-qcom-release.177+ (7f7ea82) into msm-5.10
* refs/heads/tmp-7f7ea82:
  UPSTREAM: usb: gadget: udc: renesas_usb3: Fix use after free bug in renesas_usb3_remove due to race condition
  UPSTREAM: media: rkvdec: fix use after free bug in rkvdec_remove
  UPSTREAM: x86/mm: Avoid using set_pgd() outside of real PGD pages
  UPSTREAM: relayfs: fix out-of-bounds access in relay_file_read
  UPSTREAM: io_uring: hold uring mutex around poll removal
  UPSTREAM: net/sched: flower: fix possible OOB write in fl_set_geneve_opt()
  UPSTREAM: ipvlan:Fix out-of-bounds caused by unclear skb->cb
  ANDROID: GKI: Update symbols to symbol list
  ANDROID: vendor_hook: Add hook to tune readaround size
  ANDROID: vendor_hooks: Add hooks to avoid key threads stalled in memory allocations
  UPSTREAM: f2fs: fix to avoid use-after-free for cached IPU bio
  UPSTREAM: net/sched: cls_u32: Fix reference counter leak leading to overflow
  UPSTREAM: xfs: verify buffer contents when we skip log replay
  UPSTREAM: memstick: r592: Fix UAF bug in r592_remove due to race condition
  BACKPORT: btrfs: unset reloc control if transaction commit fails in prepare_to_relocate()
  ANDROID: ABI: Update oplus symbol list
  ANDROID: Export memcg functions to allow module to add new files
  ANDROID: HID: Only utilise UHID provided exports if UHID is enabled
  UPSTREAM: bluetooth: Perform careful capability checks in hci_sock_ioctl()
  ANDROID: HID; Over-ride default maximum buffer size when using UHID
  UPSTREAM: usb: gadget: f_fs: Add unbind event before functionfs_unbind
  UPSTREAM: net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize
  ANDROID: GKI: update symbol list for exynos
  UPSTREAM: mailbox: mailbox-test: fix a locking issue in mbox_test_message_write()
  UPSTREAM: mailbox: mailbox-test: Fix potential double-free in mbox_test_message_write()
  UPSTREAM: 9p/xen : Fix use after free bug in xen_9pfs_front_remove due to race condition
  FROMGIT: pstore: Revert pmsg_lock back to a normal mutex
  ANDROID: vendor_hook: Avoid clearing protect-flag before waking waiters
  ANDROID: fix a race between speculative page walk and unmap operations
  BACKPORT: usb: gadget: udc: Handle gadget_connect failure during bind operation
  BACKPORT: usb: dwc3: gadget: Bail out in pullup if soft reset timeout happens
  BACKPORT: f2fs: skip GC if possible when checkpoint disabling
  UPSTREAM: KVM: x86: do not report a vCPU as preempted outside instruction boundaries
  ANDROID: remove CONFIG_NET_CLS_TCINDEX from gki_defconfig
  BACKPORT: net/sched: Retire tcindex classifier
  FROMLIST: usb: xhci: Remove unused udev from xhci_log_ctx trace event
  UPSTREAM: ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum
  ANDROID: GKI: Update symbols to symbol list
  ANDROID: vendor_hook: add hooks in dm_bufio.c
  ANDROID: GKI: Update symbol list for mtk
  UPSTREAM: ext4: fix invalid free tracking in ext4_xattr_move_to_block()
  ANDROID: uid_sys_stats: defer process_notifier work if uid_lock is contended
  Revert "net: mdio: fix owner field for mdio buses registered using device-tree"
  Linux 5.10.177
  hsr: ratelimit only when errors are printed
  gfs2: Always check inode size of inline inodes
  ext4: fix kernel BUG in 'ext4_write_inline_data_end()'
  libbpf: Fix btf_dump's packed struct determination
  selftests/bpf: Add few corner cases to test padding handling of btf_dump
  libbpf: Fix BTF-to-C converter's padding logic
  selftests/bpf: Test btf dump for struct with padding only fields
  zonefs: Fix error message in zonefs_file_dio_append()
  btrfs: scan device in non-exclusive mode
  s390/uaccess: add missing earlyclobber annotations to __clear_user()
  drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub
  drm/etnaviv: fix reference leak when mmaping imported buffer
  rcu: Fix rcu_torture_read ftrace event
  xtensa: fix KASAN report for show_stack
  ALSA: hda/realtek: Add quirk for Lenovo ZhaoYang CF4620Z
  ALSA: usb-audio: Fix regression on detection of Roland VS-100
  ALSA: hda/conexant: Partial revert of a quirk for Lenovo
  NFSv4: Fix hangs when recovering open state after a server reboot
  powerpc: Don't try to copy PPR for task with NULL pt_regs
  pinctrl: at91-pio4: fix domain name assignment
  pinctrl: amd: Disable and mask interrupts on resume
  net: phy: dp83869: fix default value for tx-/rx-internal-delay
  xen/netback: don't do grant copy across page boundary
  btrfs: fix race between quota disable and quota assign ioctls
  Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table
  cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL
  cifs: prevent infinite recursion in CIFSGetDFSRefer()
  Input: focaltech - use explicitly signed char type
  Input: alps - fix compatibility with -funsigned-char
  pinctrl: ocelot: Fix alt mode for ocelot
  net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only
  bnxt_en: Add missing 200G link speed reporting
  bnxt_en: Fix typo in PCI id to device description string mapping
  i40e: fix registers dump after run ethtool adapter self test
  net: ipa: compute DMA pool size properly
  ALSA: ymfpci: Fix BUG_ON in probe function
  ALSA: ymfpci: Fix assignment in if condition
  s390/vfio-ap: fix memory leak in vfio_ap device driver
  can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write
  net: stmmac: don't reject VLANs when IFF_PROMISC is set
  net/net_failover: fix txq exceeding warning
  regulator: Handle deferred clk
  r8169: fix RTL8168H and RTL8107E rx crc error
  ptp_qoriq: fix memory leak in probe()
  scsi: megaraid_sas: Fix crash after a double completion
  sfc: ef10: don't overwrite offload features at NIC reset
  mtd: rawnand: meson: invalidate cache on polling ECC bit
  mips: bmips: BCM6358: disable RAC flush for TP1
  ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx()
  tracing: Fix wrong return in kprobe_event_gen_test.c
  tools/power turbostat: Fix /dev/cpu_dma_latency warnings
  fbdev: au1200fb: Fix potential divide by zero
  fbdev: lxfb: Fix potential divide by zero
  fbdev: intelfb: Fix potential divide by zero
  fbdev: nvidia: Fix potential divide by zero
  sched_getaffinity: don't assume 'cpumask_size()' is fully initialized
  fbdev: tgafb: Fix potential divide by zero
  ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set()
  ALSA: asihpi: check pao in control_message()
  net: hsr: Don't log netdev_err message on unknown prp dst node
  md: avoid signed overflow in slot_store()
  fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY
  dm crypt: avoid accessing uninitialized tasklet
  bus: imx-weim: fix branch condition evaluates to a garbage value
  drm/meson: fix missing component unbind on bind errors
  drm/meson: Fix error handling when afbcd.ops->init fails
  kcsan: avoid passing -g for test
  kernel: kcsan: kcsan_test: build without structleak plugin
  usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC
  usb: dwc3: gadget: move cmd_endtransfer to extra function
  NFSD: fix use-after-free in __nfs42_ssc_open()
  KVM: fix memoryleak in kvm_init()
  xfs: don't reuse busy extents on extent trim
  xfs: shut down the filesystem if we screw up quota reservation
  ocfs2: fix data corruption after failed write
  sched/fair: Sanitize vruntime of entity being migrated
  sched/fair: sanitize vruntime of entity being placed
  dm crypt: add cond_resched() to dmcrypt_write()
  dm stats: check for and propagate alloc_percpu failure
  i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer()
  firmware: arm_scmi: Fix device node validation for mailbox transport
  tee: amdtee: fix race condition in amdtee_open_session
  drm/i915: Preserve crtc_state->inherited during state clearing
  drm/i915/active: Fix missing debug object activation
  nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy()
  wifi: mac80211: fix qos on mesh interfaces
  usb: ucsi: Fix NULL pointer deref in ucsi_connector_change()
  usb: chipidea: core: fix possible concurrent when switch role
  usb: chipdea: core: fix return -EINVAL if request role is the same with current role
  usb: cdns3: Fix issue with using incorrect PCI device function
  dm thin: fix deadlock when swapping to thin device
  igb: revert rtnl_lock() that causes deadlock
  fsverity: Remove WQ_UNBOUND from fsverity read workqueue
  usb: gadget: u_audio: don't let userspace block driver unbind
  usb: dwc2: fix a devres leak in hw_enable upon suspend resume
  scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR
  cifs: empty interface list when server doesn't support query interfaces
  sh: sanitize the flags on sigreturn
  net: usb: qmi_wwan: add Telit 0x1080 composition
  net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990
  scsi: storvsc: Handle BlockSize change in Hyper-V VHD/VHDX file
  scsi: lpfc: Avoid usage of list iterator variable after loop
  scsi: ufs: core: Add soft dependency on governor_simpleondemand
  scsi: hisi_sas: Check devm_add_action() return value
  scsi: target: iscsi: Fix an error message in iscsi_check_key()
  selftests/bpf: check that modifier resolves after pointer
  m68k: Only force 030 bus error if PC not in exception table
  ca8210: fix mac_len negative array access
  HID: cp2112: Fix driver not registering GPIO IRQ chip as threaded
  riscv: Bump COMMAND_LINE_SIZE value to 1024
  thunderbolt: Use const qualifier for `ring_interrupt_index`
  thunderbolt: Use scale field when allocating USB3 bandwidth
  uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2
  scsi: qla2xxx: Perform lockless command completion in abort path
  hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs
  hwmon: fix potential sensor registration fail if of_node is missing
  platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl
  Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work
  Bluetooth: L2CAP: Fix responding with wrong PDU type
  Bluetooth: L2CAP: Fix not checking for maximum number of DCID
  Bluetooth: btqcomsmd: Fix command timeout after setting BD address
  net: mdio: thunder: Add missing fwnode_handle_put()
  gve: Cache link_speed value from device
  nvme-tcp: fix nvme_tcp_term_pdu to match spec
  net/sonic: use dma_mapping_error() for error check
  erspan: do not use skb_mac_header() in ndo_start_xmit()
  atm: idt77252: fix kmemleak when rmmod idt77252
  net/mlx5: E-Switch, Fix an Oops in error handling code
  net/mlx5: Read the TC mapping of all priorities on ETS query
  net/mlx5: Fix steering rules cleanup
  bpf: Adjust insufficient default bpf_jit_limit
  keys: Do not cache key in task struct if key is requested from kernel thread
  bootconfig: Fix testcase to increase max node
  net/ps3_gelic_net: Use dma_mapping_error
  net/ps3_gelic_net: Fix RX sk_buff length
  net: qcom/emac: Fix use after free bug in emac_remove due to race condition
  net: mdio: fix owner field for mdio buses registered using device-tree
  net: phy: Ensure state transitions are processed from phy_stop()
  xirc2ps_cs: Fix use after free bug in xirc2ps_detach
  qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info
  net: usb: smsc95xx: Limit packet length to skb->len
  scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate()
  i2c: imx-lpi2c: check only for enabled interrupt flags
  igc: fix the validation logic for taprio's gate list
  igbvf: Regard vf reset nack as success
  intel/igbvf: free irq on the error path in igbvf_request_msix()
  iavf: fix non-tunneled IPv6 UDP packet type and hashing
  iavf: fix inverted Rx hash condition leading to disabled hash
  xsk: Add missing overflow check in xdp_umem_reg
  ARM: dts: imx6sl: tolino-shine2hd: fix usbotg1 pinctrl
  ARM: dts: imx6sll: e60k02: fix usbotg1 pinctrl
  power: supply: da9150: Fix use after free bug in da9150_charger_remove due to race condition
  power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition
  power: supply: bq24190_charger: using pm_runtime_resume_and_get instead of pm_runtime_get_sync
  net: tls: fix possible race condition between do_tls_getsockopt_conf() and do_tls_setsockopt_conf()
  drm/sun4i: fix missing component unbind on bind errors
  serial: 8250: ASPEED_VUART: select REGMAP instead of depending on it
  serial: 8250: SERIAL_8250_ASPEED_VUART should depend on ARCH_ASPEED
  tty: serial: fsl_lpuart: fix race on RX DMA shutdown
  serial: fsl_lpuart: Fix comment typo
  KVM: Register /dev/kvm as the _very_ last thing during initialization
  KVM: Pre-allocate cpumasks for kvm_make_all_cpus_request_except()
  KVM: Optimize kvm_make_vcpus_request_mask() a bit
  KVM: KVM: Use cpumask_available() to check for NULL cpumask when kicking vCPUs
  KVM: Clean up benign vcpu->cpu data races when kicking vCPUs
  ipmi:ssif: Add a timer between request retries
  ipmi:ssif: resend_msg() cannot fail
  ipmi:ssif: Increase the message retry time
  ipmi:ssif: make ssif_i2c_send() void
  perf: fix perf_event_context->time
  perf/core: Fix perf_output_begin parameter is incorrectly invoked in perf_event_bpf_output
  interconnect: qcom: osm-l3: fix icc_onecell_data allocation
  Revert "HID: core: Provide new max_buffer_size attribute to over-ride the default"
  Revert "HID: uhid: Over-ride the default maximum data buffer value with our own"
  ANDROID: preserve CRC for __irq_domain_add()
  Revert "PCI: loongson: Prevent LS7A MRRS increases"
  Revert "PCI: loongson: Add more devices that need MRRS quirk"
  ANDROID: remove CONFIG_NET_CLS_TCINDEX from gki_defconfig
  Linux 5.10.176
  HID: uhid: Over-ride the default maximum data buffer value with our own
  HID: core: Provide new max_buffer_size attribute to over-ride the default
  xfs: remove xfs_setattr_time() declaration
  fs: use consistent setgid checks in is_sxid()
  attr: use consistent sgid stripping checks
  attr: add setattr_should_drop_sgid()
  fs: move should_remove_suid()
  attr: add in_group_or_capable()
  fs: move S_ISGID stripping into the vfs_*() helpers
  fs: add mode_strip_sgid() helper
  xfs: use setattr_copy to set vfs inode attributes
  xfs: set prealloc flag in xfs_alloc_file_space()
  xfs: fallocate() should call file_modified()
  xfs: remove XFS_PREALLOC_SYNC
  xfs: don't leak btree cursor when insrec fails after a split
  xfs: purge dquots after inode walk fails during quotacheck
  xfs: don't assert fail on perag references on teardown
  PCI/DPC: Await readiness of secondary bus after reset
  PCI: Unify delay handling for reset and resume
  s390/ipl: add missing intersection check to ipl_report handling
  io_uring: avoid null-ptr-deref in io_arm_poll_handler
  drm/i915/active: Fix misuse of non-idle barriers as fence trackers
  drm/i915: Don't use stolen memory for ring buffers with LLC
  x86/mm: Fix use of uninitialized buffer in sme_enable()
  x86/mce: Make sure logged MCEs are processed after sysfs update
  cpuidle: psci: Iterate backwards over list in psci_pd_remove()
  fbdev: stifb: Provide valid pixelclock and add fb_check_var() checks
  mmc: sdhci_am654: lower power-on failed message severity
  mm/userfaultfd: propagate uffd-wp bit when PTE-mapping the huge zeropage
  ftrace: Fix invalid address access in lookup_rec() when index is 0
  mptcp: avoid setting TCP_CLOSE state twice
  drm/shmem-helper: Remove another errant put in error path
  ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book2 Pro
  ALSA: hda: intel-dsp-config: add MTL PCI id
  KVM: nVMX: add missing consistency checks for CR0 and CR4
  cifs: Fix smb2_set_path_size()
  tracing: Make tracepoint lockdep check actually test something
  tracing: Check field value in hist_field_name()
  tracing: Make splice_read available again
  interconnect: fix mem leak when freeing nodes
  firmware: xilinx: don't make a sleepable memory allocation from an atomic context
  serial: 8250_em: Fix UART port type
  tty: serial: fsl_lpuart: skip waiting for transmission complete when UARTCTRL_SBK is asserted
  ext4: fix possible double unlock when moving a directory
  drm/amd/display: fix shift-out-of-bounds in CalculateVMAndRowBytes
  sh: intc: Avoid spurious sizeof-pointer-div warning
  drm/amdkfd: Fix an illegal memory access
  ext4: fix task hung in ext4_xattr_delete_inode
  ext4: fail ext4_iget if special inode unallocated
  jffs2: correct logic when creating a hole in jffs2_write_begin
  mmc: atmel-mci: fix race between stop command and start of next command
  media: m5mols: fix off-by-one loop termination error
  hwmon: (adm1266) Set `can_sleep` flag for GPIO chip
  hwmon: tmp512: drop of_match_ptr for ID table
  hwmon: (ucd90320) Add minimum delay between bus accesses
  hwmon: (ina3221) return prober error code
  hwmon: (xgene) Fix use after free bug in xgene_hwmon_remove due to race condition
  hwmon: (adt7475) Fix masking of hysteresis registers
  hwmon: (adt7475) Display smoothing attributes in correct order
  ethernet: sun: add check for the mdesc_grab()
  qed/qed_mng_tlv: correctly zero out ->min instead of ->hour
  selftests: net: devlink_port_split.py: skip test if no suitable device available
  net/iucv: Fix size of interrupt data
  net: usb: smsc75xx: Move packet length check to prevent kernel panic in skb_pull
  ipv4: Fix incorrect table ID in IOCTL path
  net: dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250, 6290
  ice: xsk: disable txq irq before flushing hw
  block: sunvdc: add check for mdesc_grab() returning NULL
  nvmet: avoid potential UAF in nvmet_req_complete()
  nvme: fix handling single range discard request
  block: null_blk: Fix handling of fake timeout request
  null_blk: Move driver into its own directory
  drm/bridge: Fix returned array size name for atomic_get_input_bus_fmts kdoc
  net: usb: smsc75xx: Limit packet length to skb->len
  net/smc: fix deadlock triggered by cancel_delayed_work_syn()
  nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition
  net: phy: smsc: bail out in lan87xx_read_status if genphy_read_status fails
  net: tunnels: annotate lockless accesses to dev->needed_headroom
  qed/qed_dev: guard against a possible division by zero
  net/smc: fix NULL sndbuf_desc in smc_cdc_tx_handler()
  i40e: Fix kernel crash during reboot when adapter is in recovery mode
  ipvlan: Make skb->skb_iif track skb->dev for l3s mode
  nfc: pn533: initialize struct pn533_out_arg properly
  tcp: tcp_make_synack() can be called from process context
  scsi: core: Fix a procfs host directory removal regression
  scsi: core: Fix a comment in function scsi_host_dev_release()
  netfilter: nft_redir: correct value of inet type `.maxattrs`
  netfilter: nft_redir: correct length for loading protocol registers
  netfilter: nft_masq: correct length for loading protocol registers
  netfilter: nft_nat: correct length for loading protocol registers
  ALSA: hda: Match only Intel devices with CONTROLLER_IN_GPU()
  scsi: mpt3sas: Fix NULL pointer access in mpt3sas_transport_port_add()
  docs: Correct missing "d_" prefix for dentry_operations member d_weak_revalidate
  clk: HI655X: select REGMAP instead of depending on it
  drm/meson: fix 1px pink line on GXM when scaling video overlay
  cifs: Move the in_send statistic to __smb_send_rqst()
  drm/panfrost: Don't sync rpm suspension after mmu flushing
  xfrm: Allow transport-mode states with AF_UNSPEC selector
  Linux 5.10.175
  s390/dasd: add missing discipline function
  KVM: VMX: Fix crash due to uninitialized current_vmcs
  KVM: VMX: Introduce vmx_msr_bitmap_l01_changed() helper
  KVM: nVMX: Don't use Enlightened MSR Bitmap for L3
  UML: define RUNTIME_DISCARD_EXIT
  sh: define RUNTIME_DISCARD_EXIT
  s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36
  powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds
  powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT
  arch: fix broken BuildID for arm64 and riscv
  ext4: block range must be validated before use in ext4_mb_clear_bb()
  ext4: add strict range checks while freeing blocks
  ext4: add ext4_sb_block_valid() refactored out of ext4_inode_block_valid()
  ext4: refactor ext4_free_blocks() to pull out ext4_mb_clear_bb()
  drm/i915: Don't use BAR mappings for ring buffers with LLC
  skbuff: Fix nfct leak on napi stolen
  ipmi:watchdog: Set panic count to proper value on a panic
  ipmi/watchdog: replace atomic_add() and atomic_sub()
  media: rc: gpio-ir-recv: add remove function
  media: ov5640: Fix analogue gain control
  scripts: handle BrokenPipeError for python scripts
  PCI: Add SolidRun vendor ID
  macintosh: windfarm: Use unsigned type for 1-bit bitfields
  alpha: fix R_ALPHA_LITERAL reloc for large modules
  powerpc/kcsan: Exclude udelay to prevent recursive instrumentation
  MIPS: Fix a compilation issue
  block, bfq: fix uaf for bfqq in bic_set_bfqq()
  block, bfq: replace 0/1 with false/true in bic apis
  block/bfq-iosched.c: use "false" rather than "BLK_RW_ASYNC"
  block, bfq: fix uaf for bfqq in bfq_exit_icq_bfqq
  block, bfq: fix possible uaf for 'bfqq->bic'
  tpm/eventlog: Don't abort tpm_read_log on faulty ACPI address
  watch_queue: fix IOC_WATCH_QUEUE_SET_SIZE alloc error paths
  iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter
  ext4: Fix deadlock during directory rename
  RISC-V: Don't check text_mutex during stop_machine
  riscv: Use READ_ONCE_NOCHECK in imprecise unwinding stack mode
  SUNRPC: Fix a server shutdown leak
  net/smc: fix fallback failed while sendmsg with fastopen
  platform: x86: MLX_PLATFORM: select REGMAP instead of depending on it
  scsi: megaraid_sas: Update max supported LD IDs to 240
  net: ethernet: mtk_eth_soc: fix RX data corruption issue
  btf: fix resolving BTF_KIND_VAR after ARRAY, STRUCT, UNION, PTR
  netfilter: tproxy: fix deadlock due to missing BH disable
  netfilter: ctnetlink: revert to dumping mark regardless of event type
  bnxt_en: Avoid order-5 memory allocation for TPA data
  net: phylib: get rid of unnecessary locking
  net: stmmac: add to set device wake up flag when stmmac init phy
  net: caif: Fix use-after-free in cfusbl_device_notify()
  net: lan78xx: fix accessing the LAN7800's internal phy specific registers from the MAC driver
  net: usb: lan78xx: Remove lots of set but unused 'ret' variables
  selftests: nft_nat: ensuring the listening side is up before starting the client
  ila: do not generate empty messages in ila_xlat_nl_cmd_get_mapping()
  powerpc: dts: t1040rdb: fix compatible string for Rev A boards
  nfc: fdp: add null check of devm_kmalloc_array in fdp_nci_i2c_read_device_properties
  bgmac: fix *initial* chip reset to support BCM5358
  drm/msm/a5xx: fix context faults during ring switch
  drm/msm/a5xx: fix the emptyness check in the preempt code
  drm/msm: Document and rename preempt_lock
  drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register
  drm/msm: Fix potential invalid ptr free
  drm/nouveau/kms/nv50: fix nv50_wndw_new_ prototype
  drm/nouveau/kms/nv50-: remove unused functions
  ext4: Fix possible corruption when moving a directory
  scsi: core: Remove the /proc/scsi/${proc_name} directory earlier
  riscv: Add header include guards to insn.h
  riscv: Avoid enabling interrupts in die()
  RISC-V: Avoid dereferening NULL regs in die()
  arm64: efi: Make efi_rt_lock a raw_spinlock
  iommu/vt-d: Fix PASID directory pointer coherency
  iommu/vt-d: Fix lockdep splat in intel_pasid_get_entry()
  irqdomain: Fix domain registration race
  irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent
  irqdomain: Fix mapping-creation race
  irqdomain: Refactor __irq_domain_alloc_irqs()
  irqdomain: Look for existing mapping only once
  irq: Fix typos in comments
  udf: Fix off-by-one error when discarding preallocation
  nfc: change order inside nfc_se_io error path
  ext4: zero i_disksize when initializing the bootloader inode
  ext4: fix WARNING in ext4_update_inline_data
  ext4: move where set the MAY_INLINE_DATA flag is set
  ext4: fix another off-by-one fsmap error on 1k block filesystems
  ext4: fix RENAME_WHITEOUT handling for inline directories
  ext4: fix cgroup writeback accounting with fs-layer encryption
  drm/connector: print max_requested_bpc in state debugfs
  drm/amdgpu: fix error checking in amdgpu_read_mm_registers for soc15
  x86/CPU/AMD: Disable XSAVES on AMD family 0x17
  fork: allow CLONE_NEWTIME in clone3 flags
  fs: prevent out-of-bounds array speculation when closing a file descriptor
  Linux 5.10.174
  staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh
  staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script
  wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext"
  Linux 5.10.173
  usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails
  malidp: Fix NULL vs IS_ERR() checking
  scsi: mpt3sas: Remove usage of dma_get_required_mask() API
  scsi: mpt3sas: re-do lost mpt3sas DMA mask fix
  scsi: mpt3sas: Don't change DMA mask while reallocating pools
  Revert "scsi: mpt3sas: Fix return value check of dma_get_required_mask()"
  media: uvcvideo: Fix race condition with usb_kill_urb
  media: uvcvideo: Provide sync and async uvc_ctrl_status_event
  drm/virtio: Fix error code in virtio_gpu_object_shmem_init()
  tcp: Fix listen() regression in 5.10.163
  Bluetooth: hci_sock: purge socket queues in the destruct() callback
  drm/display/dp_mst: Fix down message handling after a packet reception error
  drm/display/dp_mst: Fix down/up message handling after sink disconnect
  x86/resctl: fix scheduler confusion with 'current'
  x86/resctrl: Apply READ_ONCE/WRITE_ONCE to task_struct.{rmid,closid}
  net: tls: avoid hanging tasks on the tx_lock
  soundwire: cadence: Drain the RX FIFO after an IO timeout
  soundwire: cadence: Remove wasted space in response_buf
  phy: rockchip-typec: Fix unsigned comparison with less than zero
  PCI: Add ACS quirk for Wangxun NICs
  PCI: loongson: Add more devices that need MRRS quirk
  kernel/fail_function: fix memory leak with using debugfs_lookup()
  PCI: Take other bus devices into account when distributing resources
  PCI: Align extra resources for hotplug bridges properly
  usb: gadget: uvc: Make bSourceID read/write
  usb: uvc: Enumerate valid values for color matching
  USB: ene_usb6250: Allocate enough memory for full object
  usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer math
  PCI: loongson: Prevent LS7A MRRS increases
  iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_config_word()
  iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_status_word()
  tools/iio/iio_utils:fix memory leak
  mei: bus-fixup:upon error print return values of send and receive
  serial: sc16is7xx: setup GPIO controller later in probe
  tty: serial: fsl_lpuart: disable the CTS when send break signal
  tty: fix out-of-bounds access in tty_driver_lookup_tty()
  staging: emxx_udc: Add checks for dma_alloc_coherent()
  media: uvcvideo: Silence memcpy() run-time false positive warnings
  media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910
  media: uvcvideo: Handle errors from calls to usb_string
  media: uvcvideo: Handle cameras with invalid descriptors
  IB/hfi1: Update RMT size calculation
  mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak
  bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC support
  firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
  tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
  thermal: intel: BXT_PMIC: select REGMAP instead of depending on it
  thermal: intel: quark_dts: fix error pointer dereference
  ASoC: zl38060 add gpiolib dependency
  ASoC: zl38060: Remove spurious gpiolib select
  ASoC: adau7118: don't disable regulators on device unbind
  loop: loop_set_status_from_info() check before assignment
  scsi: ipr: Work around fortify-string warning
  rtc: sun6i: Always export the internal oscillator
  vc_screen: modify vcs_size() handling in vcs_read()
  tcp: tcp_check_req() can be called from process context
  ARM: dts: spear320-hmi: correct STMPE GPIO compatible
  net/sched: act_sample: fix action bind logic
  nfc: fix memory leak of se_io context in nfc_genl_se_io
  net/mlx5: Geneve, Fix handling of Geneve object id as error code
  9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
  9p/xen: fix connection sequence
  9p/xen: fix version parsing
  net: fix __dev_kfree_skb_any() vs drop monitor
  sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop
  ipv6: Add lwtunnel encap size of all siblings in nexthop calculation
  netfilter: ebtables: fix table blob use-after-free
  netfilter: ctnetlink: fix possible refcount leak in ctnetlink_create_conntrack()
  watchdog: pcwd_usb: Fix attempting to access uninitialized memory
  watchdog: Fix kmemleak in watchdog_cdev_register
  watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in error path
  x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list
  ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
  ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
  ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling fastmap
  ubifs: ubifs_writepage: Mark page dirty after writing inode failed
  ubifs: dirty_cow_znode: Fix memleak in error handling path
  ubifs: Re-statistic cleaned znode count if commit failed
  ubi: Fix possible null-ptr-deref in ubi_free_volume()
  ubifs: Fix memory leak in alloc_wbufs()
  ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume()
  ubi: Fix use-after-free when volume resizing failed
  ubifs: Reserve one leb for each journal head while doing budget
  ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1
  ubifs: Fix wrong dirty space budget for dirty inode
  ubifs: Rectify space budget for ubifs_xrename()
  ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted
  ubifs: Fix build errors as symbol undefined
  ubi: ensure that VID header offset + VID header size <= alloc, size
  um: vector: Fix memory leak in vector_config
  fs: f2fs: initialize fsdata in pagecache_write()
  f2fs: use memcpy_{to,from}_page() where possible
  pwm: stm32-lp: fix the check on arr and cmp registers update
  pwm: sifive: Always let the first pwm_apply_state succeed
  pwm: sifive: Reduce time the controller lock is held
  objtool: Fix memory leak in create_static_call_sections()
  fs/jfs: fix shift exponent db_agl2size negative
  net/sched: Retire tcindex classifier
  kbuild: Port silent mode detection to future gnu make.
  pinctrl: rockchip: fix reading pull type on rk3568
  pinctrl: rockchip: fix mux route data for rk3568
  wifi: ath9k: use proper statements in conditionals
  arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY
  drm/edid: fix AVI infoframe aspect ratio handling
  drm/radeon: Fix eDP for single-display iMac11,2
  drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv
  vfio/type1: prevent underflow of locked_vm via exec()
  PCI: Avoid FLR for AMD FCH AHCI adapters
  PCI: hotplug: Allow marking devices as disconnected during bind/unbind
  PCI/PM: Observe reset delay irrespective of bridge_d3
  riscv: jump_label: Fixup unaligned arch_static_branch function
  scsi: ses: Fix slab-out-of-bounds in ses_intf_remove()
  scsi: ses: Fix possible desc_ptr out-of-bounds accesses
  scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
  scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process()
  scsi: ses: Don't attach if enclosure has no components
  scsi: qla2xxx: Fix erroneous link down
  scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests
  scsi: qla2xxx: Fix link failure in NPIV environment
  ring-buffer: Handle race between rb_move_tail and rb_check_pages
  ktest.pl: Add RUN_TIMEOUT option with default unlimited
  ktest.pl: Fix missing "end_monitor" when machine check fails
  ktest.pl: Give back console on Ctrt^C on monitor
  mm/thp: check and bail out if page in deferred queue already
  mm: memcontrol: deprecate charge moving
  docs: gdbmacros: print newest record
  remoteproc/mtk_scp: Move clk ops outside send_lock
  media: ipu3-cio2: Fix PM runtime usage_count in driver unbind
  mips: fix syscall_get_nr
  dax/kmem: Fix leak of memory-hotplug resources
  alpha: fix FEN fault handling
  rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails
  ARM: dts: exynos: correct TMU phandle in Odroid HC1
  ARM: dts: exynos: correct TMU phandle in Odroid XU
  ARM: dts: exynos: correct TMU phandle in Exynos5250
  ARM: dts: exynos: correct TMU phandle in Odroid XU3 family
  ARM: dts: exynos: correct TMU phandle in Exynos4
  ARM: dts: exynos: correct TMU phandle in Exynos4210
  dm flakey: don't corrupt the zero page
  dm flakey: fix logic when corrupting a bio
  thermal: intel: powerclamp: Fix cur_state for multi package system
  wifi: cfg80211: Fix use after free for wext
  wifi: rtl8xxxu: Use a longer retry limit of 48
  dm: add cond_resched() to dm_wq_work()
  mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type
  ext4: refuse to create ea block when umounted
  ext4: optimize ea_inode block expansion
  jbd2: fix data missing when reusing bh which is ready to be checkpointed
  ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC
  ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
  io_uring/poll: allow some retries for poll triggering spuriously
  io_uring: remove MSG_NOSIGNAL from recvmsg
  io_uring/rsrc: disallow multi-source reg buffers
  io_uring: add a conditional reschedule to the IOPOLL cancelation loop
  io_uring: mark task TASK_RUNNING before handling resume/task work
  io_uring: handle TIF_NOTIFY_RESUME when checking for task_work
  irqdomain: Drop bogus fwspec-mapping error handling
  irqdomain: Fix disassociation race
  irqdomain: Fix association race
  ima: Align ima_file_mmap() parameters with mmap_file LSM hook
  brd: return 0/-error from brd_insert_page()
  Documentation/hw-vuln: Document the interaction between IBRS and STIBP
  x86/speculation: Allow enabling STIBP with legacy IBRS
  x86/microcode/AMD: Fix mixed steppings support
  x86/microcode/AMD: Add a @cpu parameter to the reloading functions
  x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter
  x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe range
  x86/kprobes: Fix __recover_optprobed_insn check optimizing logic
  x86/reboot: Disable SVM, not just VMX, when stopping CPUs
  x86/reboot: Disable virtualization in an emergency if SVM is supported
  x86/crash: Disable virt in core NMI crash handler to avoid double shootdown
  x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows)
  KVM: s390: disable migration mode when dirty tracking is disabled
  KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI
  KVM: Destroy target device if coalesced MMIO unregistration fails
  udf: Fix file corruption when appending just after end of preallocated extent
  udf: Detect system inodes linked into directory hierarchy
  udf: Preserve link count of system files
  udf: Do not update file length for failed writes to inline files
  udf: Do not bother merging very long extents
  udf: Truncate added extents on failed expansion
  ocfs2: fix non-auto defrag path not working issue
  ocfs2: fix defrag path triggering jbd2 ASSERT
  f2fs: fix cgroup writeback accounting with fs-layer encryption
  f2fs: fix information leak in f2fs_move_inline_dirents()
  exfat: fix inode->i_blocks for non-512 byte sector size device
  exfat: redefine DIR_DELETED as the bad cluster number
  exfat: fix unexpected EOF while reading dir
  exfat: fix reporting fs error when reading dir beyond EOF
  fs: hfsplus: fix UAF issue in hfsplus_put_super
  hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
  ARM: dts: exynos: correct HDMI phy compatible in Exynos4
  cifs: Fix uninitialized memory read in smb3_qfs_tcon()
  s390/kprobes: fix current_kprobe never cleared after kprobes reenter
  s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler
  s390: discard .interp section
  s390/extmem: return correct segment type in __segment_load()
  ipmi_ssif: Rename idle state and check
  rtc: pm8xxx: fix set-alarm race
  firmware: coreboot: framebuffer: Ignore reserved pixel color bits
  wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu
  nfsd: zero out pointers after putting nfsd_files on COPY setup error
  dm cache: add cond_resched() to various workqueue loops
  dm thin: add cond_resched() to various workqueue loops
  drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5
  HID: logitech-hidpp: Don't restart communication if not necessary
  pinctrl: at91: use devm_kasprintf() to avoid potential leaks
  hwmon: (coretemp) Simplify platform device handling
  gfs2: Improve gfs2_make_fs_rw error handling
  regulator: s5m8767: Bounds check id indexing into arrays
  regulator: max77802: Bounds check regulator id against opmode
  ASoC: kirkwood: Iterate over array indexes instead of using pointer math
  docs/scripts/gdb: add necessary make scripts_gdb step
  drm/msm/dsi: Add missing check for alloc_ordered_workqueue
  drm: amd: display: Fix memory leakage
  drm/radeon: free iio for atombios when driver shutdown
  drm/tiny: ili9486: Do not assume 8-bit only SPI controllers
  HID: Add Mapping for System Microphone Mute
  drm/omap: dsi: Fix excessive stack usage
  drm/amd/display: Fix potential null-deref in dm_resume
  Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
  PM: EM: fix memory leak with using debugfs_lookup()
  uaccess: Add minimum bounds check on kernel buffer size
  coda: Avoid partial allocation of sig_inputArgs
  net/mlx5: fw_tracer: Fix debug print
  ACPI: video: Fix Lenovo Ideapad Z570 DMI match
  wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup
  m68k: Check syscall_trace_enter() return code
  net: bcmgenet: Add a check for oversized packets
  crypto: hisilicon: Wipe entire pool on error
  clocksource: Suspend the watchdog temporarily when high read latency detected
  ACPI: Don't build ACPICA with '-Os'
  ice: add missing checks for PF vsi type
  inet: fix fast path in __inet_hash_connect()
  wifi: mt7601u: fix an integer underflow
  wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-of-bounds
  x86/bugs: Reset speculation control settings on init
  timers: Prevent union confusion from unexpected restart_syscall()
  thermal: intel: Fix unsigned comparison with less than zero
  wifi: ath11k: debugfs: fix to work with multiple PCI devices
  rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug
  rcu: Suppress smp_processor_id() complaint in synchronize_rcu_expedited_wait()
  rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks
  wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds()
  wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect()
  blk-iocost: fix divide by 0 error in calc_lcoefs()
  ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy
  udf: Define EFSCORRUPTED error code
  rpmsg: glink: Avoid infinite loop on intent for missing channel
  media: saa7134: Use video_unregister_device for radio_dev
  media: usb: siano: Fix use after free bugs caused by do_submit_urb
  media: i2c: ov7670: 0 instead of -EINVAL was returned
  media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
  media: i2c: imx219: Fix binning for RAW8 capture
  media: i2c: imx219: Split common registers from mode tables
  media: i2c: imx219: remove redundant writes
  media: i2c: ov772x: Fix memleak in ov772x_probe()
  media: ov5675: Fix memleak in ov5675_init_controls()
  media: ov2740: Fix memleak in ov2740_init_controls()
  media: max9286: Fix memleak in max9286_v4l2_register()
  builddeb: clean generated package content
  powerpc: Remove linker flag from KBUILD_AFLAGS
  media: platform: ti: Add missing check for devm_regulator_get
  media: ti: cal: fix possible memory leak in cal_ctx_create()
  remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers
  Input: iqs269a - do not poll during ATI
  Input: iqs269a - do not poll during suspend or resume
  alpha/boot/tools/objstrip: fix the check for ELF header
  vdpa/mlx5: Don't clear mr struct on destroy MR
  MIPS: vpe-mt: drop physical_memsize
  MIPS: SMP-CPS: fix build error when HOTPLUG_CPU not set
  powerpc/eeh: Set channel state after notifying the drivers
  powerpc/eeh: Small refactor of eeh_handle_normal_event()
  powerpc/rtas: ensure 4KB alignment for rtas_data_buf
  powerpc/rtas: make all exports GPL
  powerpc/pseries/lparcfg: add missing RTAS retry status handling
  powerpc/pseries/lpar: add missing RTAS retry status handling
  powerpc/perf/hv-24x7: add missing RTAS retry status handling
  clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled()
  powerpc/powernv/ioda: Skip unallocated resources when mapping to PE
  clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX GDSC
  clk: qcom: gpucc-sc7180: fix clk_dis_wait being programmed for CX GDSC
  Input: ads7846 - don't check penirq immediately for 7845
  Input: ads7846 - always set last command to PWRDOWN
  Input: ads7846 - convert to one message
  Input: ads7846 - convert to full duplex
  Input: ads7846 - don't report pressure for ads7845
  clk: imx: avoid memory leak
  clk: renesas: cpg-mssr: Remove superfluous check in resume code
  clk: renesas: cpg-mssr: Fix use after free if cpg_mssr_common_init() failed
  linux/kconfig.h: replace IF_ENABLED() with PTR_IF() in <linux/kernel.h>
  Input: iqs269a - configure device with a single block write
  Input: iqs269a - increase interrupt handler return delay
  Input: iqs269a - drop unused device node references
  mtd: rawnand: sunxi: Fix the size of the last OOB region
  RISC-V: fix funct4 definition for c.jalr in parse_asm.h
  clk: qcom: gcc-qcs404: fix names of the DSI clocks used as parents
  clk: qcom: gcc-qcs404: disable gpll[04]_out_aux parents
  mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read()
  objtool: add UACCESS exceptions for __tsan_volatile_read/write
  printf: fix errname.c list
  selftests/ftrace: Fix bash specific "==" operator
  sparc: allow PM configs for sparc32 COMPILE_TEST
  perf tools: Fix auto-complete on aarch64
  leds: led-core: Fix refcount leak in of_led_get()
  perf llvm: Fix inadvertent file creation
  gfs2: jdata writepage fix
  cifs: Fix warning and UAF when destroy the MR list
  cifs: Fix lost destroy smbd connection when MR allocate failed
  nfsd: fix race to check ls_layouts
  hid: bigben_probe(): validate report count
  HID: bigben: use spinlock to safely schedule workers
  HID: bigben_worker() remove unneeded check on report_field
  HID: bigben: use spinlock to protect concurrent accesses
  ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared
  spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
  NFS: fix disabling of swap
  nfs4trace: fix state manager flag printing
  NFSv4: keep state manager thread active if swap is enabled
  NFS: Fix up handling of outstanding layoutcommit in nfs_update_inode()
  dm: remove flush_scheduled_work() during local_exit()
  ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init
  hwmon: (mlxreg-fan) Return zero speed for broken fan
  spi: bcm63xx-hsspi: Fix multi-bit mode setting
  spi: bcm63xx-hsspi: fix pm_runtime
  scsi: aic94xx: Add missing check for dma_map_single()
  scsi: mpt3sas: Fix a memory leak
  drm/amdgpu: fix enum odm_combine_mode mismatch
  hwmon: (ltc2945) Handle error case in ltc2945_value_store
  ASoC: dt-bindings: meson: fix gx-card codec node regex
  ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params()
  ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove()
  ASoC: mchp-spdifrx: fix controls that works with completion mechanism
  ASoC: mchp-spdifrx: fix return value in case completion times out
  ASoC: atmel: fix spelling mistakes
  ASoC: mchp-spdifrx: fix controls which rely on rsr register
  spi: dw_bt1: fix MUX_MMIO dependencies
  gpio: vf610: connect GPIO label to dev name
  ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress()
  drm/mediatek: Clean dangling pointer on bind error path
  drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc
  drm/mediatek: Drop unbalanced obj unref
  drm/mediatek: Use NULL instead of 0 for NULL pointer
  drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd
  gpu: host1x: Don't skip assigning syncpoints to channels
  pinctrl: mediatek: Initialize variable *buf to zero
  pinctrl: mediatek: Initialize variable pullen and pullup to zero
  pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback()
  drm/msm/mdp5: Add check for kzalloc
  drm/msm/dpu: Add check for pstates
  drm/msm/dpu: Add check for cstate
  drm/msm: use strscpy instead of strncpy
  drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness
  drm/bridge: lt9611: pass a pointer to the of node
  drm/bridge: lt9611: fix clock calculation
  drm/bridge: lt9611: fix programming of video modes
  drm/bridge: lt9611: fix polarity programming
  drm/bridge: lt9611: fix HPD reenablement
  drm/bridge: lt9611: fix sleep mode setup
  drm/msm/dpu: Disallow unallocated resources to be returned
  ALSA: hda/ca0132: minor fix for allocation size
  drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
  ASoC: fsl_sai: initialize is_dsp_mode flag
  drm/vc4: hdmi: Correct interlaced timings again
  drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5
  drm/vc4: hvs: Set AXI panic modes
  pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups
  pinctrl: rockchip: do coding style for mux route struct
  pinctrl: rockchip: add support for rk3568
  pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain
  pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins
  drm/msm/hdmi: Add missing check for alloc_ordered_workqueue
  gpu: ipu-v3: common: Add of_node_put() for reference returned by of_graph_get_port_by_id()
  drm: tidss: Fix pixel format definition
  drm/vc4: dpi: Fix format mapping for RGB565
  drm/vc4: dpi: Add option for inverting pixel clock and output enable
  drm/vkms: Fix null-ptr-deref in vkms_release()
  drm/bridge: megachips: Fix error handling in i2c_register_driver()
  drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC
  drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats
  drm: Fix potential null-ptr-deref due to drmm_mode_config_init()
  sefltests: netdevsim: wait for devlink instance after netns removal
  selftest: fib_tests: Always cleanup before exit
  net: bcmgenet: fix MoCA LED control
  l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register()
  selftests/net: Interpret UDP_GRO cmsg data as an int value
  irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
  irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
  bpf: Fix global subprog context argument resolution logic
  can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a bus error
  thermal/drivers/hisi: Drop second sensor hi3660
  wifi: mac80211: make rate u32 in sta_set_rate_info_rx()
  crypto: crypto4xx - Call dma_unmap_page when done
  selftests/bpf: Fix out-of-srctree build
  wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize()
  wifi: iwl4965: Add missing check for create_singlethread_workqueue()
  wifi: iwl3945: Add missing check for create_singlethread_workqueue
  RISC-V: time: initialize hrtimer based broadcast clock event device
  m68k: /proc/hardware should depend on PROC_FS
  crypto: rsa-pkcs1pad - Use akcipher_request_complete
  rds: rds_rm_zerocopy_callback() correct order for list_add_tail()
  libbpf: Fix alen calculation in libbpf_nla_dump_errormsg()
  Bluetooth: L2CAP: Fix potential user-after-free
  OPP: fix error checking in opp_migrate_dentry()
  tap: tap_open(): correctly initialize socket uid
  tun: tun_chr_open(): correctly initialize socket uid
  net: add sock_init_data_uid()
  s390/vmem: fix empty page tables cleanup under KASAN
  irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe
  irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe
  irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains
  irqchip: Fix refcount leak in platform_irqchip_probe
  net/mlx5: Enhance debug print in page allocation failure
  bpftool: profile online CPUs instead of possible
  crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware
  crypto: ccp - Refactor out sev_fw_alloc()
  leds: led-class: Add missing put_device() to led_put()
  crypto: xts - Handle EBUSY correctly
  net: ethernet: ti: add missing of_node_put before return
  net: ethernet: ti: am65-cpsw: handle deferred probe with dev_err_probe()
  net: ethernet: ti: am65-cpsw: fix tx csum offload for multi mac mode
  x86/microcode: Adjust late loading result reporting message
  x86/microcode: Check CPU capabilities after late microcode update correctly
  x86/microcode: Add a parameter to microcode_check() to store CPU capabilities
  x86/microcode: Print previous version of microcode after reload
  x86/microcode: Default-disable late loading
  x86/microcode: Rip out the OLD_INTERFACE
  x86: Mark stop_this_cpu() __noreturn
  x86/microcode: Replace deprecated CPU-hotplug functions.
  x86/cpu: Init AP exception handling from cpu_init_secondary()
  powercap: fix possible name leak in powercap_register_zone()
  crypto: seqiv - Handle EBUSY correctly
  crypto: essiv - Handle EBUSY correctly
  crypto: ccp - Failure on re-initialization due to duplicate sysfs filename
  ACPI: battery: Fix missing NUL-termination with large strings
  wifi: cfg80211: Fix extended KCK key length check in nl80211_set_rekey_data()
  wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
  wifi: ath9k: Fix potential stack-out-of-bounds write in ath9k_wmi_rsp_callback()
  wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  ath9k: htc: clean up statistics macros
  ath9k: hif_usb: simplify if-if to if-else
  wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback function
  wifi: orinoco: check return value of hermes_write_wordrec()
  wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU
  thermal/drivers/tsens: Sort out msm8976 vs msm8956 data
  thermal/drivers/tsens: Add compat string for the qcom,msm8960
  thermal/drivers/qcom/tsens_v1: Enable sensor 3 on MSM8976
  thermal/drivers/tsens: Drop msm8976-specific defines
  ACPICA: nsrepair: handle cases without a return value correctly
  crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2
  crypto: ccp - Use kzalloc for sev ioctl interfaces to prevent kernel memory leak
  crypto: ccp: Use the stack and common buffer for status commands
  crypto: ccp: Use the stack for small SEV command buffers
  lib/mpi: Fix buffer overrun when SG is too long
  rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()
  rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls
  rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
  genirq: Fix the return type of kstat_cpu_irqs_sum()
  ACPICA: Drop port I/O validation for some regions
  crypto: x86/ghash - fix unaligned access in ghash_setkey()
  wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave()
  wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave()
  wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave()
  wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave()
  wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave()
  wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()
  wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit()
  wifi: wilc1000: fix potential memory leak in wilc_mac_xmit()
  wifi: ipw2200: fix memory leak in ipw_wdev_init()
  wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave()
  libbpf: Fix btf__align_of() by taking into account field offsets
  wifi: rtlwifi: Fix global-out-of-bounds bug in _rtl8812ae_phy_set_txpower_limit()
  rtlwifi: fix -Wpointer-sign warning
  wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave()
  wifi: libertas: fix memory leak in lbs_init_adapter()
  wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave()
  wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave()
  wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave()
  wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave()
  wifi: rsi: Fix memory leak in rsi_coex_attach()
  block: bio-integrity: Copy flags when bio_integrity_payload is cloned
  x86/perf/zhaoxin: Add stepping check for ZXC
  sched/rt: pick_next_rt_entity(): check list_entry
  sched/deadline,rt: Remove unused parameter from pick_next_[rt|dl]_entity()
  s390/dasd: Fix potential memleak in dasd_eckd_init()
  s390/dasd: Prepare for additional path event handling
  blk-mq: correct stale comment of .get_budget
  blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx
  blk-mq: avoid sleep in blk_mq_alloc_request_hctx
  arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node
  ARM: dts: imx7s: correct iomuxc gpr mux controller cells
  ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference
  arm64: dts: renesas: beacon-renesom: Fix gpio expander reference
  arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name
  arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name
  arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name
  arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node name
  arm64: dts: amlogic: meson-gx: add missing unit address to rng node name
  arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names property
  arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible
  arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name
  arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name
  ARM: imx: Call ida_simple_remove() for ida_simple_get
  ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato
  arm64: dts: ti: k3-j7200: Fix wakeup pinmux range
  ARM: s3c: fix s3c64xx_set_timer_source prototype
  ARM: OMAP1: call platform_device_put() in error case in omap1_dm_timer_init()
  arm64: dts: meson: remove CPU opps below 1GHz for G12A boards
  arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names
  arm64: dts: qcom: ipq8074: fix Gen3 PCIe node
  arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges
  arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY
  arm64: dts: qcom: ipq8074: fix PCIe PHY serdes size
  arm64: dts: qcom: Fix IPQ8074 PCIe PHY nodes
  arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names
  arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address
  arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name
  arm64: dts: meson-gx: Fix Ethernet MAC address unit name
  arm64: dts: qcom: sc7180: correct SPMI bus address cells
  arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name
  arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description
  ARM: zynq: Fix refcount leak in zynq_early_slcr_init
  arm64: dts: qcom: qcs404: use symbol names for PCIe resets
  ARM: OMAP2+: Fix memory leak in realtime_counter_init()
  powerpc/mm: Rearrange if-else block to avoid clang warning
  HID: asus: use spinlock to safely schedule workers
  HID: asus: use spinlock to protect concurrent accesses
  HID: asus: Remove check for same LED brightness on set
  Linux 5.10.172
  io_uring: ensure that io_init_req() passes in the right issue_flags
  Revert "nvmem: core: Fix a conflict between MTD and NVMEM on wp-gpios property"
  Revert "nvmem: core: remove nvmem_config wp_gpio"
  Revert "nvmem: core: fix cleanup after dev_set_name()"
  Revert "nvmem: core: fix registration vs use race"
  Revert "nvmem: core: fix return value"
  Linux 5.10.171
  io_uring: add missing lock in io_get_file_fixed
  USB: core: Don't hold device lock while reading the "descriptors" sysfs file
  usb: gadget: u_serial: Add null pointer check in gserial_resume
  USB: serial: option: add support for VW/Skoda "Carstick LTE"
  drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling
  drm/virtio: Fix NULL vs IS_ERR checking in virtio_gpu_object_shmem_init
  scripts/tags.sh: fix incompatibility with PCRE2
  scripts/tags.sh: Invoke 'realpath' via 'xargs'
  md: Flush workqueue md_rdev_misc_wq in md_alloc()
  vc_screen: don't clobber return value in vcs_read
  net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues().
  bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state
  HID: core: Fix deadloop in hid_apply_multiplier.
  neigh: make sure used and confirmed times are valid
  IB/hfi1: Assign npages earlier
  btrfs: send: limit number of clones and allocated memory size
  ACPI: NFIT: fix a potential deadlock during NFIT teardown
  ARM: dts: rockchip: add power-domains property to dp node on rk3288
  arm64: dts: rockchip: drop unused LED mode property from rk3328-roc-cc
  Fix XFRM-I support for nested ESP tunnels
  Revert "Revert "nvmem: core: Fix a conflict between MTD and NVMEM on wp-gpios property""
  Linux 5.10.170
  bpf: add missing header file include
  Revert "net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs"
  ext4: Fix function prototype mismatch for ext4_feat_ktype
  audit: update the mailing list in MAINTAINERS
  wifi: mwifiex: Add missing compatible string for SD8787
  nbd: fix possible overflow on 'first_minor' in nbd_dev_add()
  nbd: fix possible overflow for 'first_minor' in nbd_dev_add()
  nbd: fix max value for 'first_minor'
  Revert "Revert "block: nbd: add sanity check for first_minor""
  uaccess: Add speculation barrier to copy_from_user()
  mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh
  drm/i915/gvt: fix double free bug in split_2MB_gtt_entry
  powerpc: dts: t208x: Disable 10G on MAC1 and MAC2
  can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len
  KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS
  KVM: SVM: Skip WRMSR fastpath on VM-Exit if next RIP isn't valid
  KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception
  random: always mix cycle counter in add_latent_entropy()
  clk: mxl: syscon_node_to_regmap() returns error pointers
  powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G
  clk: mxl: Fix a clk entry by adding relevant flags
  clk: mxl: Add option to override gate clks
  clk: mxl: Remove redundant spinlocks
  clk: mxl: Switch from direct readl/writel based IO to regmap based IO
  wifi: rtl8xxxu: gen2: Turn on the rate control
  drm/etnaviv: don't truncate physical page address
  Linux 5.10.169
  nvmem: core: fix return value
  net: sched: sch: Fix off by one in htb_activate_prios()
  ASoC: SOF: Intel: hda-dai: fix possible stream_tag leak
  alarmtimer: Prevent starvation by small intervals and SIG_IGN
  kvm: initialize all of the kvm_debugregs structure before sending it to userspace
  net/sched: tcindex: search key must be 16 bits
  i40e: Add checking for null for nlmsg_find_attr()
  net/sched: act_ctinfo: use percpu stats
  flow_offload: fill flags to action structure
  drm/i915/gen11: Wa_1408615072/Wa_1407596294 should be on GT list
  drm/i915/gen11: Moving WAs to icl_gt_workarounds_init()
  nilfs2: fix underflow in second superblock position calculations
  ipv6: Fix tcp socket connection with DSCP.
  ipv6: Fix datagram socket connection with DSCP.
  ixgbe: add double of VLAN header when computing the max MTU
  net: mpls: fix stale pointer if allocation fails during device rename
  net: stmmac: Restrict warning on disabling DMA store and fwd mode
  bnxt_en: Fix mqprio and XDP ring checking logic
  net: stmmac: fix order of dwmac5 FlexPPS parametrization sequence
  net: openvswitch: fix possible memory leak in ovs_meter_cmd_set()
  net/usb: kalmia: Don't pass act_len in usb_bulk_msg error path
  dccp/tcp: Avoid negative sk_forward_alloc by ipv6_pinfo.pktoptions.
  net/sched: tcindex: update imperfect hash filters respecting rcu
  sctp: sctp_sock_filter(): avoid list_entry() on possibly empty list
  net: bgmac: fix BCM5358 support by setting correct flags
  i40e: add double of VLAN header when computing the max MTU
  ixgbe: allow to increase MTU to 3K with XDP enabled
  revert "squashfs: harden sanity check in squashfs_read_xattr_id_table"
  net: Fix unwanted sign extension in netdev_stats_to_stats64()
  Revert "mm: Always release pages to the buddy allocator in memblock_free_late()."
  hugetlb: check for undefined shift on 32 bit architectures
  sched/psi: Fix use-after-free in ep_remove_wait_queue()
  ALSA: hda/realtek - fixed wrong gpio assigned
  ALSA: hda/conexant: add a new hda codec SN6180
  mmc: mmc_spi: fix error handling in mmc_spi_probe()
  mmc: sdio: fix possible resource leaks in some error paths
  mmc: jz4740: Work around bug on JZ4760(B)
  netfilter: nft_tproxy: restrict to prerouting hook
  ovl: remove privs in ovl_fallocate()
  ovl: remove privs in ovl_copyfile()
  s390/signal: fix endless loop in do_signal
  aio: fix mremap after fork null-deref
  nvmem: core: fix registration vs use race
  nvmem: core: fix cleanup after dev_set_name()
  nvmem: core: remove nvmem_config wp_gpio
  nvmem: core: add error handling for dev_set_name
  platform/x86: touchscreen_dmi: Add Chuwi Vi8 (CWI501) DMI match
  nvme-fc: fix a missing queue put in nvmet_fc_ls_create_association
  s390/decompressor: specify __decompress() buf len to avoid overflow
  net: sched: sch: Bounds check priority
  net: stmmac: do not stop RX_CLK in Rx LPI state for qcs404 SoC
  net/rose: Fix to not accept on connected socket
  tools/virtio: fix the vringh test for virtio ring changes
  ASoC: cs42l56: fix DT probe
  ALSA: hda: Do not unset preset when cleaning up codec
  selftests/bpf: Verify copy_register_state() preserves parent/live fields
  ASoC: Intel: sof_rt5682: always set dpcm_capture for amplifiers

 Conflicts:
	Documentation/devicetree/bindings
	Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml

Change-Id: I1f66c988a4f4f4661c8f74bcd1ad89220081567e
Signed-off-by: Srinivasarao Pathipati <quic_c_spathi@quicinc.com>
2023-07-20 10:51:40 +05:30

2093 lines
50 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Qualcomm self-authenticating modem subsystem remoteproc driver
*
* Copyright (C) 2016 Linaro Ltd.
* Copyright (C) 2014 Sony Mobile Communications AB
* Copyright (c) 2012-2013, 2020 The Linux Foundation. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/devcoredump.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
#include "remoteproc_internal.h"
#include "qcom_common.h"
#include "qcom_pil_info.h"
#include "qcom_q6v5.h"
#include <linux/qcom_scm.h>
#define MPSS_CRASH_REASON_SMEM 421
#define MBA_LOG_SIZE SZ_4K
/* RMB Status Register Values */
#define RMB_PBL_SUCCESS 0x1
#define RMB_MBA_XPU_UNLOCKED 0x1
#define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2
#define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3
#define RMB_MBA_AUTH_COMPLETE 0x4
/* PBL/MBA interface registers */
#define RMB_MBA_IMAGE_REG 0x00
#define RMB_PBL_STATUS_REG 0x04
#define RMB_MBA_COMMAND_REG 0x08
#define RMB_MBA_STATUS_REG 0x0C
#define RMB_PMI_META_DATA_REG 0x10
#define RMB_PMI_CODE_START_REG 0x14
#define RMB_PMI_CODE_LENGTH_REG 0x18
#define RMB_MBA_MSS_STATUS 0x40
#define RMB_MBA_ALT_RESET 0x44
#define RMB_CMD_META_DATA_READY 0x1
#define RMB_CMD_LOAD_READY 0x2
/* QDSP6SS Register Offsets */
#define QDSP6SS_RESET_REG 0x014
#define QDSP6SS_GFMUX_CTL_REG 0x020
#define QDSP6SS_PWR_CTL_REG 0x030
#define QDSP6SS_MEM_PWR_CTL 0x0B0
#define QDSP6V6SS_MEM_PWR_CTL 0x034
#define QDSP6SS_STRAP_ACC 0x110
/* AXI Halt Register Offsets */
#define AXI_HALTREQ_REG 0x0
#define AXI_HALTACK_REG 0x4
#define AXI_IDLE_REG 0x8
#define AXI_GATING_VALID_OVERRIDE BIT(0)
#define HALT_ACK_TIMEOUT_US 100000
/* QDSP6SS_RESET */
#define Q6SS_STOP_CORE BIT(0)
#define Q6SS_CORE_ARES BIT(1)
#define Q6SS_BUS_ARES_ENABLE BIT(2)
/* QDSP6SS CBCR */
#define Q6SS_CBCR_CLKEN BIT(0)
#define Q6SS_CBCR_CLKOFF BIT(31)
#define Q6SS_CBCR_TIMEOUT_US 200
/* QDSP6SS_GFMUX_CTL */
#define Q6SS_CLK_ENABLE BIT(1)
/* QDSP6SS_PWR_CTL */
#define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0)
#define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1)
#define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2)
#define Q6SS_L2TAG_SLP_NRET_N BIT(16)
#define Q6SS_ETB_SLP_NRET_N BIT(17)
#define Q6SS_L2DATA_STBY_N BIT(18)
#define Q6SS_SLP_RET_N BIT(19)
#define Q6SS_CLAMP_IO BIT(20)
#define QDSS_BHS_ON BIT(21)
#define QDSS_LDO_BYP BIT(22)
/* QDSP6v56 parameters */
#define QDSP6v56_LDO_BYP BIT(25)
#define QDSP6v56_BHS_ON BIT(24)
#define QDSP6v56_CLAMP_WL BIT(21)
#define QDSP6v56_CLAMP_QMC_MEM BIT(22)
#define QDSP6SS_XO_CBCR 0x0038
#define QDSP6SS_ACC_OVERRIDE_VAL 0x20
/* QDSP6v65 parameters */
#define QDSP6SS_CORE_CBCR 0x20
#define QDSP6SS_SLEEP 0x3C
#define QDSP6SS_BOOT_CORE_START 0x400
#define QDSP6SS_BOOT_CMD 0x404
#define BOOT_FSM_TIMEOUT 10000
struct reg_info {
struct regulator *reg;
int uV;
int uA;
};
struct qcom_mss_reg_res {
const char *supply;
int uV;
int uA;
};
struct rproc_hexagon_res {
const char *hexagon_mba_image;
struct qcom_mss_reg_res *proxy_supply;
struct qcom_mss_reg_res *active_supply;
char **proxy_clk_names;
char **reset_clk_names;
char **active_clk_names;
char **active_pd_names;
char **proxy_pd_names;
int version;
bool need_mem_protection;
bool has_alt_reset;
bool has_mba_logs;
bool has_spare_reg;
};
struct q6v5 {
struct device *dev;
struct rproc *rproc;
void __iomem *reg_base;
void __iomem *rmb_base;
struct regmap *halt_map;
struct regmap *conn_map;
u32 halt_q6;
u32 halt_modem;
u32 halt_nc;
u32 conn_box;
struct reset_control *mss_restart;
struct reset_control *pdc_reset;
struct qcom_q6v5 q6v5;
struct clk *active_clks[8];
struct clk *reset_clks[4];
struct clk *proxy_clks[4];
struct device *active_pds[1];
struct device *proxy_pds[3];
int active_clk_count;
int reset_clk_count;
int proxy_clk_count;
int active_pd_count;
int proxy_pd_count;
struct reg_info active_regs[1];
struct reg_info proxy_regs[3];
int active_reg_count;
int proxy_reg_count;
bool dump_mba_loaded;
size_t current_dump_size;
size_t total_dump_size;
phys_addr_t mba_phys;
void *mba_region;
size_t mba_size;
size_t dp_size;
phys_addr_t mdata_phys;
size_t mdata_size;
phys_addr_t mpss_phys;
phys_addr_t mpss_reloc;
size_t mpss_size;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_subdev smd_subdev;
struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon;
bool need_mem_protection;
bool has_alt_reset;
bool has_mba_logs;
bool has_spare_reg;
int mpss_perm;
int mba_perm;
const char *hexagon_mdt_image;
int version;
};
enum {
MSS_MSM8916,
MSS_MSM8974,
MSS_MSM8996,
MSS_MSM8998,
MSS_SC7180,
MSS_SDM845,
};
static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
const struct qcom_mss_reg_res *reg_res)
{
int rc;
int i;
if (!reg_res)
return 0;
for (i = 0; reg_res[i].supply; i++) {
regs[i].reg = devm_regulator_get(dev, reg_res[i].supply);
if (IS_ERR(regs[i].reg)) {
rc = PTR_ERR(regs[i].reg);
if (rc != -EPROBE_DEFER)
dev_err(dev, "Failed to get %s\n regulator",
reg_res[i].supply);
return rc;
}
regs[i].uV = reg_res[i].uV;
regs[i].uA = reg_res[i].uA;
}
return i;
}
static int q6v5_regulator_enable(struct q6v5 *qproc,
struct reg_info *regs, int count)
{
int ret;
int i;
for (i = 0; i < count; i++) {
if (regs[i].uV > 0) {
ret = regulator_set_voltage(regs[i].reg,
regs[i].uV, INT_MAX);
if (ret) {
dev_err(qproc->dev,
"Failed to request voltage for %d.\n",
i);
goto err;
}
}
if (regs[i].uA > 0) {
ret = regulator_set_load(regs[i].reg,
regs[i].uA);
if (ret < 0) {
dev_err(qproc->dev,
"Failed to set regulator mode\n");
goto err;
}
}
ret = regulator_enable(regs[i].reg);
if (ret) {
dev_err(qproc->dev, "Regulator enable failed\n");
goto err;
}
}
return 0;
err:
for (; i >= 0; i--) {
if (regs[i].uV > 0)
regulator_set_voltage(regs[i].reg, 0, INT_MAX);
if (regs[i].uA > 0)
regulator_set_load(regs[i].reg, 0);
regulator_disable(regs[i].reg);
}
return ret;
}
static void q6v5_regulator_disable(struct q6v5 *qproc,
struct reg_info *regs, int count)
{
int i;
for (i = 0; i < count; i++) {
if (regs[i].uV > 0)
regulator_set_voltage(regs[i].reg, 0, INT_MAX);
if (regs[i].uA > 0)
regulator_set_load(regs[i].reg, 0);
regulator_disable(regs[i].reg);
}
}
static int q6v5_clk_enable(struct device *dev,
struct clk **clks, int count)
{
int rc;
int i;
for (i = 0; i < count; i++) {
rc = clk_prepare_enable(clks[i]);
if (rc) {
dev_err(dev, "Clock enable failed\n");
goto err;
}
}
return 0;
err:
for (i--; i >= 0; i--)
clk_disable_unprepare(clks[i]);
return rc;
}
static void q6v5_clk_disable(struct device *dev,
struct clk **clks, int count)
{
int i;
for (i = 0; i < count; i++)
clk_disable_unprepare(clks[i]);
}
static int q6v5_pds_enable(struct q6v5 *qproc, struct device **pds,
size_t pd_count)
{
int ret;
int i;
for (i = 0; i < pd_count; i++) {
dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
ret = pm_runtime_get_sync(pds[i]);
if (ret < 0) {
pm_runtime_put_noidle(pds[i]);
dev_pm_genpd_set_performance_state(pds[i], 0);
goto unroll_pd_votes;
}
}
return 0;
unroll_pd_votes:
for (i--; i >= 0; i--) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}
return ret;
}
static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
size_t pd_count)
{
int i;
for (i = 0; i < pd_count; i++) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}
}
static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
bool local, bool remote, phys_addr_t addr,
size_t size)
{
struct qcom_scm_vmperm next[2];
int perms = 0;
if (!qproc->need_mem_protection)
return 0;
if (local == !!(*current_perm & BIT(QCOM_SCM_VMID_HLOS)) &&
remote == !!(*current_perm & BIT(QCOM_SCM_VMID_MSS_MSA)))
return 0;
if (local) {
next[perms].vmid = QCOM_SCM_VMID_HLOS;
next[perms].perm = QCOM_SCM_PERM_RWX;
perms++;
}
if (remote) {
next[perms].vmid = QCOM_SCM_VMID_MSS_MSA;
next[perms].perm = QCOM_SCM_PERM_RW;
perms++;
}
return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),
current_perm, next, perms);
}
static void q6v5_debug_policy_load(struct q6v5 *qproc)
{
const struct firmware *dp_fw;
if (request_firmware_direct(&dp_fw, "msadp", qproc->dev))
return;
if (SZ_1M + dp_fw->size <= qproc->mba_size) {
memcpy(qproc->mba_region + SZ_1M, dp_fw->data, dp_fw->size);
qproc->dp_size = dp_fw->size;
}
release_firmware(dp_fw);
}
static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5 *qproc = rproc->priv;
/* MBA is restricted to a maximum size of 1M */
if (fw->size > qproc->mba_size || fw->size > SZ_1M) {
dev_err(qproc->dev, "MBA firmware load failed\n");
return -EINVAL;
}
memcpy(qproc->mba_region, fw->data, fw->size);
q6v5_debug_policy_load(qproc);
return 0;
}
static int q6v5_reset_assert(struct q6v5 *qproc)
{
int ret;
if (qproc->has_alt_reset) {
reset_control_assert(qproc->pdc_reset);
ret = reset_control_reset(qproc->mss_restart);
reset_control_deassert(qproc->pdc_reset);
} else if (qproc->has_spare_reg) {
/*
* When the AXI pipeline is being reset with the Q6 modem partly
* operational there is possibility of AXI valid signal to
* glitch, leading to spurious transactions and Q6 hangs. A work
* around is employed by asserting the AXI_GATING_VALID_OVERRIDE
* BIT before triggering Q6 MSS reset. AXI_GATING_VALID_OVERRIDE
* is withdrawn post MSS assert followed by a MSS deassert,
* while holding the PDC reset.
*/
reset_control_assert(qproc->pdc_reset);
regmap_update_bits(qproc->conn_map, qproc->conn_box,
AXI_GATING_VALID_OVERRIDE, 1);
reset_control_assert(qproc->mss_restart);
reset_control_deassert(qproc->pdc_reset);
regmap_update_bits(qproc->conn_map, qproc->conn_box,
AXI_GATING_VALID_OVERRIDE, 0);
ret = reset_control_deassert(qproc->mss_restart);
} else {
ret = reset_control_assert(qproc->mss_restart);
}
return ret;
}
static int q6v5_reset_deassert(struct q6v5 *qproc)
{
int ret;
if (qproc->has_alt_reset) {
reset_control_assert(qproc->pdc_reset);
writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET);
ret = reset_control_reset(qproc->mss_restart);
writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
reset_control_deassert(qproc->pdc_reset);
} else if (qproc->has_spare_reg) {
ret = reset_control_reset(qproc->mss_restart);
} else {
ret = reset_control_deassert(qproc->mss_restart);
}
return ret;
}
static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
{
unsigned long timeout;
s32 val;
timeout = jiffies + msecs_to_jiffies(ms);
for (;;) {
val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG);
if (val)
break;
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
msleep(1);
}
return val;
}
static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms)
{
unsigned long timeout;
s32 val;
timeout = jiffies + msecs_to_jiffies(ms);
for (;;) {
val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
if (val < 0)
break;
if (!status && val)
break;
else if (status && val == status)
break;
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
msleep(1);
}
return val;
}
static void q6v5_dump_mba_logs(struct q6v5 *qproc)
{
struct rproc *rproc = qproc->rproc;
void *data;
if (!qproc->has_mba_logs)
return;
if (q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys,
qproc->mba_size))
return;
data = vmalloc(MBA_LOG_SIZE);
if (!data)
return;
memcpy(data, qproc->mba_region, MBA_LOG_SIZE);
dev_coredumpv(&rproc->dev, data, MBA_LOG_SIZE, GFP_KERNEL);
}
static int q6v5proc_reset(struct q6v5 *qproc)
{
u32 val;
int ret;
int i;
if (qproc->version == MSS_SDM845) {
val = readl(qproc->reg_base + QDSP6SS_SLEEP);
val |= Q6SS_CBCR_CLKEN;
writel(val, qproc->reg_base + QDSP6SS_SLEEP);
ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
val, !(val & Q6SS_CBCR_CLKOFF), 1,
Q6SS_CBCR_TIMEOUT_US);
if (ret) {
dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
return -ETIMEDOUT;
}
/* De-assert QDSP6 stop core */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
/* Trigger boot FSM */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
if (ret) {
dev_err(qproc->dev, "Boot FSM failed to complete.\n");
/* Reset the modem so that boot FSM is in reset state */
q6v5_reset_deassert(qproc);
return ret;
}
goto pbl_wait;
} else if (qproc->version == MSS_SC7180) {
val = readl(qproc->reg_base + QDSP6SS_SLEEP);
val |= Q6SS_CBCR_CLKEN;
writel(val, qproc->reg_base + QDSP6SS_SLEEP);
ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
val, !(val & Q6SS_CBCR_CLKOFF), 1,
Q6SS_CBCR_TIMEOUT_US);
if (ret) {
dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
return -ETIMEDOUT;
}
/* Turn on the XO clock needed for PLL setup */
val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
val |= Q6SS_CBCR_CLKEN;
writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
val, !(val & Q6SS_CBCR_CLKOFF), 1,
Q6SS_CBCR_TIMEOUT_US);
if (ret) {
dev_err(qproc->dev, "QDSP6SS XO clock timed out\n");
return -ETIMEDOUT;
}
/* Configure Q6 core CBCR to auto-enable after reset sequence */
val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR);
val |= Q6SS_CBCR_CLKEN;
writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR);
/* De-assert the Q6 stop core signal */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
/* Wait for 10 us for any staggering logic to settle */
usleep_range(10, 20);
/* Trigger the boot FSM to start the Q6 out-of-reset sequence */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
/* Poll the MSS_STATUS for FSM completion */
ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
if (ret) {
dev_err(qproc->dev, "Boot FSM failed to complete.\n");
/* Reset the modem so that boot FSM is in reset state */
q6v5_reset_deassert(qproc);
return ret;
}
goto pbl_wait;
} else if (qproc->version == MSS_MSM8996 ||
qproc->version == MSS_MSM8998) {
int mem_pwr_ctl;
/* Override the ACC value if required */
writel(QDSP6SS_ACC_OVERRIDE_VAL,
qproc->reg_base + QDSP6SS_STRAP_ACC);
/* Assert resets, stop core */
val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
/* BHS require xo cbcr to be enabled */
val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
val |= Q6SS_CBCR_CLKEN;
writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
/* Read CLKOFF bit to go low indicating CLK is enabled */
ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
val, !(val & Q6SS_CBCR_CLKOFF), 1,
Q6SS_CBCR_TIMEOUT_US);
if (ret) {
dev_err(qproc->dev,
"xo cbcr enabling timed out (rc:%d)\n", ret);
return ret;
}
/* Enable power block headswitch and wait for it to stabilize */
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= QDSP6v56_BHS_ON;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
udelay(1);
/* Put LDO in bypass mode */
val |= QDSP6v56_LDO_BYP;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
/* Deassert QDSP6 compiler memory clamp */
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val &= ~QDSP6v56_CLAMP_QMC_MEM;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
/* Deassert memory peripheral sleep and L2 memory standby */
val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
/* Turn on L1, L2, ETB and JU memories 1 at a time */
if (qproc->version == MSS_MSM8996) {
mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL;
i = 19;
} else {
/* MSS_MSM8998 */
mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL;
i = 28;
}
val = readl(qproc->reg_base + mem_pwr_ctl);
for (; i >= 0; i--) {
val |= BIT(i);
writel(val, qproc->reg_base + mem_pwr_ctl);
/*
* Read back value to ensure the write is done then
* wait for 1us for both memory peripheral and data
* array to turn on.
*/
val |= readl(qproc->reg_base + mem_pwr_ctl);
udelay(1);
}
/* Remove word line clamp */
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val &= ~QDSP6v56_CLAMP_WL;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
} else {
/* Assert resets, stop core */
val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
/* Enable power block headswitch and wait for it to stabilize */
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= QDSS_BHS_ON | QDSS_LDO_BYP;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
udelay(1);
/*
* Turn on memories. L2 banks should be done individually
* to minimize inrush current.
*/
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= Q6SS_L2DATA_SLP_NRET_N_2;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= Q6SS_L2DATA_SLP_NRET_N_1;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= Q6SS_L2DATA_SLP_NRET_N_0;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
}
/* Remove IO clamp */
val &= ~Q6SS_CLAMP_IO;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
/* Bring core out of reset */
val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
val &= ~Q6SS_CORE_ARES;
writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
/* Turn on core clock */
val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
val |= Q6SS_CLK_ENABLE;
writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG);
/* Start core execution */
val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
val &= ~Q6SS_STOP_CORE;
writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
pbl_wait:
/* Wait for PBL status */
ret = q6v5_rmb_pbl_wait(qproc, 1000);
if (ret == -ETIMEDOUT) {
dev_err(qproc->dev, "PBL boot timed out\n");
} else if (ret != RMB_PBL_SUCCESS) {
dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret);
ret = -EINVAL;
} else {
ret = 0;
}
return ret;
}
static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
struct regmap *halt_map,
u32 offset)
{
unsigned int val;
int ret;
/* Check if we're already idle */
ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
if (!ret && val)
return;
/* Assert halt request */
regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
/* Wait for halt */
regmap_read_poll_timeout(halt_map, offset + AXI_HALTACK_REG, val,
val, 1000, HALT_ACK_TIMEOUT_US);
ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
if (ret || !val)
dev_err(qproc->dev, "port failed halt\n");
/* Clear halt request (port will remain halted until reset) */
regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
}
static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
{
unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
dma_addr_t phys;
void *metadata;
int mdata_perm;
int xferop_ret;
size_t size;
void *ptr;
int ret;
metadata = qcom_mdt_read_metadata(qproc->dev, fw, qproc->hexagon_mdt_image, &size, NULL);
if (IS_ERR(metadata))
return PTR_ERR(metadata);
if (qproc->mdata_phys) {
if (size > qproc->mdata_size) {
ret = -EINVAL;
dev_err(qproc->dev, "metadata size outside memory range\n");
goto free_metadata;
}
phys = qproc->mdata_phys;
ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC);
if (!ptr) {
ret = -EBUSY;
dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
&qproc->mdata_phys, size);
goto free_metadata;
}
} else {
ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs);
if (!ptr) {
ret = -ENOMEM;
dev_err(qproc->dev, "failed to allocate mdt buffer\n");
goto free_metadata;
}
}
memcpy(ptr, metadata, size);
if (qproc->mdata_phys)
memunmap(ptr);
/* Hypervisor mapping to access metadata by modem */
mdata_perm = BIT(QCOM_SCM_VMID_HLOS);
ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true,
phys, size);
if (ret) {
dev_err(qproc->dev,
"assigning Q6 access to metadata failed: %d\n", ret);
ret = -EAGAIN;
goto free_dma_attrs;
}
writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "MPSS header authentication timed out\n");
else if (ret < 0)
dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
/* Metadata authentication done, remove modem access */
xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, false,
phys, size);
if (xferop_ret)
dev_warn(qproc->dev,
"mdt buffer not reclaimed system may become unstable\n");
free_dma_attrs:
if (!qproc->mdata_phys)
dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs);
free_metadata:
kfree(metadata);
return ret < 0 ? ret : 0;
}
static bool q6v5_phdr_valid(const struct elf32_phdr *phdr)
{
if (phdr->p_type != PT_LOAD)
return false;
if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
return false;
if (!phdr->p_memsz)
return false;
return true;
}
static int q6v5_mba_load(struct q6v5 *qproc)
{
int ret;
int xfermemop_ret;
bool mba_load_err = false;
qcom_q6v5_prepare(&qproc->q6v5);
ret = q6v5_pds_enable(qproc, qproc->active_pds, qproc->active_pd_count);
if (ret < 0) {
dev_err(qproc->dev, "failed to enable active power domains\n");
goto disable_irqs;
}
ret = q6v5_pds_enable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
if (ret < 0) {
dev_err(qproc->dev, "failed to enable proxy power domains\n");
goto disable_active_pds;
}
ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
if (ret) {
dev_err(qproc->dev, "failed to enable proxy supplies\n");
goto disable_proxy_pds;
}
ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
if (ret) {
dev_err(qproc->dev, "failed to enable proxy clocks\n");
goto disable_proxy_reg;
}
ret = q6v5_regulator_enable(qproc, qproc->active_regs,
qproc->active_reg_count);
if (ret) {
dev_err(qproc->dev, "failed to enable supplies\n");
goto disable_proxy_clk;
}
ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
if (ret) {
dev_err(qproc->dev, "failed to enable reset clocks\n");
goto disable_vdd;
}
ret = q6v5_reset_deassert(qproc);
if (ret) {
dev_err(qproc->dev, "failed to deassert mss restart\n");
goto disable_reset_clks;
}
ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
qproc->active_clk_count);
if (ret) {
dev_err(qproc->dev, "failed to enable clocks\n");
goto assert_reset;
}
/*
* Some versions of the MBA firmware will upon boot wipe the MPSS region as well, so provide
* the Q6 access to this region.
*/
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true,
qproc->mpss_phys, qproc->mpss_size);
if (ret) {
dev_err(qproc->dev, "assigning Q6 access to mpss memory failed: %d\n", ret);
goto disable_active_clks;
}
/* Assign MBA image access in DDR to q6 */
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true,
qproc->mba_phys, qproc->mba_size);
if (ret) {
dev_err(qproc->dev,
"assigning Q6 access to mba memory failed: %d\n", ret);
goto disable_active_clks;
}
writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
if (qproc->dp_size) {
writel(qproc->mba_phys + SZ_1M, qproc->rmb_base + RMB_PMI_CODE_START_REG);
writel(qproc->dp_size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
}
ret = q6v5proc_reset(qproc);
if (ret)
goto reclaim_mba;
ret = q6v5_rmb_mba_wait(qproc, 0, 5000);
if (ret == -ETIMEDOUT) {
dev_err(qproc->dev, "MBA boot timed out\n");
goto halt_axi_ports;
} else if (ret != RMB_MBA_XPU_UNLOCKED &&
ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) {
dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret);
ret = -EINVAL;
goto halt_axi_ports;
}
qproc->dump_mba_loaded = true;
return 0;
halt_axi_ports:
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
mba_load_err = true;
reclaim_mba:
xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
false, qproc->mba_phys,
qproc->mba_size);
if (xfermemop_ret) {
dev_err(qproc->dev,
"Failed to reclaim mba buffer, system may become unstable\n");
} else if (mba_load_err) {
q6v5_dump_mba_logs(qproc);
}
disable_active_clks:
q6v5_clk_disable(qproc->dev, qproc->active_clks,
qproc->active_clk_count);
assert_reset:
q6v5_reset_assert(qproc);
disable_reset_clks:
q6v5_clk_disable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
disable_vdd:
q6v5_regulator_disable(qproc, qproc->active_regs,
qproc->active_reg_count);
disable_proxy_clk:
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
disable_proxy_reg:
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
disable_proxy_pds:
q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
disable_active_pds:
q6v5_pds_disable(qproc, qproc->active_pds, qproc->active_pd_count);
disable_irqs:
qcom_q6v5_unprepare(&qproc->q6v5);
return ret;
}
static void q6v5_mba_reclaim(struct q6v5 *qproc)
{
int ret;
u32 val;
qproc->dump_mba_loaded = false;
qproc->dp_size = 0;
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
if (qproc->version == MSS_MSM8996) {
/*
* To avoid high MX current during LPASS/MSS restart.
*/
val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
QDSP6v56_CLAMP_QMC_MEM;
writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
}
q6v5_reset_assert(qproc);
q6v5_clk_disable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
q6v5_clk_disable(qproc->dev, qproc->active_clks,
qproc->active_clk_count);
q6v5_regulator_disable(qproc, qproc->active_regs,
qproc->active_reg_count);
q6v5_pds_disable(qproc, qproc->active_pds, qproc->active_pd_count);
/* In case of failure or coredump scenario where reclaiming MBA memory
* could not happen reclaim it here.
*/
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false,
qproc->mba_phys,
qproc->mba_size);
WARN_ON(ret);
ret = qcom_q6v5_unprepare(&qproc->q6v5);
if (ret) {
q6v5_pds_disable(qproc, qproc->proxy_pds,
qproc->proxy_pd_count);
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
}
}
static int q6v5_reload_mba(struct rproc *rproc)
{
struct q6v5 *qproc = rproc->priv;
const struct firmware *fw;
int ret;
ret = request_firmware(&fw, rproc->firmware, qproc->dev);
if (ret < 0)
return ret;
q6v5_load(rproc, fw);
ret = q6v5_mba_load(qproc);
release_firmware(fw);
return ret;
}
static int q6v5_mpss_load(struct q6v5 *qproc)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
const struct firmware *seg_fw;
const struct firmware *fw;
struct elf32_hdr *ehdr;
phys_addr_t mpss_reloc;
phys_addr_t boot_addr;
phys_addr_t min_addr = PHYS_ADDR_MAX;
phys_addr_t max_addr = 0;
u32 code_length;
bool relocate = false;
char *fw_name;
size_t fw_name_len;
ssize_t offset;
size_t size = 0;
void *ptr;
int ret;
int i;
fw_name_len = strlen(qproc->hexagon_mdt_image);
if (fw_name_len <= 4)
return -EINVAL;
fw_name = kstrdup(qproc->hexagon_mdt_image, GFP_KERNEL);
if (!fw_name)
return -ENOMEM;
ret = request_firmware(&fw, fw_name, qproc->dev);
if (ret < 0) {
dev_err(qproc->dev, "unable to load %s\n", fw_name);
goto out;
}
/* Initialize the RMB validator */
writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
ret = q6v5_mpss_init_image(qproc, fw);
if (ret)
goto release_firmware;
ehdr = (struct elf32_hdr *)fw->data;
phdrs = (struct elf32_phdr *)(ehdr + 1);
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
if (!q6v5_phdr_valid(phdr))
continue;
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
relocate = true;
if (phdr->p_paddr < min_addr)
min_addr = phdr->p_paddr;
if (phdr->p_paddr + phdr->p_memsz > max_addr)
max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
}
/*
* In case of a modem subsystem restart on secure devices, the modem
* memory can be reclaimed only after MBA is loaded.
*/
q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false,
qproc->mpss_phys, qproc->mpss_size);
/* Share ownership between Linux and MSS, during segment loading */
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true,
qproc->mpss_phys, qproc->mpss_size);
if (ret) {
dev_err(qproc->dev,
"assigning Q6 access to mpss memory failed: %d\n", ret);
ret = -EAGAIN;
goto release_firmware;
}
mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
qproc->mpss_reloc = mpss_reloc;
/* Load firmware segments */
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
if (!q6v5_phdr_valid(phdr))
continue;
offset = phdr->p_paddr - mpss_reloc;
if (offset < 0 || offset + phdr->p_memsz > qproc->mpss_size) {
dev_err(qproc->dev, "segment outside memory range\n");
ret = -EINVAL;
goto release_firmware;
}
if (phdr->p_filesz > phdr->p_memsz) {
dev_err(qproc->dev,
"refusing to load segment %d with p_filesz > p_memsz\n",
i);
ret = -EINVAL;
goto release_firmware;
}
ptr = memremap(qproc->mpss_phys + offset, phdr->p_memsz, MEMREMAP_WC);
if (!ptr) {
dev_err(qproc->dev,
"unable to map memory region: %pa+%zx-%x\n",
&qproc->mpss_phys, offset, phdr->p_memsz);
goto release_firmware;
}
if (phdr->p_filesz && phdr->p_offset < fw->size) {
/* Firmware is large enough to be non-split */
if (phdr->p_offset + phdr->p_filesz > fw->size) {
dev_err(qproc->dev,
"failed to load segment %d from truncated file %s\n",
i, fw_name);
ret = -EINVAL;
memunmap(ptr);
goto release_firmware;
}
memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);
} else if (phdr->p_filesz) {
/* Replace "xxx.xxx" with "xxx.bxx" */
sprintf(fw_name + fw_name_len - 3, "b%02d", i);
ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev,
ptr, phdr->p_filesz);
if (ret) {
dev_err(qproc->dev, "failed to load %s\n", fw_name);
memunmap(ptr);
goto release_firmware;
}
if (seg_fw->size != phdr->p_filesz) {
dev_err(qproc->dev,
"failed to load segment %d from truncated file %s\n",
i, fw_name);
ret = -EINVAL;
release_firmware(seg_fw);
memunmap(ptr);
goto release_firmware;
}
release_firmware(seg_fw);
}
if (phdr->p_memsz > phdr->p_filesz) {
memset(ptr + phdr->p_filesz, 0,
phdr->p_memsz - phdr->p_filesz);
}
memunmap(ptr);
size += phdr->p_memsz;
code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
if (!code_length) {
boot_addr = relocate ? qproc->mpss_phys : min_addr;
writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
}
writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG);
if (ret < 0) {
dev_err(qproc->dev, "MPSS authentication failed: %d\n",
ret);
goto release_firmware;
}
}
/* Transfer ownership of modem ddr region to q6 */
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true,
qproc->mpss_phys, qproc->mpss_size);
if (ret) {
dev_err(qproc->dev,
"assigning Q6 access to mpss memory failed: %d\n", ret);
ret = -EAGAIN;
goto release_firmware;
}
ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "MPSS authentication timed out\n");
else if (ret < 0)
dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret);
qcom_pil_info_store("modem", qproc->mpss_phys, qproc->mpss_size);
release_firmware:
release_firmware(fw);
out:
kfree(fw_name);
return ret < 0 ? ret : 0;
}
static void qcom_q6v5_dump_segment(struct rproc *rproc,
struct rproc_dump_segment *segment,
void *dest, size_t cp_offset, size_t size)
{
int ret = 0;
struct q6v5 *qproc = rproc->priv;
int offset = segment->da - qproc->mpss_reloc;
void *ptr = NULL;
/* Unlock mba before copying segments */
if (!qproc->dump_mba_loaded) {
ret = q6v5_reload_mba(rproc);
if (!ret) {
/* Reset ownership back to Linux to copy segments */
ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
true, false,
qproc->mpss_phys,
qproc->mpss_size);
}
}
if (!ret)
ptr = memremap(qproc->mpss_phys + offset + cp_offset, size, MEMREMAP_WC);
if (ptr) {
memcpy(dest, ptr, size);
memunmap(ptr);
} else {
memset(dest, 0xff, size);
}
qproc->current_dump_size += size;
/* Reclaim mba after copying segments */
if (qproc->current_dump_size == qproc->total_dump_size) {
if (qproc->dump_mba_loaded) {
/* Try to reset ownership back to Q6 */
q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm,
false, true,
qproc->mpss_phys,
qproc->mpss_size);
q6v5_mba_reclaim(qproc);
}
}
}
static int q6v5_start(struct rproc *rproc)
{
struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
int xfermemop_ret;
int ret;
ret = q6v5_mba_load(qproc);
if (ret)
return ret;
dev_info(qproc->dev, "MBA booted with%s debug policy, loading mpss\n",
qproc->dp_size ? "" : "out");
ret = q6v5_mpss_load(qproc);
if (ret)
goto reclaim_mpss;
ret = qcom_q6v5_wait_for_start(&qproc->q6v5, msecs_to_jiffies(5000));
if (ret == -ETIMEDOUT) {
dev_err(qproc->dev, "start timed out\n");
goto reclaim_mpss;
}
xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
false, qproc->mba_phys,
qproc->mba_size);
if (xfermemop_ret)
dev_err(qproc->dev,
"Failed to reclaim mba buffer system may become unstable\n");
/* Reset Dump Segment Mask */
qproc->current_dump_size = 0;
return 0;
reclaim_mpss:
q6v5_mba_reclaim(qproc);
q6v5_dump_mba_logs(qproc);
return ret;
}
static int q6v5_stop(struct rproc *rproc)
{
struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
int ret;
ret = qcom_q6v5_request_stop(&qproc->q6v5, qproc->sysmon);
if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "timed out on wait\n");
q6v5_mba_reclaim(qproc);
return 0;
}
static int qcom_q6v5_register_dump_segments(struct rproc *rproc,
const struct firmware *mba_fw)
{
const struct firmware *fw;
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
const struct elf32_hdr *ehdr;
struct q6v5 *qproc = rproc->priv;
unsigned long i;
int ret;
ret = request_firmware(&fw, qproc->hexagon_mdt_image, qproc->dev);
if (ret < 0) {
dev_err(qproc->dev, "unable to load %s\n",
qproc->hexagon_mdt_image);
return ret;
}
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
ehdr = (struct elf32_hdr *)fw->data;
phdrs = (struct elf32_phdr *)(ehdr + 1);
qproc->total_dump_size = 0;
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
if (!q6v5_phdr_valid(phdr))
continue;
ret = rproc_coredump_add_custom_segment(rproc, phdr->p_paddr,
phdr->p_memsz,
qcom_q6v5_dump_segment,
NULL);
if (ret)
break;
qproc->total_dump_size += phdr->p_memsz;
}
release_firmware(fw);
return ret;
}
static const struct rproc_ops q6v5_ops = {
.start = q6v5_start,
.stop = q6v5_stop,
.parse_fw = qcom_q6v5_register_dump_segments,
.load = q6v5_load,
};
static void qcom_msa_handover(struct qcom_q6v5 *q6v5)
{
struct q6v5 *qproc = container_of(q6v5, struct q6v5, q6v5);
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
}
static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
{
struct of_phandle_args args;
struct resource *res;
int ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
qproc->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(qproc->reg_base))
return PTR_ERR(qproc->reg_base);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(qproc->rmb_base))
return PTR_ERR(qproc->rmb_base);
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
"qcom,halt-regs", 3, 0, &args);
if (ret < 0) {
dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
return -EINVAL;
}
qproc->halt_map = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(qproc->halt_map))
return PTR_ERR(qproc->halt_map);
qproc->halt_q6 = args.args[0];
qproc->halt_modem = args.args[1];
qproc->halt_nc = args.args[2];
if (qproc->has_spare_reg) {
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
"qcom,spare-regs",
1, 0, &args);
if (ret < 0) {
dev_err(&pdev->dev, "failed to parse spare-regs\n");
return -EINVAL;
}
qproc->conn_map = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(qproc->conn_map))
return PTR_ERR(qproc->conn_map);
qproc->conn_box = args.args[0];
}
return 0;
}
static int q6v5_init_clocks(struct device *dev, struct clk **clks,
char **clk_names)
{
int i;
if (!clk_names)
return 0;
for (i = 0; clk_names[i]; i++) {
clks[i] = devm_clk_get(dev, clk_names[i]);
if (IS_ERR(clks[i])) {
int rc = PTR_ERR(clks[i]);
if (rc != -EPROBE_DEFER)
dev_err(dev, "Failed to get %s clock\n",
clk_names[i]);
return rc;
}
}
return i;
}
static int q6v5_pds_attach(struct device *dev, struct device **devs,
char **pd_names)
{
size_t num_pds = 0;
int ret;
int i;
if (!pd_names)
return 0;
while (pd_names[num_pds])
num_pds++;
for (i = 0; i < num_pds; i++) {
devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
if (IS_ERR_OR_NULL(devs[i])) {
ret = PTR_ERR(devs[i]) ? : -ENODATA;
goto unroll_attach;
}
}
return num_pds;
unroll_attach:
for (i--; i >= 0; i--)
dev_pm_domain_detach(devs[i], false);
return ret;
}
static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds,
size_t pd_count)
{
int i;
for (i = 0; i < pd_count; i++)
dev_pm_domain_detach(pds[i], false);
}
static int q6v5_init_reset(struct q6v5 *qproc)
{
qproc->mss_restart = devm_reset_control_get_exclusive(qproc->dev,
"mss_restart");
if (IS_ERR(qproc->mss_restart)) {
dev_err(qproc->dev, "failed to acquire mss restart\n");
return PTR_ERR(qproc->mss_restart);
}
if (qproc->has_alt_reset || qproc->has_spare_reg) {
qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev,
"pdc_reset");
if (IS_ERR(qproc->pdc_reset)) {
dev_err(qproc->dev, "failed to acquire pdc reset\n");
return PTR_ERR(qproc->pdc_reset);
}
}
return 0;
}
static int q6v5_alloc_memory_region(struct q6v5 *qproc)
{
struct device_node *child;
struct reserved_mem *rmem;
struct device_node *node;
struct resource r;
int ret;
/*
* In the absence of mba/mpss sub-child, extract the mba and mpss
* reserved memory regions from device's memory-region property.
*/
child = of_get_child_by_name(qproc->dev->of_node, "mba");
if (!child) {
node = of_parse_phandle(qproc->dev->of_node,
"memory-region", 0);
} else {
node = of_parse_phandle(child, "memory-region", 0);
of_node_put(child);
}
ret = of_address_to_resource(node, 0, &r);
of_node_put(node);
if (ret) {
dev_err(qproc->dev, "unable to resolve mba region\n");
return ret;
}
qproc->mba_phys = r.start;
qproc->mba_size = resource_size(&r);
qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size);
if (!qproc->mba_region) {
dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
&r.start, qproc->mba_size);
return -EBUSY;
}
if (!child) {
node = of_parse_phandle(qproc->dev->of_node,
"memory-region", 1);
} else {
child = of_get_child_by_name(qproc->dev->of_node, "mpss");
node = of_parse_phandle(child, "memory-region", 0);
of_node_put(child);
}
ret = of_address_to_resource(node, 0, &r);
of_node_put(node);
if (ret) {
dev_err(qproc->dev, "unable to resolve mpss region\n");
return ret;
}
qproc->mpss_phys = qproc->mpss_reloc = r.start;
qproc->mpss_size = resource_size(&r);
if (!child) {
node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2);
} else {
child = of_get_child_by_name(qproc->dev->of_node, "metadata");
node = of_parse_phandle(child, "memory-region", 0);
of_node_put(child);
}
if (!node)
return 0;
rmem = of_reserved_mem_lookup(node);
if (!rmem) {
dev_err(qproc->dev, "unable to resolve metadata region\n");
return -EINVAL;
}
qproc->mdata_phys = rmem->base;
qproc->mdata_size = rmem->size;
return 0;
}
static int q6v5_probe(struct platform_device *pdev)
{
const struct rproc_hexagon_res *desc;
struct q6v5 *qproc;
struct rproc *rproc;
const char *mba_image;
int ret;
desc = of_device_get_match_data(&pdev->dev);
if (!desc)
return -EINVAL;
if (desc->need_mem_protection && !qcom_scm_is_available())
return -EPROBE_DEFER;
mba_image = desc->hexagon_mba_image;
ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
0, &mba_image);
if (ret < 0 && ret != -EINVAL)
return ret;
rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
}
rproc->auto_boot = false;
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
qproc = (struct q6v5 *)rproc->priv;
qproc->dev = &pdev->dev;
qproc->rproc = rproc;
qproc->hexagon_mdt_image = "modem.mdt";
ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL)
goto free_rproc;
platform_set_drvdata(pdev, qproc);
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
goto free_rproc;
ret = q6v5_alloc_memory_region(qproc);
if (ret)
goto free_rproc;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
goto free_rproc;
}
qproc->proxy_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc;
}
qproc->reset_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
desc->active_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n");
goto free_rproc;
}
qproc->active_clk_count = ret;
ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
desc->proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
goto free_rproc;
}
qproc->proxy_reg_count = ret;
ret = q6v5_regulator_init(&pdev->dev, qproc->active_regs,
desc->active_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n");
goto free_rproc;
}
qproc->active_reg_count = ret;
ret = q6v5_pds_attach(&pdev->dev, qproc->active_pds,
desc->active_pd_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to attach active power domains\n");
goto free_rproc;
}
qproc->active_pd_count = ret;
ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds,
desc->proxy_pd_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
goto detach_active_pds;
}
qproc->proxy_pd_count = ret;
qproc->has_alt_reset = desc->has_alt_reset;
ret = q6v5_init_reset(qproc);
if (ret)
goto detach_proxy_pds;
qproc->version = desc->version;
qproc->need_mem_protection = desc->need_mem_protection;
qproc->has_mba_logs = desc->has_mba_logs;
ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM,
qcom_msa_handover);
if (ret)
goto detach_proxy_pds;
qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss");
qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
if (IS_ERR(qproc->sysmon)) {
ret = PTR_ERR(qproc->sysmon);
goto remove_subdevs;
}
ret = rproc_add(rproc);
if (ret)
goto remove_sysmon_subdev;
return 0;
remove_sysmon_subdev:
qcom_remove_sysmon_subdev(qproc->sysmon);
remove_subdevs:
qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
detach_active_pds:
q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
free_rproc:
rproc_free(rproc);
return ret;
}
static int q6v5_remove(struct platform_device *pdev)
{
struct q6v5 *qproc = platform_get_drvdata(pdev);
struct rproc *rproc = qproc->rproc;
rproc_del(rproc);
qcom_remove_sysmon_subdev(qproc->sysmon);
qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
rproc_free(rproc);
return 0;
}
static const struct rproc_hexagon_res sc7180_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){
"xo",
NULL
},
.reset_clk_names = (char*[]){
"iface",
"bus",
"snoc_axi",
NULL
},
.active_clk_names = (char*[]){
"mnoc_axi",
"nav",
NULL
},
.active_pd_names = (char*[]){
"load_state",
NULL
},
.proxy_pd_names = (char*[]){
"cx",
"mx",
"mss",
NULL
},
.need_mem_protection = true,
.has_alt_reset = false,
.has_mba_logs = true,
.has_spare_reg = true,
.version = MSS_SC7180,
};
static const struct rproc_hexagon_res sdm845_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){
"xo",
"prng",
NULL
},
.reset_clk_names = (char*[]){
"iface",
"snoc_axi",
NULL
},
.active_clk_names = (char*[]){
"bus",
"mem",
"gpll0_mss",
"mnoc_axi",
NULL
},
.active_pd_names = (char*[]){
"load_state",
NULL
},
.proxy_pd_names = (char*[]){
"cx",
"mx",
"mss",
NULL
},
.need_mem_protection = true,
.has_alt_reset = true,
.has_mba_logs = false,
.has_spare_reg = false,
.version = MSS_SDM845,
};
static const struct rproc_hexagon_res msm8998_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){
"xo",
"qdss",
"mem",
NULL
},
.active_clk_names = (char*[]){
"iface",
"bus",
"gpll0_mss",
"mnoc_axi",
"snoc_axi",
NULL
},
.proxy_pd_names = (char*[]){
"cx",
"mx",
NULL
},
.need_mem_protection = true,
.has_alt_reset = false,
.has_mba_logs = false,
.has_spare_reg = false,
.version = MSS_MSM8998,
};
static const struct rproc_hexagon_res msm8996_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "pll",
.uA = 100000,
},
{}
},
.proxy_clk_names = (char*[]){
"xo",
"pnoc",
"qdss",
NULL
},
.active_clk_names = (char*[]){
"iface",
"bus",
"mem",
"gpll0_mss",
"snoc_axi",
"mnoc_axi",
NULL
},
.need_mem_protection = true,
.has_alt_reset = false,
.has_mba_logs = false,
.has_spare_reg = false,
.version = MSS_MSM8996,
};
static const struct rproc_hexagon_res msm8916_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "mx",
.uV = 1050000,
},
{
.supply = "cx",
.uA = 100000,
},
{
.supply = "pll",
.uA = 100000,
},
{}
},
.proxy_clk_names = (char*[]){
"xo",
NULL
},
.active_clk_names = (char*[]){
"iface",
"bus",
"mem",
NULL
},
.need_mem_protection = false,
.has_alt_reset = false,
.has_mba_logs = false,
.has_spare_reg = false,
.version = MSS_MSM8916,
};
static const struct rproc_hexagon_res msm8974_mss = {
.hexagon_mba_image = "mba.b00",
.proxy_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "mx",
.uV = 1050000,
},
{
.supply = "cx",
.uA = 100000,
},
{
.supply = "pll",
.uA = 100000,
},
{}
},
.active_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "mss",
.uV = 1050000,
.uA = 100000,
},
{}
},
.proxy_clk_names = (char*[]){
"xo",
NULL
},
.active_clk_names = (char*[]){
"iface",
"bus",
"mem",
NULL
},
.need_mem_protection = false,
.has_alt_reset = false,
.has_mba_logs = false,
.has_spare_reg = false,
.version = MSS_MSM8974,
};
static const struct of_device_id q6v5_of_match[] = {
{ .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
{ .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
{ .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
{ .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss},
{ .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss},
{ .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
{ },
};
MODULE_DEVICE_TABLE(of, q6v5_of_match);
static struct platform_driver q6v5_driver = {
.probe = q6v5_probe,
.remove = q6v5_remove,
.driver = {
.name = "qcom-q6v5-mss",
.of_match_table = q6v5_of_match,
},
};
module_platform_driver(q6v5_driver);
MODULE_DESCRIPTION("Qualcomm Self-authenticating modem remoteproc driver");
MODULE_LICENSE("GPL v2");