c1db035d70
* 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>
2093 lines
50 KiB
C
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");
|