Merge remote-tracking branch 'origin/msm-5.4' into msm-waipio

* origin/msm-5.4 at kernel.lnx.5.4-200305.1
  soc: qcom: pmic_glink: add debugfs to filter logs
  msm: kgsl: Enable the CX GSDC before accessing IOMMU registers
  msm: kgsl: Move the IOMMU clocks to the KGSL device
  msm: kgsl: Move GMU to a component device
  msm: kgsl: Minor cleanups for kgsl bus probe
  msm: pcie: Revert "scale CX and rate change after DRV resume"
  defconfig: Enable CPU isolation cooling device for lahaina
  NFC: Add driver to configure NFC-I3C controller GPIOs
  soc: qcom: Kconfig: Fix the dependencies for minidump
  defconfig: lahaina-qgki: Move minidump to QGKI
  defconfig: lahaina: Enable qbt_handler DLKM
  qbt_handler: Make the qbt driver as DLKM for GKI
  msm: cvp: avoid OOB write while accessing memory
  clk: qcom: update the DisplayPort clocks
  scsi: ufs: crypto fix on QTI ufs
  iommu/arm-smmu: Cleanup qsmmuv500_iova_to_phys_hard()
  iommu/arm-smmu: Remove DOMAIN_ATTR_DEBUG
  iommu/arm-smmu: Cleanup arm_smmu_init()
  iommu/arm-smmu: Rationalize TLB sync timeout handling
  msm: kgsl: Make a device specific scales_bandwidth function
  msm-poweroff: Correct the SCM_DLOAD_BOTHDUMPS definition
  qcom_scm: Add entry for minidump download mode
  phy: ufs: Refactor phy_power_on and phy_calibrate callbacks
  dt-bindings: clock: Add support for clock ids for SHIMA
  drm: Add DisplayPort colorspace property creation function
  drm: Rename HDMI colorspace property creation function
  arm64: mm: improve the mem-offline device node availability check
  arm64: Honor limits set by boot parameter
  msm: cvp: Add AXI reset pulse
  msm: kgsl: Set default bus control to true
  defconfig: lahaina: Enable gpu devfreq governors on lahaina
  slim-msm-ngd: Check current state of sub system restart notifier
  slim-msm-ngd: Prevent system suspend during initialization
  defconfig: lahaina: enable QBT_HANDLER
  leds: qti-flash: Add maximum available flash current prediction
  qbt_handler: Change return type of qbt_poll
  scripts: gki: Ensure HOSTLD and HOSTAR are not changed
  scsi: ufs-qcom: Refactor phy_power_on/off calls
  scsi: ufs-qcom: Adjust the order of bus bandwidth voting and unvoting
  mm/oom-kill: Remove obsolete IS_ENABLED check
  mm/oom-kill: Add option to panic when killing foreground app
  defconfig: lahaina: Expose additional page debugging info
  mm, page_owner: set page owner info for tail pages
  mm/Kconfig: Re-add HAVE_USERSPACE_LOW_MEMORY_KILLER
  cnss2: Avoid double calling MHI force wake put
  cnss2: Add meta into as a segment to firmware RAM dump
  cnss2: Retry if PCI link training fails
  ANDROID: kbuild: avoid excessively long argument lists
  iommu/arm-smmu: Cleanup context fault logging logic
  trace/sched: Fix compilation issues on !SMP
  scsi: ufshcd-qti: Always allow vendor to configure clocks
  scsi: ufs-qcom: Get low power levels from devicetree
  scsi: ufshcd-qti: enable runtime-pm
  arm64: defconfig: Enable the pinctrl-shima driver
  pinctrl: qcom: Add support for Shima SoC pin control
  drivers: soc: qti: Add support for fingerprint driver
  ASoC: compare CPU DAI stream name to find BE DAI
  cnss2: Expose APIs to prevent and allow PCIe L1 state
  msm: pcie: add option to disable L1ss TO for DRV suspend
  msm: pcie: cache l1ss timeout in drv_info
  msm: pcie: scale CX and rate change after DRV resume
  msm: pcie: provide APIs to prevent and allow PCIe ASPM L1
  mmc: sdhci-msm: Support Retention of SDCC Regs in CX Collapse
  mmc: sdhci-msm: Add SD card DLL setting for SRD104 Mode
  mmc: sdhci-msm: Add support for bus bandwidth voting
  cnss2: Extend idle restart timeout
  msm: ADSPRPC: Enable Asynchronous RPC
  cnss2: Avoid idle restart completely if reboot is in progress
  cnss2: Add sysfs entry for system shutdown
  cnss2: Set WLAON_QFPROM_PWR_CTRL_REG during power on and off
  cnss2: Add sanity check for cnss pm runtime APIs
  cnss2: check wlfw mac before switching to mission mode
  msm: adsprpc: Initialize adsp memory region
  scsi: ufshcd-qti: Fix null pointer check
  defconfig: arm64: enable required configs for trusted VM
  defconfig: arm64: Enable data defconfigs
  Revert "mm: oom-kill: Add lmk_kill possible for ULMK"
  iommu/arm-smmu: Add support for active-only interconnect votes
  sched: walt: Improve the scheduler
  memshare: Modify the driver to be dynamically loadable
  msm: ipa: create ipa framework
  arm64: defconfig: Enable Shima platform
  arm64: Kconfig: Add config option for Shima
  slim-msm-ngd: Depend on PIL driver notification instead of qmi
  msm: kgsl: Initialize LPAC registers
  interconnect: Print the tag in the debugfs summary
  ucsi: start usb host mode when partner type is power cable/ufp
  msm: kgsl: Remove the extra recovery hop
  msm: kgsl: Set bus scaling function during gmu probe
  msm: kgsl: Keep a copy of CP INIT cmdstream
  msm: kgsl: Clear halt before gmu boot
  qseecom: change qseecom_process_listener_from_smcinvoke
  firmware: qcom_scm: fix for missing listener id
  Merge fbe changes from upstream 5.4
  msm: kgsl: Override UBWC configuration for A660 based on DDR type
  msm: kgsl: Add A660 hardware clock gating register values
  msm: ipa: Fix ipa3_wwan_xmit return type
  sched: walt: Improve the scheduler
  sched: walt: Improve the scheduler
  sched: walt: move walt_stats member in cfs_rq under CFS_BANDWIDTH
  sched: use rq_clock if WALT is not enabled
  trace: Add trace points for tasklet entry/exit
  defconfig: lahaina-qgki: Remove CONFIG_IIO config from QGKI
  defconfig: enable msm_performance driver on Lahaina
  interconnect: Move internal structs into a separate file
  interconnect: qcom: Add multiple voter support
  defconfig: Enable UFS BSG driver
  defconfig: lahaina-gki: enable the glink debug spmi controller driver
  spmi: add glink debug spmi controller driver
  haven: doorbell: Remove locks around read/send
  defconfig: arm64: Remove QTEE_SHM_BRIDGE
  scripts: gki: Add proper MAKE PATH
  pinctrl: qcom: Correctly configure the SDC2 pins
  ANDROID: Kconfig.gki: Remove most of the built in qcom clks
  include: regulator: Add header for RPM-SMD voltage levels
  dt-bindings: clock: update DisplayPort clock names for Lahaina
  drivers: llcc: Remove programming of cache override registers
  serial: msm_geni_serial: Set clock freq correctly for RUMI
  crypto: msm: add compat_qcedev to support 32bit process
  msm: adsprpc: protect access of context table
  soc: qcom: msm_perf: Add msm_performance module
  ion: don't wakeup refill threads for order-0 requests
  ion: Reduce secure system heap allocation time by stealing pages
  usb: dwc3: Do not initiate remote wakeup from core layer
  clk: qcom: remove flags for byte div clk src
  slim-msm-ngd: Add qmi deferred response check in pm resume
  slim-msm-ngd: Add wake lock to avoid race with suspend and SSR
  dt-bindings: ipcc: Add MPROC signal for TZ
  scsi: ufshcd-qti: Add quirk to disable fastauto mode
  scsi: ufshcd-qti: Fix hibern8 timeout during scaling
  clk: qcom: gpucc-lahaina: Remove CLK_IS_CRITICAL
  msm-geni-serial: Use dma_alloc_coherent to avoid dma map/unmap
  usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer
  msm: kgsl: Enable I/O coherency on A660
  kernel_headers: Add missing mem-buf.h UAPI header file
  memshare: Add snapshot of memshare driver
  thermal: adc-tm: Fix ADC_TM channel mapping
  thermal: adc-tm: Fix compilation recipe in makefile
  iio: adc: qcom-spmi-adc5: Add SID in ADC IIO channel properties
  ion: Fix pool refill error
  dt-bindings: interconnect: Add disp specific nodes for Lahaina
  iio: adc: Add full-scale voltage for PMIC7 ADC
  msm: ipa: Update debugfs to print rules correctly
  clk: qcom: clk-alpha-pll: Remove already enabled warning in PLL configs
  msm: ipa: Update WLAN pipes to use WLAN2 clients
  cnss2: Replace "%p" with "%pK"
  iio: adc: qcom-vadc-common: Change ADC7 die_temp output unit to mC
  defconfig: arm64: Enable QCOM_SCM driver
  arm64: Kconfig: Add ARCH_QCOM dependency for ARCH_QTI_VM
  defconfig: arm64: Add ARCH_QCOM config
  haven: Pass doorbell irq number to client callback
  interconnect: qcom: Remove duplicate compatible string
  interconnect: qcom: Configure QoS when provider is sync stated
  interconnect: qcom: Enable the QoS ports
  iommu: iommu-debug: Fix race with respect to test buffer allocation
  iommu: qti: Track iommu domains
  iommu: iommu-debug: Remove CONFIG_IOMMU_DEBUG_TRACKING
  arm64: defconfig: Disable CONFIG_IOMMU_DEBUG_TRACKING
  net: wireless: Add snapshot of db.txt
  Revert "cfg80211: reg: remove support for built-in regdb"
  interconnect: qcom: Do not set any QoS for the NSP
  defconfig: msm: Enable QUPv3 drivers on Lahaina QGKI perf image
  arm64: defconfig: Enable CPUFREQ-HW for Lahaina
  leds: qti-flash: Add support for qti_flash_led_prepare()
  msm: adsprpc: Cache invalidate optimization
  Revert "pinctrl: msm: Configure interrupts as input and gpio mode"
  msm: adsprpc: Cache flush operation optimization
  arm64: defconfig: Enable the mem-buf driver on Lahaina QGKI
  soc: qcom: mem-buf: Add support for inter-VM memory sharing
  msm: kgsl: Do not mark all buffers as iocoherent
  arm64: defconfig: Enable CONFIG_PANIC_ON_OOPS
  arm64: defconfig: Add LOCALVERSION strings for Lahaina
  clk: qcom: Cache vdd vote if clk is unprepared
  arm64: defconfig: Enable QCOM watchdog for Lahaina
  radio: RTC6226: fill device capabilities in video_device
  thermal: adc-tm: Correct a macro expression for PMIC7 ADC_TM
  msm: adsprpc: Remove output buffers from cache flush logic
  msm: adsprpc: Add error handling checks
  msm: adsprpc: Add force no flush and invalidate flag
  adsprpc: use uint for counters and maintain consistency in datatypes
  msm: adsprpc: Remove remote mappings after PD is up
  clk: qcom: gcc-lahaina: Enable gpu_memnoc_gfx and gpu_snoc_dvm_gfx always
  msm: cvp: buffer managerment optimization for Lahaina
  soc: qcom: Add forever loop after non-secure bite configuration
  defconfig: lahaina: enable FSA driver on Lahaina
  sched: Provide stub definitions for WALT
  haven: Add support for MEM_NOTIFY
  haven: Add support for MEM_SHARE/MEM_LEND
  haven: Add support for the MEM_ACCEPT call
  haven: Add support for the MEM_RELEASE/MEM_RECLAIM calls
  haven: Add support for the MEM_QCOM_LOOKUP_SGL call
  haven: Add support for the mem-buf driver's message queue
  haven: Add the memparcel handle as a well known haven type
  PM / devfreq: Remove dependencies between sysfs nodes and suspend count
  soc: qcom: Remove incorrect error check from Guest VM PIL Loader
  eud: Handle multiple events with eud interrupt
  i3c: i3c-master-msm-geni: Support for 3.4 Mhz,400 Khz
  kernel_headers: Fix headers not detected in incremental builds
  dma-mapping-fast: Align memory allocation to dma_alloc_attrs expectations
  msm: cvp: Disable CVP power collapse
  leds: qti-flash: Add individual APIs to enable and disable switch
  defconfig: lahaina-gki: Enable USB Audio QMI Service driver
  sound: usb: Fix incorrect type assignments
  arm64: defconfig: Enable USB_F_FS_IPC_LOGGING for lahaina_debug, take 3
  power: supply: qti_battery_charger: Handle generic notification
  soc: qcom: qti_battery_debug: Update QBG device context dump length
  arm64: defconfig: Enable new touchscreen on Lahaina
  arm64: defconfig: Enable touchscreen on Lahaina
  defconfig: lahaina: Enable KGSL driver
  serial: msm_geni_serial: Cover console under GENI_CONSOLE config
  defconfig: lahaina: Enable DYNAMIC_DEBUG
  firmware: shmbridge: Enable shmbridge by default
  serial: msm_geni_serial: Manage HSUART clocks when read HW Ver
  arm64: defconfig: Enable QCOM EUD driver
  clk: qcom: clk-rpmh: Wait for completion when enabling clocks
  ANDROID: serdev: Fix platform device support
  msm: tsens: Add code to support thermal framework changes
  soc: qcom: rpmh: Add completion status to rpmh debug information
  msm: kgsl: Add rgmu_init() for firmware loading
  leds: qti-flash: Update interrupt names
  ASoC: Update the widgets power up/down sequence
  msm: cvp: Enable CVP auto PIL
  thermal: adc-tm: Fix match table description and Makefile
  ASoC: pcm: update the start-up sequence for playback
  msm: synx: redesign callback registration and dispatch
  ion: msm: Add support for secure allocations for the Trusted UI(TUI) VMID
  soc: qcom: secure_buffer: Add support for the Trusted UI(TUI) VMID
  lib/list_sort: fix function type mismatches
  kernel_headers: Add missing header for lahaina
  crypto: msm: Rename qcrypto module
  crypto: msm: Build qcedev and qcedev-smmu together
  crypto: msm: Fix compile errors
  crypto: msm: Fix incorrect boolean logic
  Revert "defconfig: lahaina: enable FSA driver on Lahaina"
  Add hdcp_qseecom driver snapshot for Lahaina
  mm: set the watermark_boost before updating the low and high wmarks
  mm, oom: check LMK enabled for pagefault_out_of_memory()
  mm: oom: enable the sysctl_reap_mem_on_sigkill by default
  defconfig: Enable userspace low memory killer for Lahaina
  mm, oom: Modify default value of panic_on_oom
  mm: oom-kill: Add lmk_kill possible for ULMK
  defconfig: arm64: Add SELinux configs
  defconfig: lahaina: Enable CONFIG_EDAC_QGKI flag
  drivers: edac: Avoid configuring interrupt register in polling mode
  arm64: defconfig: Enable Haven HVC Driver
  tty: Add Haven RM Console driver
  haven: rm: Add VM Services - Console APIs
  haven: rm: Add IRQ Management APIs for IRQ lending
  msm: kgsl: Fix gdsc disable timeout during reset
  msm: kgsl: Always boot GMU with default CM3 config
  ion: msm: Add support for the Trusted UI(TUI) dynamic carveout heap
  coresight-etm4x: Don't set LPOVERRIDE bit when tupwr-disable is true
  ASoC: pcm: update arch_setup_dma_ops to of_dma_configure for hostless
  mm: make faultaround produce old ptes
  wil6210: prevent ioctl access while in reset or suspend
  drivers: edac: Defer work for the polling EDAC driver
  edac: Allow the option of creating a deferrable work for polling
  ASoC: dt-bindings: update soundwire port configurations
  defconfig: lahaina: Enable hv-haptics driver
  input: qcom-hv-haptics: correct pattern source checking logic
  defconfig: lahaina: enable FSA driver on Lahaina
  defconfig: lahaina: Enable the Type-C alternate mode driver
  soc: qcom: Add Type-C alternate mode driver
  ion: Add support for dynamic carveout heaps
  i3c: i3c-master-msm-geni: Propagate tip changes from 4.19
  leds: qti-flash: Fix updating flags when disabling flash/torch device
  sound: usb: Add snapshot for usb audio qmi driver
  ion: msm: Add support for addition/removal of memory to ION heaps
  ion: msm: Add support for querying the security state of heaps
  ion: msm: Add support for mapping VMIDs to ION flags
  Bluetooth: Remove unused regulator entries
  msm: cvp: Relocate Synx init/uninit calls
  qseecom: add compat_qseecom to support 32bit process
  drivers: llcc: edac: Add a config flag for non GKI variants
  msm: cvp: Enable CVP power collapse and LLC
  defconfig: arm64: Enable wakelock feature for lahaina
  defconfig: Enable ARCH_QTI_VM config
  arm64: Kconfig: Add config option for QTI's virtual machine
  soc: qcom: ipcc: Do not reset the device during probe
  power: reset: use nvmem restart_reason
  sched/fair: bonus vruntime for task boost 3
  defconfig: Split CNSS configs to GKI and debug
  devfreq: memlat: Add CPU Hotplug and Idle awareness in memlat
  input: touchscreen: Enable new Focaltech touch driver
  soc: qcom: rpmh: Correct rpm_msg pointer offset and add list_del
  drivers: cpuidle: lpm-levels: Move local_irq_enable
  drivers: soc: qcom: rpmh: Correctly set dirty flag
  include/linux: add HDCP QSEECOM header file
  arm64: defconfig: Enable USB Mass Storage drivers on Lahaina
  arm64: defconfig: lahaina: Enable GuestVM PIL support
  soc: qcom: Add Guest VM PIL loader
  dwc3-msm: Add USB role switch handling
  ucsi: Add usage of USB role switch functionality
  scsi: ufs: Fix phy init sequence
  haven: Add VM management support for clients
  arm64: defconfig: Enable haven doorbell driver
  haven: Add haven doorbell driver
  arm64: defconfig: Enable Haven virtualization drivers
  haven: Add Haven Resource Manager Driver
  arm64: defconfig: Enable extcon USB GPIO driver on Lahaina
  msm: kgsl: Make the scratch privileged
  clk: qcom: gdsc-regulator: Add support for proxy consumers
  msm: kgsl: Set busmon driver data
  msm: kgsl: Do not call dispatcher functions directly
  drivers: thermal: Avoid trip evaluation for disabled thermal zone
  haven: Add Haven Message Queue driver
  arch: arm64: hh: Add Haven arm64 hypercall interface
  haven: hcall: Add Haven hypercall interface
  haven: Add common Haven types and macros
  Revert "rpmsg: glink: Set tail pointer to 0 at end of FIFO"
  Revert "PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX"
  Revert "UPSTREAM: firmware/qcom_scm: Add scm call to handle smmu errata"
  Revert "UPSTREAM: firmware: qcom_scm-64: Add atomic version of qcom_scm_call"
  Revert "UPSTREAM: cpufreq: qcom-hw: Move driver initialization earlier"
  msm: kgsl: Dump maximum possible IB1 size in snapshot
  scsi: ufs-qti: Remove the second init in hba probe path
  ufs: ufs-qcom: Clean up UFS PHY mode and submode selection
  msm: kgsl: Handle error from nvmem_cell_read while reading speed_bin fuse
  coresight: csr: read MSR start address and size from dt
  regulator: Add snapshot of qpnp-amoled regulator driver
  msm: cvp: fix DSP probe crash
  sched: micro optimization for sched_energy_present
  extcon: usb-gpio: Add support for optional VBUS output enable GPIO
  msm: ipa4: debug patch gsi interrupt issue
  usb: ep0: complete the pending control request before soft-disconnect
  mhi: dev: uci: add support for DIAG and DCI clients
  msm: cvp: Add debug node control power collapse
  msm: pcie: always enable BDF to SID for PCIe RC mode
  msm: adsprpc: detect privileged processes based on group ID
  eud: Set pdev->id value to 0 and add set_mctrl() API
  usb: dwc3: Remove extra format specifier
  psi: Improve ftrace events
  soc: qcom: spcom: propagate print macro parameters to pr_*()
  psi: print threshold time in decimal
  psi: use proper accessor
  msm: adsprpc: Separate header and non-ion copy buffer
  sched/uclamp: Fix a bug in propagating uclamp value in new cgroups
  input: qti-hv-haptics: Add debugfs parameters to configure effects
  input: qcom,hv-haptics: Add DT definitions
  input: misc: Add initial driver to support QTI HV haptics
  clk: qcom: clk-alpha-pll: Fix zonda set_rate failure when PLL is disabled
  arm64: Call idle notifiers in CPU idle
  ANDROID: idle_notifier: Add generic idle notifiers
  defconfig: lahaina: enable QTI battery debug driver
  soc: qcom: add initial version of qti_battery_debug driver
  kernel_headers: Add missing kernel headers to lahaina
  defconfig: enable QSEECOM as a GKI module
  qseecom: use of_reserved_mem_lookup to get heap base and size
  iommu/arm-smmu: Use an atomic context when fastmap is set on GKI
  msm: pcie: remove PCI_MSM_MSI dependencies
  msm: pcie: add support to control pipe clk mux for LPM
  msm: pcie: add support for gcc_aggre_noc_pcie_*_axi_clk
  qseeecom: Fix possible unused function
  clk: qcom: gpucc: Enable cx_gmu, hub_cx_int_clk always
  usb: gadget: configfs: Add max_speed setting
  iommu-debug: allocate test_virt_addr when reading it
  iommu: iommu-debug: Fix return code for iommu_debug_dma_unmap_write
  Add support BT/FM CHK 3.2 chip
  f_fs: Return correct USB endpoint descriptor to user space daemon
  usb: gadget: Update functions for SSP descriptors
  defconfig: lahaina: correct PMIC ADC driver config enablement
  defconfig: lahaina: remove disablement of SPMI temp alarm driver
  clk: qcom: gpucc: Add support for HLOS1_VOTE_GPU_SMMU_CLK
  dt-bindings: clock: Add support for HLOS1_VOTE_SMMU_CLK
  hrtimer: fix issue during core isolation
  kernel headers: Update comparison logic
  scsi: ufs: Make crypto updates on QTI ufs
  arm64: defconfig: Enable MSM PCIe and MHI Host driver for lahaina
  msm: pcie: configure PCIe and MSI as modules in Makefile
  iommu: io-pgtable-fast: Fix IOMMU configuration usage in self-tests
  dwc3-msm: Add dwc3_msm_release_ss_lane() API
  msm: cvp: Support releasing persistent buffer
  msm: kgsl: Move secvid programming to gpudev
  msm: kgsl: Do dispatcher init at first open
  msm: kgsl: Move APRIV config to a6xx start
  msm: kgsl: Move preemption start to ringbuffer start
  msm: kgsl: Move ringbuffer global allocations to init time
  msm: kgsl: Fix memory leak in a6xx_init
  msm: kgsl: Create first_open and last_close
  msm: kgsl: Add function to get context bank number
  Revert "devfreq: bimc_bwmon: Add support to enable BWMON clks"
  arm64: defconfig: Enable memory debug configs on Lahaina
  usb: dwc3-msm: Fix out-of-bounds access in bus voting
  pwm: pwm-qti-lpg: Refactor qpnp_lpg_parse_dt() for readability
  soc: fsa4480-i2c: Register with UCSI for audio accessory notifications
  ucsi: ucsi_glink: Notify upon change in connector status
  linux: scm: Update the API for assign memory to subsys
  arm64: defconfig: enable flash LED driver on Lahaina
  leds: add support for QTI flash LED driver
  ANDROID: Re-use SUGOV_RT_MAX_FREQ to control uclamp rt behavior
  ANDROID: cpufreq/schedutil: Select frequency using util_avg for RT
  pwm: pwm-qti-lpg: Handle nvmem device lookup failure properly
  clk: qcom: clk-rpmh: Mark rfclka2 as optional for Lahaina
  tracing: rework sched_preempt_disable trace point implementation
  sched: core: reset preemption/irqsoff disable timestamp
  defconfig: enable schedutil governor on Lahaina
  msm: cvp: Use compiler data type in uapi
  sched/core: Fix size of rq::uclamp initialization
  iommu/arm-smmu: log outstanding transactions on sync timeout
  msm: gsi: Fix the WARNING for gsi_write_channel_scratch
  arm64: defconfig: Enable QRTR MHI on lahaina_debug
  interconnect: qcom: Add QoS config support
  net: qrtr: Introduce MHI transport for qrtr
  PM / devfreq: Make governor registration less verbose
  regulator: qcom_pm8008-regulator: correct chip-en chip variable type
  cpuidle: lpm-levels: update lpm_disallowed() with sched hints
  mhi: Export more symbols
  mhi: Fix compile errors
  msm: pcie: update PCIe RC and MSI driver to compile as GKI modules
  regulator: qcom_pm8008: correct parent supply voltage voting
  arm64: defconfig: Enable CFI_PERMISSIVE flag
  scripts: gki: Add LD to make args to enable CFI/LTO
  soc: qcom: glink_pkt: Fix minor version in device creation
  Revert "usb: dwc3: gadget: Fix logical condition"
  arm64: defconfig: Enable SG support in Lahaina GKI
  defconfig: lahaina: enable the battery charger driver
  power: supply: Add QTI battery charger
  defconfig: lahaina-gki: enable the qcom_pm8008-regulator driver
  regulator: qcom_pm8008: allow multiple PM8008 instances with unique names
  regulator: qcom_pm8008: change reg property format from u16 to u32
  regulator: qcom_pm8008: Add LDO OCP interrupt support
  regulator: add a regulator driver for the PM8008 PMIC
  defconfig: Add kernel hardening features
  dwc3: gadget: Fix dr_mode check with USB device mode APIs
  msm: ipa4: Fix to unmap the page if skb allocation failed
  defconfig: lahaina-gki: enable various USB CONFIGFS functions
  usb: gadget: f_cdev: Fix func_suspend
  usb: gadget: Make USB_CONFIGFS_NCM buildable as a module
  usb: gadget: f_gsi: Fix function suspend
  usb: gadget: Add function wakeup support
  cnss2: Add daemon_support dts option for QCA6390
  input: touchscreen: Add new Focaltech touch driver
  regulator: refgen: add support for proxy consumers
  regulator: rpmh-regulator: support parent supply specification in subnodes
  msm: kgsl: Remove write-only register from snapshot
  arm64: defconfig: Enable TSENS driver for lahaina
  memory_dump: add new feature for cpuss dump
  iommu/iova: Limit IOVA alignment using CONFIG_ARM64_DMA_IOMMU_ALIGNMENT
  power: reset: Add qcom_dload command to poweroff driver
  msm: ipa: clear the ipa pipeline before any ep config
  Revert "cnss2: Add support to monitor PM QOS votes"
  net: cnss2: Build generic netlink support by default
  sched/fair: consider uclamp boost while deciding the start_cpu
  NFC: Add support to get NFC interface type
  msm: ipa: split quota stat memory between q6 and ap
  Example kernel headers header_lib package
  uapi: sound: remove redundant QGKI config checks
  Revert "FROMLIST: scsi: ufs-qcom: Adjust bus bandwidth voting and unvoting"
  msm: kgsl: Remove icc path from gmu device
  msm: kgsl: Add support for multiple ddr tables
  msm: kgsl: Setup LPAC global pagetable
  msm: kgsl: Check snapshot status after snapshot
  msm: kgsl: Update a660 CP indexed register ranges
  qcom: soc_sleep_stats: Correctly read accumulated sleep length
  iommu/arm-smmu: Replace while loop with for_each_set_bit
  iommu/arm-smmu: enhance tlb sync timeout handler
  uapi: sound: remove redundant QGKI config checks
  soc: qcom: pmic_glink: add support for multiple pmic_glink devices
  psi: Use deferrable psi_avgs_work
  psi: Introduce ftrace events
  cnss2: NULL terminate FW build ID string
  arm64: defconfig: Enable CMA performance optimizations on Lahaina
  mm: Allow only __GFP_CMA allocations from Movable zone
  mm: fix the use of ALLOC_CMA
  zram: allow zram to allocate CMA pages
  mm: fix cma accounting in zone_watermark_ok
  mm: add cma pcp list
  arm64: defconfig: Re-enable USB_F_FS_IPC_LOGGING for lahaina_debug
  cma: redirect page allocation to CMA
  arm64: defconfig: Enable CMA debug configs on Lahaina
  Revert "mm: cma: make writeable CMA debugfs optional"
  ion: Make MSM pool auto refill built-in only
  soc: qcom: Add module dependence for spss_utils
  input: touchscreen: Enable FTS Touch driver
  input: touchscreen: Add STMicroelectronics Touchscreen driver
  drivers: lpm-levels: Use cpu_do_idle for shallower LPM entry
  wil6210: add ioctl interface
  wil6210: fix vendor command policy for vendor unspec commands
  wil6210: add policy for all vendor commands
  NFC: Made the QTI NFC drivers GKI compliant
  Revert "defconfig: lahaina: Enable QRNG driver"
  interconnect: qcom: Add sync_state for Lahaina QNOC
  defconfig: Lahaina: update external display module config
  soc: pil: Disable error-ready timeout
  uapi: sound: remove redundant QGKI config checks
  smp: Wake up all idle CPUs when suspending to idle
  uapi: sound: remove redundant QGKI config checks
  uapi: sound: remove redundant QGKI config checks
  uapi: sound: remove redundant QGKI config checks
  arm64: defconfig: Enable CONFIG_MODULE_SIG to allow module signing
  defconfig: lahaina: enable QTI crypto driver
  msm: cvp: Avoid overflowing the stack frame
  arm64: defconfig: Enable RTB driver
  devfreq: bwmon: Export symbols
  driver: soc: qcom: Fix function prototype
  PM / devfreq: memlat: Export symbols
  drivers: qcom: Fix a parameter for sysfs_attr_init()
  PM / devfreq: Fix CONFIG check for cache HW monitor prototype
  clocks: Add a missing header to clk/qcom/common.h
  PM /devfreq:  Fix function prototype
  PM / devfreq: memlat: Use the cpumask_pr_args macros
  msm: kgsl: Remove unused header from gpu_bwmon
  thermal: Fix trace_thermal_zone_trip
  dma-buf: Export missing dma_buf_ref_mod symbol
  iommu: dma-mapping-fast: Export symbols
  drivers: pinctrl: Export msm_qup_write
  PM / devfreq: Add MODULE_LICENSE for arm-memlat-mon
  PM / devfreq: Export tracepoint symbols
  firmware: qcom-scm: Force built in drivers to depend on QCOM SCM
  coresight: Remove duplicate Kconfig entries
  include: Fixup headers to pass KERNEL_HEADER_TEST
  soc: spcom: Add ipc logging engine
  uapi: sound: remove redundant QGKI config check
  msm: IPA: remove unsupport enum for uC debug stats
  msm: cvp: CVP DSP driver restructure for Lahaina
  arm64: defconfig: Enable USB role switch driver on lahaina
  clk: qcom: Fix accessing of clks element during the probe
  usb: gadget: Don't perform start xfer with USB BAM endpoint
  msm: cvp: FD support in fence path
  cpufreq: schedutil: fix CPU util when WALT is enabled
  drivers: thermal: Add support to change thermal zone configuration
  arm64: defconfig: Enable debug cc clock driver for Lahaina
  arm64: defconfig: Enable CONFIG_BALANCE_ANON_FILE_RECLAIM on Lahaina
  arm64: defconfig: Enable clean page reclaim tracking on Lahaina
  iommu/arm-smmu: Fix memory leak with respect to TBU data structures
  msm: cvp: Enable CVP driver on DSP
  defconfig: change default governor to performance on lahaina
  hwrng: update qrng driver copyright and license marking
  msm:ipa: Address the -Wmisleading-indentation warning
  socinfo: Avoid sysfs entry name changes between kernel versions
  clk: qcom: rcg: update the DFS macro for RCG
  msm: pcie: correct error check of wakeup source registration
  msm: kgsl: Disable GBIF_CLIENT_QOS on a660v1
  msm: kgsl: Skip the intersecting vma
  clk: qcom: debug: Remove use of hw init
  clk: qcom: Add debug cc clk measure nodes for Lahaina
  arm64: defconfig: Remove CONFIG_SPS from lahaina_debug.config
  msm: ipa4: Fix using of tag_desc
  NFC: Add NFC hardware check and get info ioctl
  cpufreq: qcom-cpufreq-hw: Initialize the data type for offsets to u16
  ASoC: core: Add compat ioctl support for listen driver
  msm: ipa: Fix using generic name for offload connect/disconnect
  msm: ipa: stop remote IPA channels if tethering is not enabled
  arm64: defconfig: Enable SMCInvoke driver for Lahaina
  SMCInvoke: Add SMCInvoke driver snapshot for Lahaina
  msm: cvp: remove version and deprecated functions
  qseecom: update interface as per new scm driver
  msm: cvp: Add flush api in uapi
  drivers: thermal: Add config sysfs entry support for thermal zones
  mm: swap: Add null pointer check
  selinux: stop flooding the log buffer
  fs/buffer.c: Revoke LRU when trying to drop buffers
  defconfig: arm64: Enable sched debug features on Lahaiana
  sched/core: Fix compilation issues when WALT is enabled
  sched/fair: skip 6% energy check when best_energy_cpu is idle
  interconnect: qcom: Change bcm voter initlevel
  clk: qcom: gcc-lahaina: Add PCIe and UFS clock muxes
  dt-bindings: clock: gcc: Add PCIe pipe and UFS symbol clocks
  clk: qcom: Fix incorrect mux_get_parent mapping
  defconfig: Lahaina: enable external display module
  msm: ipa: vote for device side through mhi for tethering use cases
  msm: ipa: tune mhip ring size shrink to 6 elements
  defconfig: lahaina-qgki: Enable thermal drivers
  msm:ipa: mhip ring size optimization
  msm:ipa: uc based flow control for UL tethering offload
  msm:ipa: stop UL IPA TX channel at the end of the probe
  msm:ipa: continue ODL  logging on MHIP post modem SSR
  coresight: csr: update programming sequence of enabling etr to bam
  coresight: fix tmc flush timeout issue
  coresight: tmc: leverage etr disable/enable when switching mode
  coresight: tmc: add usb support to etr
  platform: msm: add support for external display module
  usb: typec: ucsi: fix spelling mistake "connetor" -> "connector"
  usb: typec: ucsi: Actually enable all the interface notifications
  usb: typec: ucsi: Store the notification mask
  usb: typec: ucsi: Fix the notification bit offsets
  PM / QoS: Reorder pm_qos/freq_qos/dev_pm_qos structs
  PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX
  arm64: defconfig: Enable USB QDSS and USB BAM drivers on Lahaina
  msm: kgsl: Check correct register for clamps on a660
  msm: kgsl: Set DMA Mask for gmu device
  msm: kgsl: Setup CP_CHICKEN_DBG register for a660
  msm: kgsl: Add A660 to the gpulist
  dt-bindings: clock: add MDSS clock names for Lahaina
  iommu/arm-smmu: avoid possible deadlock during map_sg
  iommu: Fixup selftests
  ion:  Fix API changes in dma-buf-ref.c
  sched: walt: Improve the scheduler
  sched: walt: improve the scheduler
  sched/fair: Don't place wakee on waker cpu if colocate enabled
  arm64: defconfig: Enable qseecom driver for Lahaina
  msm: kgsl: Don't error out if dst size is not equal to src in copy_prop
  arm64: defconfig: Enable SPS driver for lahaina
  msm:ipa: Race condition observed during client disconnect
  defconfig: Enable DCC driver for GKI
  dt-bindings: Add new port types for SWR 1.6 feature
  HID: Trace events for external sensor driver
  HID: qvr: Correct axes orientation
  HID:correct mag axis config for External viewer
  HID: qvr: wait event interruptible timeout change
  HID: qvr: Decrease wait event interruptible timeout value
  HID: qvr: Optimized Viewer Requirements
  HID: qvr: Code refactoring
  HID: Read calibration data from external sensor
  HID: Filtering mag data depending on timestamp
  HID: external sensor driver
  msm: adsprpc: HMX,Async-FastRPC capability
  sched/walt: Avoid walt irq work in offlined cpu
  sched/fair: Improve the scheduler
  interconnect: qcom: Fix MACRO fields for Lahaina
  iinterconnect: qcom: Hold high bandwidth vote for keepalive BCMs
  scsi: ufshcd-qti: Port the new crypto framework to QTI ufs
  msm: ipa: Add SMMU driver as soft dependency for IPA
  include: sound: add stub function for wcd dsp manager
  iommu/arm-smmu: Rename the ARM SMMU module
  regmap: Quit the read-loop based on position of file-offset
  arm64: qcom: Enable QTI config
  scsi: ufs-qti: Check for valid vcc before accessing
  iommu/arm-smmu: Use dev_iommu_fwspec_get() to retrieve IOMMU fwspec
  iommu/arm-smmu: Unregister TBU driver when unloading the SMMU module
  crypto: msm: Add QTI crypto drivers
  iommu/arm-smmu: Add missing iommu_device_unregister()
  msm: ipa: fix ipa_disable_apps_wan_cons_deaggr declaration
  Revert "drivers: qcom: cmd-db: modularize commandDB driver"
  msm: kgsl: Calculate the offset of context bank 0
  arm64: defconfig: Enable poweroff driver for Lahaina GKI
  power: reset: Add snapshot of msm-poweroff
  msm: kgsl: Refactor IOMMU contexts
  msm: kgsl: Support global secure memory objects
  msm: kgsl: Add a function to map global buffers
  msm: ipa3: IPA clock vote ioctl
  msm: ipa3: IPA clock vote ioctl
  msm: tsens: Add Tsens driver snapshot
  arm64: defconfig: Enable slimbus driver config for lahaina
  msm: cvp: remove additional checks in response_handler
  defconfig: lahaina: Enable ADC drivers for lahaina
  coresight: tmc: etr: Add sys interface for ETR
  thermal: adc-tm: Add support for PMIC7 ADC_TM
  thermal: adc-tm: Add ADC_TM driver snapshot
  msm: ipa : Fix KW array index issue on dbg_buff
  msm: IPA: add the missing iounmap handle
  arm64: defconfig: Enable all memory hotplug related configs on Lahaina
  soc: qcom: mem-offline: Clear page-table entries after offline
  soc: qcom: mem-offline: Set offlinable region based on minimum DDR sizes
  arm64: Update dram end address while randomizing base
  arm64: mm/memblock: Update memory limit calculation
  drivers: base: expose amount allocated per block
  dma-mapping-fast: Remap contiguous pages only when needed
  arm64: mm: Fix compilation when CONFIG_MEMORY_HOTPLUG is not enabled
  mm, oom: Try to online memory block before killing
  arm64: Make section size configurable for memory hotplug
  mm/memory_hotplug: Add hot-added memory blocks to ZONE_MOVABLE type
  arm64: Override memory limit set by boot parameter
  soc: qcom: mem-offline: Add a snapshot of the mem-offline driver
  qseecom: Add qseecom driver snapshot for Lahaina
  defconfig: Lahaina: Enable support for WLAN
  arm64: defconfig: Enable TSENS driver for lahaina
  firmware: qcom_scm: Add changes for tsens reinit
  NFC: Add NFC I2C and I3C drivers for SNxxx
  Linux 5.4.7
  iwlwifi: pcie: move power gating workaround earlier in the flow
  nbd: fix shutdown and recv work deadlock v2
  mmc: sdhci: Add a quirk for broken command queuing
  mmc: sdhci: Workaround broken command queuing on Intel GLK
  mmc: sdhci-of-esdhc: fix P2020 errata handling
  mmc: sdhci: Update the tuning failed messages to pr_debug level
  mmc: sdhci-of-esdhc: Revert "mmc: sdhci-of-esdhc: add erratum A-009204 support"
  mmc: sdhci-msm: Correct the offset and value for DDR_CONFIG register
  ocxl: Fix concurrent AFU open and device removal
  powerpc/irq: fix stack overflow verification
  powerpc/vcpu: Assume dedicated processors as non-preempt
  x86/mce: Fix possibly incorrect severity calculation on AMD
  x86/MCE/AMD: Allow Reserved types to be overwritten in smca_banks[]
  x86/MCE/AMD: Do not use rdmsr_safe_on_cpu() in smca_configure()
  x86/intel: Disable HPET on Intel Coffee Lake H platforms
  KVM: arm64: Ensure 'params' is initialised when looking up sys register
  KVM: arm/arm64: Properly handle faulting of device mappings
  kvm: x86: Host feature SSBD doesn't imply guest feature AMD_SSBD
  kvm: x86: Host feature SSBD doesn't imply guest feature SPEC_CTRL_SSBD
  KVM: PPC: Book3S HV: Fix regression on big endian hosts
  iocost: over-budget forced IOs should schedule async delay
  ext4: validate the debug_want_extra_isize mount option at parse time
  ext4: unlock on error in ext4_expand_extra_isize()
  ext4: check for directory entries too close to block end
  ext4: fix ext4_empty_dir() for directories with holes
  clk: imx: pll14xx: fix clk_pll14xx_wait_lock
  clk: imx: clk-composite-8m: add lock to gate/mux
  clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table
  pinctrl: baytrail: Really serialize all register accesses
  serial: sprd: Add clearing break interrupt operation
  tty/serial: atmel: fix out of range clock divider handling
  staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value
  platform/x86: hp-wmi: Make buffer for HPWMI_FEATURE2_QUERY 128 bytes
  intel_th: msu: Fix window switching without windows
  intel_th: Fix freeing IRQs
  intel_th: pci: Add Elkhart Lake SOC support
  intel_th: pci: Add Comet Lake PCH-V support
  USB: EHCI: Do not return -EPIPE when hub is disconnected
  mm: vmscan: protect shrinker idr replace with CONFIG_MEMCG
  KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails
  cpufreq: Avoid leaving stale IRQ work items during CPU offline
  efi/memreserve: Register reservations as 'reserved' in /proc/iomem
  spi: fsl: use platform_get_irq() instead of of_irq_to_resource()
  spi: fsl: don't map irq during probe
  usbip: Fix error path of vhci_recv_ret_submit()
  usbip: Fix receive error in vhci-hcd when using scatter-gather
  can: flexcan: add low power enter/exit acknowledgment helper
  ARM: dts: Fix vcsi regulator to be always-on for droid4 to prevent hangs
  s390/ftrace: fix endless recursion in function_graph tracer
  md: avoid invalid memory access for array sb->dev_roles
  RDMA/siw: Fix post_recv QP state locking
  ath10k: Revert "ath10k: add cleanup in ath10k_sta_state()"
  drm/amdgpu: fix uninitialized variable pasid_mapping_needed
  usb: xhci: Fix build warning seen with CONFIG_PM=n
  spi: cadence: Correct handling of native chipselect
  spi: dw: Correct handling of native chipselect
  selftests: net: tls: remove recv_rcvbuf test
  can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices
  can: flexcan: poll MCR_LPM_ACK instead of GPR ACK for stop mode acknowledgment
  can: flexcan: fix possible deadlock and out-of-order reception after wakeup
  can: j1939: j1939_sk_bind(): take priv after lock is held
  can: m_can: tcan4x5x: add required delay after reset
  can: xilinx_can: Fix missing Rx can packets on CANFD2.0
  iommu/vt-d: Allocate reserved region for ISA with correct permission
  iommu/vt-d: Set ISA bridge reserved region as relaxable
  iommu/vt-d: Fix dmar pte read access not set error
  iommu: set group default domain before creating direct mappings
  iommu: fix KASAN use-after-free in iommu_insert_resv_region
  tpm: fix invalid locking in NONBLOCKING mode
  tpm_tis: reserve chip for duration of tpm_tis_core_init
  mmc: mediatek: fix CMD_TA to 2 for MT8173 HS200/HS400 mode
  Revert "mmc: sdhci: Fix incorrect switch to HS mode"
  btrfs: don't prematurely free work in scrub_missing_raid56_worker()
  btrfs: don't prematurely free work in reada_start_machine_worker()
  MIPS: futex: Restore \n after sync instructions
  net: wireless: intel: iwlwifi: fix GRO_NORMAL packet stalling
  ibmvnic: Fix completion structure initialization
  RDMA/bnxt_re: Fix chip number validation Broadcom's Gen P5 series
  bpf: Provide better register bounds after jmp32 instructions
  RDMA/bnxt_re: Fix stat push into dma buffer on gen p5 devices
  RDMA/bnxt_re: Fix missing le16_to_cpu
  tools, bpf: Fix build for 'make -s tools/bpf O=<dir>'
  net: phy: initialise phydev speed and duplex sanely
  ice: Fix setting coalesce to handle DCB configuration
  ice: Only disable VF state when freeing each VF resources
  drm/amdgpu: fix bad DMA from INTERRUPT_CNTL2
  mips: fix build when "48 bits virtual memory" is enabled
  libtraceevent: Fix memory leakage in copy_filter_type
  crypto: vmx - Avoid weird build failures
  mac80211: consider QoS Null frames for STA_NULLFUNC_ACKED
  crypto: sun4i-ss - Fix 64-bit size_t warnings on sun4i-ss-hash.c
  crypto: sun4i-ss - Fix 64-bit size_t warnings
  s390/cpumf: Adjust registration of s390 PMU device drivers
  mt76: fix possible out-of-bound access in mt7615_fill_txs/mt7603_fill_txs
  net: ethernet: ti: ale: clean ale tbl on init and intf restart
  ASoC: soc-pcm: check symmetry before hw_params
  fbtft: Make sure string is NULL terminated
  iwlwifi: check kasprintf() return value
  bnxt_en: Improve RX buffer error handling.
  s390/kasan: support memcpy_real with TRACE_IRQFLAGS
  s390/crypto: Fix unsigned variable compared with zero
  perf probe: Fix to show function entry line as probe-able
  perf session: Fix decompression of PERF_RECORD_COMPRESSED records
  brcmfmac: remove monitor interface when detaching
  net-af_xdp: Use correct number of channels from ethtool
  x86/insn: Add some Intel instructions to the opcode map
  ASoC: Intel: bytcr_rt5640: Update quirk for Acer Switch 10 SW5-012 2-in-1
  firmware_loader: Fix labels with comma for builtin firmware
  net: phy: avoid matching all-ones clause 45 PHY IDs
  bnxt_en: Return proper error code for non-existent NVM variable
  selftests, bpf: Workaround an alu32 sub-register spilling issue
  selftests, bpf: Fix test_tc_tunnel hanging
  perf/core: Fix the mlock accounting, again
  ASoC: wm5100: add missed pm_runtime_disable
  spi: st-ssc4: add missed pm_runtime_disable
  ASoC: wm2200: add missed operations in remove and probe failure
  sched/uclamp: Fix overzealous type replacement
  btrfs: don't prematurely free work in run_ordered_work()
  btrfs: don't prematurely free work in end_workqueue_fn()
  mmc: tmio: Add MMC_CAP_ERASE to allow erase/discard/trim requests
  crypto: virtio - deal with unsupported input sizes
  xhci-pci: Allow host runtime PM as default also for Intel Ice Lake xHCI
  tun: fix data-race in gro_normal_list()
  spi: tegra20-slink: add missed clk_unprepare
  regulator: core: Let boot-on regulators be powered off
  ASoC: wm8904: fix regcache handling
  iwlwifi: mvm: fix unaligned read of rx_pkt_status
  bcache: fix deadlock in bcache_allocator
  tracing/kprobe: Check whether the non-suffixed symbol is notrace
  MIPS: ralink: enable PCI support only if driver for mt7621 SoC is selected
  tracing: use kvcalloc for tgid_map array allocation
  RDMA/efa: Clear the admin command buffer prior to its submission
  qtnfmac: fix using skb after free
  x86/crash: Add a forward declaration of struct kimage
  qtnfmac: fix invalid channel information output
  qtnfmac: fix debugfs support for multiple cards
  cpufreq: Register drivers only after CPU devices have been registered
  bcache: fix static checker warning in bcache_device_free()
  parport: load lowlevel driver if ports not found
  nvme: Discard workaround for non-conformant devices
  net: ethernet: ti: Add dependency for TI_DAVINCI_EMAC
  s390/disassembler: don't hide instruction addresses
  r8169: respect EEE user setting when restarting network
  net: dsa: sja1105: Disallow management xmit during switch reset
  ASoC: Intel: kbl_rt5663_rt5514_max98927: Add dmic format constraint
  bpf, testing: Workaround a verifier failure for test_progs
  iio: dac: ad5446: Add support for new AD5600 DAC
  ASoC: rt5677: Mark reg RT5677_PWR_ANLG2 as volatile
  spi: pxa2xx: Add missed security checks
  media: vim2m: media_device_cleanup was called too early
  media: vicodec: media_device_cleanup was called too early
  EDAC/ghes: Fix grain calculation
  iio: cros_ec_baro: set info_mask_shared_by_all_available field
  media: v4l2-ctrl: Lock main_hdl on operations of requests_queued.
  media: cedrus: Use helpers to access capture queue
  media: si470x-i2c: add missed operations in remove
  ice: delay less
  crypto: atmel - Fix authenc support when it is set to m
  soundwire: intel: fix PDI/stream mapping for Bulk
  media: pvrusb2: Fix oops on tear-down when radio support is not present
  selftests: net: Fix printf format warnings on arm
  fsi: core: Fix small accesses and unaligned offsets via sysfs
  ath10k: fix get invalid tx rate for Mesh metric
  media: exynos4-is: fix wrong mdev and v4l2 dev order in error path
  drm/amdgpu: Avoid accidental thread reactivation.
  selftests: proc: Make va_max 1MB
  cgroup: freezer: don't change task and cgroups status unnecessarily
  s390/bpf: Use kvcalloc for addrs array
  libbpf: Fix negative FD close() in xsk_setup_xdp_prog()
  perf probe: Filter out instances except for inlined subroutine and subprogram
  perf probe: Skip end-of-sequence and non statement lines
  perf probe: Fix to show calling lines of inlined functions
  perf probe: Return a better scope DIE if there is no best scope
  net: avoid potential false sharing in neighbor related code
  perf probe: Skip overlapped location on searching variables
  perf parse: If pmu configuration fails free terms
  xen/gntdev: Use select for DMA_SHARED_BUFFER
  ice: Check for null pointer dereference when setting rings
  drm/amdgpu: fix potential double drop fence reference
  drm/amd/powerplay: fix struct init in renoir_print_clk_levels
  drm/amdgpu: disallow direct upload save restore list from gfx driver
  perf tools: Splice events onto evlist even on error
  perf tools: Fix cross compile for ARM64
  perf probe: Fix to probe a function which has no entry pc
  libsubcmd: Use -O0 with DEBUG=1
  perf probe: Fix to show inlined function callsite without entry_pc
  perf probe: Fix to show ranges of variables in functions without entry_pc
  perf probe: Fix to probe an inline function which has no entry pc
  perf probe: Walk function lines in lexical blocks
  perf jevents: Fix resource leak in process_mapfile() and main()
  perf probe: Fix to list probe event with correct line number
  perf cs-etm: Fix definition of macro TO_CS_QUEUE_NR
  perf probe: Fix to find range-only function instance
  rtlwifi: fix memory leak in rtl92c_set_fw_rsvdpagepkt()
  drm: msm: a6xx: fix debug bus register configuration
  RDMA/core: Fix return code when modify_port isn't supported
  ALSA: timer: Limit max amount of slave instances
  spi: img-spfi: fix potential double release
  bnx2x: Fix PF-VF communication over multi-cos queues.
  spi: dw: Fix Designware SPI loopback
  media: vivid: media_device_cleanup was called too early
  ASoC: SOF: topology: set trigger order for FE DAI link
  nvmem: core: fix nvmem_cell_write inline function
  nvmem: imx-ocotp: reset error status on probe
  media: staging/imx: Use a shorter name for driver
  nvme: introduce "Command Aborted By host" status code
  media: v4l2-core: fix touch support in v4l_g_fmt
  media: rcar_drif: fix a memory disclosure
  cpufreq: sun50i: Fix CPU speed bin detection
  ixgbe: protect TX timestamping from API misuse
  pinctrl: amd: fix __iomem annotation in amd_gpio_irq_handler()
  pinctrl: qcom: sc7180: Add missing tile info in SDC_QDSD_PINGROUP/UFS_RESET
  ASoC: SOF: imx: fix reverse CONFIG_SND_SOC_SOF_OF dependency
  spi: sifive: disable clk when probe fails and remove
  ALSA: pcm: Fix missing check of the new non-cached buffer type
  Bluetooth: Fix advertising duplicated flags
  libbpf: Fix error handling in bpf_map__reuse_fd()
  iio: dln2-adc: fix iio_triggered_buffer_postenable() position
  ALSA: bebob: expand sleep just after breaking connections for protocol version 1
  pinctrl: sh-pfc: sh7734: Fix duplicate TCLK1_B
  net/mlx5e: Verify that rule has at least one fwd/drop action
  loop: fix no-unmap write-zeroes request behavior
  libata: Ensure ata_port probe has completed before detach
  net: hns3: add struct netdev_queue debug info for TX timeout
  s390/mm: add mm_pxd_folded() checks to pxd_free()
  s390: add error handling to perf_callchain_kernel
  s390/time: ensure get_clock_monotonic() returns monotonic values
  phy: qcom-usb-hs: Fix extcon double register after power cycle
  phy: renesas: phy-rcar-gen2: Fix the array off by one warning
  net: dsa: LAN9303: select REGMAP when LAN9303 enable
  gpu: host1x: Allocate gather copy for host1x
  staging: wilc1000: check if device is initialzied before changing vif
  RDMA/core: Set DMA parameters correctly
  RDMA/qedr: Fix srqs xarray initialization
  RDMA/hns: Fix memory leak on 'context' on error return path
  RDMA/qedr: Fix memory leak in user qp and mr
  ACPI: button: Add DMI quirk for Medion Akoya E2215T
  spi: sprd: adi: Add missing lock protection when rebooting
  ubsan, x86: Annotate and allow __ubsan_handle_shift_out_of_bounds() in uaccess regions
  regulator: core: Release coupled_rdevs on regulator_init_coupling() error
  drm/tegra: sor: Use correct SOR index on Tegra210
  net: phy: dp83867: enable robust auto-mdix
  i40e: Wrong 'Advertised FEC modes' after set FEC to AUTO
  drm/amd/display: correctly populate dpp refclk in fpga
  i40e: initialize ITRN registers with correct values
  drm/amd/display: setting the DIG_MODE to the correct value.
  arm64: psci: Reduce the waiting time for cpu_psci_cpu_kill()
  EDAC/amd64: Set grain per DIMM
  drm: Don't free jobs in wait_event_interruptible()
  md/bitmap: avoid race window between md_bitmap_resize and bitmap_file_clear_bit
  staging: wilc1000: potential corruption in wilc_parse_join_bss_param()
  md: no longer compare spare disk superblock events in super_load
  media: smiapp: Register sensor after enabling runtime PM on the device
  media: aspeed: clear garbage interrupts
  media: imx7-mipi-csis: Add a check for devm_regulator_get
  media: st-mipid02: add a check for devm_gpiod_get_optional
  media: ov5640: Make 2592x1944 mode only available at 15 fps
  media: ad5820: Define entity function
  media: ov6650: Fix stored frame interval not in sync with hardware
  drm/nouveau: Don't grab runtime PM refs for HPD IRQs
  media: aspeed: set hsync and vsync polarities to normal before starting mode detection
  media: cedrus: Fix undefined shift with a SHIFT_AND_MASK_BITS macro
  x86/ioapic: Prevent inconsistent state when moving an interrupt
  ipmi: Don't allow device module unload when in use
  RDMA/siw: Fix SQ/RQ drain logic
  rtl8xxxu: fix RTL8723BU connection failure issue after warm reboot
  ASoC: soc-pcm: fixup dpcm_prune_paths() loop continue
  drm/gma500: fix memory disclosures due to uninitialized bytes
  RDMA/hns: Fix wrong parameters when initial mtt of srq->idx_que
  net: hns3: log and clear hardware error after reset complete
  selftests/bpf: Make a copy of subtest name
  perf tests: Disable bp_signal testing for arm64
  power: supply: cpcap-battery: Check voltage before orderly_poweroff
  staging: iio: ad9834: add a check for devm_clk_get
  drm/amdgpu: fix amdgpu trace event print string format error
  drm/amd/display: fix header for RN clk mgr
  drm/amd/display: enable hostvm based on roimmu active for dcn2.1
  x86/mce: Lower throttling MCE messages' priority to warning
  bpf/stackmap: Fix deadlock with rq_lock in bpf_get_stack()
  Bluetooth: hci_core: fix init for HCI_USER_CHANNEL
  Bluetooth: Workaround directed advertising bug in Broadcom controllers
  Bluetooth: missed cpu_to_le16 conversion in hci_init4_req
  Bluetooth: btusb: avoid unused function warning
  iio: adc: max1027: Reset the device at probe time
  drm/amd/powerplay: avoid disabling ECC if RAS is enabled for VEGA20
  usb: usbfs: Suppress problematic bind and unbind uevents.
  perf vendor events arm64: Fix Hisi hip08 DDRC PMU eventname
  perf test: Avoid infinite loop for task exit case
  perf report: Add warning when libunwind not compiled in
  perf test: Report failure for mmap events
  drm/bridge: dw-hdmi: Restore audio when setting a mode
  rtw88: coex: Set 4 slot mode for A2DP
  ath10k: Correct error handling of dma_map_single()
  x86/mm: Use the correct function type for native_set_fixmap()
  drm/amd/display: Program DWB watermarks from correct state
  extcon: sm5502: Reset registers during initialization
  drm/amd/display: Fix dongle_caps containing stale information.
  syscalls/x86: Use the correct function type in SYSCALL_DEFINE0
  drm/amd/display: add new active dongle to existent w/a
  media: ti-vpe: vpe: fix a v4l2-compliance failure about invalid sizeimage
  drm/amd/display: wait for set pipe mcp command completion
  drm/amd/display: Properly round nominal frequency for SPD
  media: ti-vpe: vpe: ensure buffers are cleaned up properly in abort cases
  media: ti-vpe: vpe: fix a v4l2-compliance failure causing a kernel panic
  media: ti-vpe: vpe: Make sure YUYV is set as default format
  media: ti-vpe: vpe: fix a v4l2-compliance failure about frame sequence number
  media: ti-vpe: vpe: fix a v4l2-compliance warning about invalid pixel format
  media: ti-vpe: vpe: Fix Motion Vector vpdma stride
  ASoC: SOF: enable sync_write in hdac_bus
  misc: fastrpc: fix memory leak from miscdev->name
  crypto: aegis128/simd - build 32-bit ARM for v8 architecture explicitly
  crypto: inside-secure - Fix a maybe-uninitialized warning
  media: cx88: Fix some error handling path in 'cx8800_initdev()'
  team: call RCU read lock when walking the port_list
  net/smc: increase device refcount for added link group
  libbpf: Fix passing uninitialized bytes to setsockopt
  libbpf: Fix struct end padding in btf_dump
  selftests/bpf: Fix btf_dump padding test case
  drm/drm_vblank: Change EINVAL by the correct errno
  mwifiex: pcie: Fix memory leak in mwifiex_pcie_init_evt_ring
  MIPS: futex: Emit Loongson3 sync workarounds within asm
  drm/amdkfd: Fix MQD size calculation
  block: Fix writeback throttling W=1 compiler warnings
  samples: pktgen: fix proc_cmd command result check logic
  drm/bridge: dw-hdmi: Refuse DDC/CI transfers on the internal I2C controller
  media: meson/ao-cec: move cec_notifier_cec_adap_register after hw setup
  media: cec-funcs.h: add status_req checks
  media: flexcop-usb: fix NULL-ptr deref in flexcop_usb_transfer_init()
  tools/memory-model: Fix data race detection for unordered store and load
  regulator: max8907: Fix the usage of uninitialized variable in max8907_regulator_probe()
  hwrng: omap3-rom - Call clk_disable_unprepare() on exit only if not idled
  crypto: aegis128-neon - use Clang compatible cflags for ARM
  usb: renesas_usbhs: add suspend event support in gadget mode
  drm/amd/display: fix struct init in update_bounding_box
  rtw88: fix NSS of hw_cap
  media: venus: Fix occasionally failures to suspend
  drm/amd/display: set minimum abm backlight level
  selftests/bpf: Correct path to include msg + path
  drm/amd/powerplay: A workaround to GPU RESET on APU
  x86/math-emu: Check __copy_from_user() result
  drm/amdkfd: fix a potential NULL pointer dereference (v2)
  drm/sun4i: dsi: Fix TCON DRQ set bits
  pinctrl: devicetree: Avoid taking direct reference to device name string
  drm/amd/display: Set number of pipes to 1 if the second pipe was disabled
  media: vimc: Fix gpf in rmmod path when stream is active
  ath10k: fix offchannel tx failure when no ath10k_mac_tx_frm_has_freq
  media: venus: core: Fix msm8996 frequency table
  tools/power/cpupower: Fix initializer override in hsw_ext_cstates
  media: ov6650: Fix stored crop rectangle not in sync with hardware
  media: ov6650: Fix stored frame format not in sync with hardware
  media: i2c: ov2659: Fix missing 720p register config
  media: ov6650: Fix crop rectangle alignment not passed back
  media: i2c: ov2659: fix s_stream return value
  media: ov6650: Fix control handler not freed on init error
  media: max2175: Fix build error without CONFIG_REGMAP_I2C
  media: vim2m: Fix BUG_ON in vim2m_device_release()
  media: vim2m: Fix abort issue
  media: seco-cec: Add a missing 'release_region()' in an error handling path
  media: cedrus: fill in bus_info for media device
  media: am437x-vpfe: Setting STD to current value is not an error
  spi: gpio: prevent memory leak in spi_gpio_probe
  drm/komeda: Workaround for broken FLIP_COMPLETE timestamps
  IB/iser: bound protection_sg size by data_sg size
  ath10k: fix backtrace on coredump
  Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit31 when using SIM0_D"
  Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit30 when using SSI_SCK2 and SSI_WS2"
  libertas: fix a potential NULL pointer dereference
  rtlwifi: prevent memory leak in rtl_usb_probe
  staging: rtl8188eu: fix possible null dereference
  staging: rtl8192u: fix multiple memory leaks on error path
  drm/meson: vclk: use the correct G12A frac max value
  spi: Add call to spi_slave_abort() function when spidev driver is released
  ath10k: Check if station exists before forwarding tx airtime report
  drm/amd/display: Handle virtual signal type in disable_link()
  ath10k: add cleanup in ath10k_sta_state()
  drm/amd/display: Rebuild mapped resources after pipe split
  drm/ttm: return -EBUSY on pipelining with no_gpu_wait (v2)
  drm/amdgpu: grab the id mgr lock while accessing passid_mapping
  drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 code
  iio: light: bh1750: Resolve compiler warning and make code more readable
  iio: max31856: add missing of_node and parent references to iio_dev
  drm/amd/display: OTC underflow fix
  drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings
  drm/amd/display: verify stream link before link test
  drm: Use EOPNOTSUPP, not ENOTSUPP
  drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register
  drm/panel: Add missing drm_panel_init() in panel drivers
  drm/mipi-dbi: fix a loop in debugfs code
  drm: mst: Fix query_payload ack reply struct
  drm/virtio: switch virtio_gpu_wait_ioctl() to gem helper.
  drm/vc4/vc4_hdmi: fill in connector info
  ALSA: hda/ca0132 - Fix work handling in delayed HP detection
  ALSA: hda/ca0132 - Avoid endless loop
  ALSA: hda/ca0132 - Keep power on during processing DSP response
  ALSA: pcm: Avoid possible info leaks from PCM stream buffers
  Btrfs: fix removal logic of the tree mod log that leads to use-after-free issues
  btrfs: handle ENOENT in btrfs_uuid_tree_iterate
  btrfs: do not leak reloc root if we fail to read the fs root
  btrfs: skip log replay on orphaned roots
  btrfs: abort transaction after failed inode updates in create_subvol
  btrfs: send: remove WARN_ON for readonly mount
  Btrfs: fix missing data checksums after replaying a log tree
  btrfs: return error pointer from alloc_test_extent_buffer
  Btrfs: make tree checker detect checksum items with overlapping ranges
  btrfs: do not call synchronize_srcu() in inode_tree_del
  btrfs: don't double lock the subvol_sem for rename exchange
  NFC: nxp-nci: Fix probing without ACPI
  net: dsa: b53: Fix egress flooding settings
  net: stmmac: platform: Fix MDIO init for platforms without PHY
  net: ethernet: ti: davinci_cpdma: fix warning "device driver frees DMA memory with different size"
  mlxsw: spectrum_router: Remove unlikely user-triggerable warning
  dpaa2-ptp: fix double free of the ptp_qoriq IRQ
  net: ena: fix issues in setting interrupt moderation params in ethtool
  net: ena: fix default tx interrupt moderation interval
  bonding: fix bond_neigh_init()
  neighbour: remove neigh_cleanup() method
  selftests: forwarding: Delete IPv6 address at the end
  sctp: fully initialize v4 addr in some functions
  sctp: fix memleak on err handling of stream initialization
  qede: Fix multicast mac configuration
  qede: Disable hardware gro when xdp prog is installed
  nfp: flower: fix stats id allocation
  net: usb: lan78xx: Fix suspend/resume PHY register access error
  net-sysfs: Call dev_hold always in rx_queue_add_kobject
  net: qlogic: Fix error paths in ql_alloc_large_buffers()
  net: phy: ensure that phy IDs are correctly typed
  net: nfc: nci: fix a possible sleep-in-atomic-context bug in nci_uart_tty_receive()
  net: hisilicon: Fix a BUG trigered by wrong bytes_compl
  net: gemini: Fix memory leak in gmac_setup_txqs
  net: dst: Force 4-byte alignment of dst_metrics
  mod_devicetable: fix PHY module format
  fjes: fix missed check in fjes_acpi_add
  af_packet: set defaule value for tmo
  arm64: defconfig: Enable CPUFREQ-HW for Lahaina
  arm64: Add fallback option during memory hot add
  mm/Kconfig: Enable MEMORY_HOTPLUG for arm64
  arm64: Honor limits set by bootloader
  arm64: Add "remove" probe driver for memory hot-remove
  arm64: Hot-remove implementation for arm64
  arm64: memory-hotplug: Add MEMORY_HOTPLUG, MEMORY_HOTREMOVE, MEMORY_PROBE
  arm64: Memory hotplug support for arm64 platform
  msm: IPA: uC debug stats for loadable modules
  ASoC: compress: add support for Vorbis and amrwb_plus
  ANDROID: Kconfig.gki: Add Hidden SPRD DRM configs
  defconfig: Enable MHI Host driver for lahaina
  mhi: add snapshot for MHI driver stack
  mhi: core: export symbols for references
  uapi: sound: add new meta key to get DSP render position
  Kconfig: add description for AUDIO_QGKI
  SoC: pcm: Add delay_blk feature
  include: Add snapshot of header files for wcd spi and dsp manager
  ALSA: jack: Add support to report second microphone
  defconfig: lahaina-qgki: enable CONFIG_AUDIO_QGKI
  uapi: sound: latency mode support for transcode loopback
  ASoC: msm: add support for different compressed formats
  ASoc: msm: qdspv2: Clock recovery support in compress driver
  dt-bindings: sound: Add snapshot of audio port types for soundwire
  ASoC: msm: qdsp6v2: Add TrueHD HDMI compress pass-though
  msm: dt-binding: add snapshot of audio external clockfor Lahaina
  ASoC: msm: qdsp6v2: Support to set session start delay
  arm64: defconfig: Enable CONFIG_BT_SLIM on Lahaina
  bluetooth: add change for btfm slimbus driver
  ASoC: msm: qdsp6v2: Support to configure render window
  ASoC: msm: qdsp6v2: Support to configure clk recovery mode
  ASoC: msm: qdsp6v2: Support to configure render mode
  ASoC: Cold start latency reduction
  SoC: soc-pcm: call pcm_new when creating new pcm
  ASoC: compress: update snd_soc_platform to snd_soc_component
  ANDROID: Add a tracepoint for mapping inode to full path
  Revert "drm/virtio: fix DRM_FORMAT_* handling"
  ANDROID: gki_defconfig: Disable TRANSPARENT_HUGEPAGE
  staging: android: ion: Remove unused rbtree for ion_buffer
  kasan: Zero shadow memory on memory hotplug
  defconfig: lahaina: Enable QRNG driver
  drivers: slimbus: Makefile: Correct makefile configuration
  ASoC: core: Support for compress ioctls
  ASoC: pcm: Add support for compat mode
  wil6210: notify cfg80211_new_sta upon connection before init tx ring
  wil6210: allow disabling EDMG through force_edmg_channel debugfs
  wil6210: fix update SSID when changing beacon
  Linux 5.4.6
  ALSA: hda: Fix regression by strip mask fix
  drm/amdgpu: add invalidate semaphore limit for SRIOV and picasso in gmc9
  drm/amdgpu: avoid using invalidate semaphore for picasso
  drm/i915/gvt: Fix cmd length check for MI_ATOMIC
  drm/amdgpu/gfx10: re-init clear state buffer after gpu reset
  drm/amdgpu/gfx10: explicitly wait for cp idle after halt/unhalt
  drm/amdgpu: invalidate mmhub semaphore workaround in gmc9/gmc10
  drm/amdgpu: initialize vm_inv_eng0_sem for gfxhub and mmhub
  drm/amd/display: add default clocks if not able to fetch them
  drm/amd/display: re-enable wait in pipelock, but add timeout
  drm/dp_mst: Correct the bug in drm_dp_update_payload_part1()
  drm/radeon: fix r1xx/r2xx register checker for POT textures
  drm/i915/fbc: Disable fbc by default on all glk+
  drm/nouveau/kms/nv50-: Limit MST BPC to 8
  drm/nouveau/kms/nv50-: Store the bpc we're using in nv50_head_atom
  drm/nouveau/kms/nv50-: Call outp_atomic_check_view() before handling PBN
  scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd
  scsi: qla2xxx: Correctly retrieve and interpret active flash region
  scsi: qla2xxx: Change discovery state before PLOGI
  scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX
  scsi: qla2xxx: Initialize free_work before flushing it
  scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd
  scsi: iscsi: Fix a potential deadlock in the timeout handler
  scsi: ufs: Disable autohibern8 feature in Cadence UFS
  dm thin: Flush data device before committing metadata
  dm thin metadata: Add support for a pre-commit callback
  dm clone: Flush destination device before committing metadata
  dm clone metadata: Use a two phase commit
  dm clone metadata: Track exact changes per transaction
  dm btree: increase rebalance threshold in __rebalance2()
  dm mpath: remove harmful bio-based optimization
  drm: meson: venc: cvbs: fix CVBS mode matching
  drm/mgag200: Flag all G200 SE A machines as broken wrt <startadd>
  drm/mgag200: Add workaround for HW that does not support 'startadd'
  drm/mgag200: Store flags from PCI driver data in device structure
  drm/mgag200: Extract device type from flags
  drm/panfrost: Fix a race in panfrost_gem_free_object()
  drm/panfrost: Fix a BO leak in panfrost_ioctl_mmap_bo()
  drm/panfrost: Fix a race in panfrost_ioctl_madvise()
  dma-buf: Fix memory leak in sync_file_merge()
  vfio/pci: call irq_bypass_unregister_producer() before freeing irq
  ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume()
  ARM: dts: s3c64xx: Fix init order of clock providers
  cifs: Fix retrieval of DFS referrals in cifs_mount()
  CIFS: Fix NULL pointer dereference in mid callback
  CIFS: Do not miss cancelled OPEN responses
  CIFS: Close open handle after interrupted close
  CIFS: Respect O_SYNC and O_DIRECT flags during reconnect
  cifs: Don't display RDMA transport on reconnect
  cifs: smbd: Return -ECONNABORTED when trasnport is not in connected state
  cifs: smbd: Return -EINVAL when the number of iovs exceeds SMBDIRECT_MAX_SGE
  cifs: smbd: Add messages on RDMA session destroy and reconnection
  cifs: smbd: Only queue work for error recovery on memory registration
  cifs: smbd: Return -EAGAIN when transport is reconnecting
  rpmsg: glink: Free pending deferred work on remove
  rpmsg: glink: Don't send pending rx_done during remove
  rpmsg: glink: Fix rpmsg_register_device err handling
  rpmsg: glink: Put an extra reference during cleanup
  rpmsg: glink: Fix use after free in open_ack TIMEOUT case
  rpmsg: glink: Fix reuse intents memory leak issue
  rpmsg: glink: Set tail pointer to 0 at end of FIFO
  xtensa: fix syscall_set_return_value
  xtensa: fix TLB sanity checker
  gfs2: fix glock reference problem in gfs2_trans_remove_revoke
  gfs2: Multi-block allocations in gfs2_page_mkwrite
  xtensa: use MEMBLOCK_ALLOC_ANYWHERE for KASAN shadow map
  block: fix "check bi_size overflow before merge"
  PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX
  PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3
  PCI: rcar: Fix missing MACCTLR register setting in initialization sequence
  PCI: Do not use bus number zero from EA capability
  PCI/MSI: Fix incorrect MSI-X masking on resume
  PCI: Fix Intel ACS quirk UPDCR register address
  PCI: pciehp: Avoid returning prematurely from sysfs requests
  PCI/PM: Always return devices to D0 when thawing
  PCI/switchtec: Read all 64 bits of part_event_bitmap
  mmc: core: Re-work HW reset for SDIO cards
  mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan()
  mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response
  mmc: block: Make card_busy_detect() a bit more generic
  USB: Fix incorrect DMA allocations for local memory pool drivers
  ANDROID: update ABI for db845c changes
  BACKPORT: iommu: arm-smmu-impl: Add sdm845 implementation hook
  UPSTREAM: firmware/qcom_scm: Add scm call to handle smmu errata
  UPSTREAM: firmware: qcom_scm-64: Add atomic version of qcom_scm_call
  UPSTREAM: cpufreq: qcom-hw: Move driver initialization earlier
  UPSTREAM: cpufreq: Initialize cpufreq-dt driver earlier
  UPSTREAM: cpufreq: Initialize the governors in core_initcall
  ANDROID: tty: serial_core: Export uart_console_device so it can be used by modules
  ANDROID: gki_defconfig: Add qcom pcie options to gki_defconfig
  ANDROID: Kconfig.gki: Add entries for qcom clk drivers
  ANDROID: Kconfig.gki: Add PINCTRL_MSM to QCOM Hidden configs
  ANDROID: Kconfig.gki: Add hidden CONFIG_WANT_DEV_COREDUMP for DRM_MSM driver
  ANDROID: PCI: qcom: Add support for SDM845 PCIe controller
  ANDROID: PCI: qcom: Fix the fixup of PCI_VENDOR_ID_QCOM
  ANDROID: phy: qcom: qmp: Add SDM845 QHP PCIe PHY
  ANDROID: phy: qcom: qmp: Add SDM845 PCIe QMP PHY support
  ANDROID: phy: qcom: qmp: Use power_on/off ops for PCIe
  ANDROID: phy: qcom-qmp: Increase PHY ready timeout
  msm: ipa3: Fix to ignore frag status packet in lan consumer pipe
  cpufreq: qcom-cpufreq-hw: Fix incorrect type warning from sparse
  arm64: defconfig: Enable SPS driver for Lahaina
  ASoC: compress: propagate the error code from the compress framework
  ASoC: msm: Update the encode option and sample rate
  Asoc: Add audio backend to hwdep interface
  ALSA: pcm: fix blocking while loop in snd_pcm_update_hw_ptr0()
  ASoC: Compress: Check and set pcm_new driver op
  ASoC: dapm: Avoid static route b/w cpu and codec dai
  scsi: ufs-qcom: Add reset control support for host controller
  scsi: ufs-qcom: Add ioctl interface for ufs query requests
  BACKPORT: FROMLIST: scsi: ufs: Export query request interfaces
  ALSA: compress: Add support to send codec specific data
  scsi: ufs-qti: Fix overwriting model name
  ASoC: msm: qdsp6v2: Cleanup of compress offload drivers
  ALSA: PCM: User control API implementation
  ALSA: PCM: volume API implementation
  ALSA: core: Handle user defined ioctls
  coresight: tmc: Fix mem_lock dead lock
  cpufreq: record CPUFREQ stat for fast switch path
  cpufreq: Add snapshot of qcom-cpufreq driver
  arm64: defconfig: Enable debug features on Lahaina
  coresight: ost: correct the kconfig dependency
  Bluetooth: Re-initialize regulator to NULL on error
  ANDROID: gki_defconfig: Enable CONFIG_GNSS_CMDLINE_SERIAL
  ANDROID: gnss: Add command line test driver
  ANDROID: serdev: add platform device support
  ANDROID: usb: gadget: Add configfs attribuite for controling match_existing_only
  net: cnss2: Remove unsupported symbol references
  ANDROID: gki_defconfig: enable ARM64_SW_TTBR0_PAN
  ANDROID: gki_defconfig: Set BINFMT_MISC as =m
  arm64: defconfig: Enable EDAC driver support for QCOM SoCs
  msm: sps: Fix build warnings
  msm: ipa3: Fix to avoid memory out of bound access error
  wil6210: reduce ucode_debug memory region
  wil6210: enable access category queues
  wil6210: allow sending special packets when tx ring is full
  wil6210: Support ndo_select_queue in net_device_ops
  wil6210: add verification for cid upper bound
  wil6210: take mem_lock for writing in crash dump collection
  wil6210: minimize the time that mem_lock is held
  wil6210: enable AP/PCP power save
  soc: mem_dump: fix physical address mapping issue
  soc: mem_dump: Add support for CPU subsystem register dump
  soc: qcom: Update the dump table region size in imem
  soc: qcom: Unify the memory dump entries registration
  arm64: defconfig: Enable minidump driver on Lahaina GKI
  soc: qcom: Add snapshot of minidump
  FROMLIST: ARM: Remove arm_pm_restart()
  FROMLIST: ARM64: Remove arm_pm_restart()
  FROMLIST: ARM: Register with kernel restart handler
  FROMLIST: drivers: firmware: psci: Register with kernel restart handler
  FROMLIST: ARM: xen: Register with kernel restart handler
  FROMLIST: ARM: prima2: Register with kernel restart handler
  shmbridge: get bridge mem pool's DMA address with dma_map_single
  firmware: qcom_scm: Add calls to support poweroff driver
  firmware: qcom_scm: Expose qcom_scm_set_download_mode
  arm64: defconfig: Enable WALT for Lahaina
  sched: Improve the scheduler
  hwrng: Add QRNG driver snapshot for kona
  msm: sps: Add SPS driver snapshot
  ANDROID: ASoC: add hikey960-i2s DT bindings
  ANDROID: sound: Add hikey960 i2s audio driver
  ANDROID: HACK: adv7511: Add poweron delay to allow for EDID probing to work
  ANDROID: drm: kirin: Fix Makefile to correct for module builds
  ANDROID: drm: kirin960: Remove one mode-line that seems to be causing trouble
  ANDROID: drm: kirin: remove wait for VACTIVE IRQ
  ANDROID: drm: kirin: Add kirin960 dpe driver support
  ANDROID: drm: kirin: Introduce kirin960
  ANDROID: arm64: dts: hi3660: Add support for usb on Hikey960
  ANDROID: arm64: dts: hikey960: Fix bootwarning on mapping reboot reason syscon
  ANDROID: arm64: dts: hi3660: adb reboot node
  ANDROID: arm64: dts: hi3660: enable gpu
  ANDROID: arm64: dts: hi3660-hikey960: Add i2s & sound device
  ANDROID: arm64: dts: hi3660: add display driver dts
  ANDROID: arm64: dts: hikey960: Add CMA entry for ION/framebuffers
  ANDROID: mm/memory.c: export mm_trace_rss_stat
  ANDROID: update ABI for 5.4.5
  Linux 5.4.5
  r8169: add missing RX enabling for WoL on RTL8125
  net: mscc: ocelot: unregister the PTP clock on deinit
  ionic: keep users rss hash across lif reset
  xdp: obtain the mem_id mutex before trying to remove an entry.
  page_pool: do not release pool until inflight == 0.
  net/mlx5e: ethtool, Fix analysis of speed setting
  net/mlx5e: Fix translation of link mode into speed
  net/mlx5e: Fix freeing flow with kfree() and not kvfree()
  net/mlx5e: Fix SFF 8472 eeprom length
  act_ct: support asymmetric conntrack
  net/mlx5e: Fix TXQ indices to be sequential
  net: Fixed updating of ethertype in skb_mpls_push()
  hsr: fix a NULL pointer dereference in hsr_dev_xmit()
  Fixed updating of ethertype in function skb_mpls_pop
  gre: refetch erspan header from skb->data after pskb_may_pull()
  cls_flower: Fix the behavior using port ranges with hw-offload
  net: sched: allow indirect blocks to bind to clsact in TC
  net: core: rename indirect block ingress cb function
  tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE()
  tcp: tighten acceptance of ACKs not matching a child socket
  tcp: fix rejected syncookies due to stale timestamps
  net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup
  net: ipv6: add net argument to ip6_dst_lookup_flow
  net/mlx5e: Query global pause state before setting prio2buffer
  tipc: fix ordering of tipc module init and exit routine
  tcp: md5: fix potential overestimation of TCP option space
  openvswitch: support asymmetric conntrack
  net/tls: Fix return values to avoid ENOTSUPP
  net: thunderx: start phy before starting autonegotiation
  net_sched: validate TCA_KIND attribute in tc_chain_tmplt_add()
  net: sched: fix dump qlen for sch_mq/sch_mqprio with NOLOCK subqueues
  net: ethernet: ti: cpsw: fix extra rx interrupt
  net: dsa: fix flow dissection on Tx path
  net: bridge: deny dev_set_mac_address() when unregistering
  mqprio: Fix out-of-bounds access in mqprio_dump
  inet: protect against too small mtu values.
  ANDROID: add initial ABI whitelist for android-5.4
  wil6210: dump Rx status message on errors
  arm64: config: Enable socinfo driver for QCOM SoCs
  coresight: Add snapshot of jtagv8 driver
  defconfig: lahaina-gki: enable ufs 7nm phy for lahaina
  phy: qcom-ufs: add 7nm UFS QMP PHY support on Lahaina
  phy: qcom-ufs: add UFS HS-G4 support
  phy: qcom-ufs: move PHY configurations after vregs and clocks are enabled
  phy: qcom-ufs: don't error out if vddp-ref-clk-supply is absent
  phy: qcom-ufs: make ref_clk as optional
  phy: qcom-ufs: separate out 2 lanes configuration
  phy: qcom-ufs: set no runtime PM callbacks flag
  phy: qcom-ufs: parse ref-clk details prior to resource request
  phy: qcom-ufs: remove warnings for optional clocks
  phy: qcom-ufs: add optional ref aux clk
  phy: qcom-ufs: don't probe for "dev_ref_clk_ctrl_mem"
  phy: qcom-ufs: remove failure when rx/tx_iface_clk are absent
  defconfig: Initial genericarmv8 defconfig
  mm: oom_kill: dump info of all tasks when the FG process is killed
  iommu/arm-smmu: restrict secure vmid update while attached
  iommu/arm-smmu: reduce tlb sync poll retry latency
  interconnect: qcom:  Build icc-rpmh with qnoc-lahaina
  kbuild: Disable the gcc-wrapper with an environment variable
  PM / devfreq: icc: add support for L3 voting
  PM / devfreq: memlat: add support for shared core-dev tables
  sched: Support Energy Aware Scheduling irrespective of governor
  sched: Add schedutil snapshot
  PM / devfreq: memlat: simplify core-dev table parsing logic
  ANDROID: abi update for 5.4.4
  ANDROID: mm: Throttle rss_stat tracepoint
  FROMLIST: vsprintf: Inline call to ptr_to_hashval
  UPSTREAM: rss_stat: Add support to detect RSS updates of external mm
  UPSTREAM: mm: emit tracepoint when RSS changes
  defconfig: Enable QCOM_RUN_QUEUE_STATS
  time: Add rq_stats snapshot
  Linux 5.4.4
  EDAC/ghes: Do not warn when incrementing refcount on 0
  r8169: fix rtl_hw_jumbo_disable for RTL8168evl
  workqueue: Fix missing kfree(rescuer) in destroy_workqueue()
  blk-mq: make sure that line break can be printed
  ext4: fix leak of quota reservations
  ext4: fix a bug in ext4_wait_for_tail_page_commit
  splice: only read in as much information as there is pipe buffer space
  rtc: disable uie before setting time and enable after
  USB: dummy-hcd: increase max number of devices to 32
  powerpc: Define arch_is_kernel_initmem_freed() for lockdep
  mm/shmem.c: cast the type of unmap_start to u64
  s390/kaslr: store KASLR offset for early dumps
  s390/smp,vdso: fix ASCE handling
  firmware: qcom: scm: Ensure 'a0' status code is treated as signed
  ext4: work around deleting a file with i_nlink == 0 safely
  mm: memcg/slab: wait for !root kmem_cache refcnt killing on root kmem_cache destruction
  mfd: rk808: Fix RK818 ID template
  mm, memfd: fix COW issue on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings
  powerpc: Fix vDSO clock_getres()
  powerpc: Avoid clang warnings around setjmp and longjmp
  omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251
  omap: pdata-quirks: revert pandora specific gpiod additions
  iio: ad7949: fix channels mixups
  iio: ad7949: kill pointless "readback"-handling code
  Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails"
  scsi: qla2xxx: Fix a dma_pool_free() call
  scsi: qla2xxx: Fix SRB leak on switch command timeout
  reiserfs: fix extended attributes on the root directory
  ext4: Fix credit estimate for final inode freeing
  quota: fix livelock in dquot_writeback_dquots
  seccomp: avoid overflow in implicit constant conversion
  ext2: check err when partial != NULL
  quota: Check that quota is not dirty before release
  video/hdmi: Fix AVI bar unpack
  powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts
  powerpc: Allow flush_icache_range to work across ranges >4GB
  powerpc/xive: Prevent page fault issues in the machine crash handler
  powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB
  coresight: Serialize enabling/disabling a link device.
  stm class: Lose the protocol driver when dropping its reference
  ppdev: fix PPGETTIME/PPSETTIME ioctls
  RDMA/core: Fix ib_dma_max_seg_size()
  ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity
  mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of pandora_wl1251_init_card
  pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup controller init
  pinctrl: samsung: Fix device node refcount leaks in init code
  pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup controller init
  pinctrl: samsung: Fix device node refcount leaks in Exynos wakeup controller init
  pinctrl: samsung: Add of_node_put() before return in error path
  pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type()
  pinctrl: rza2: Fix gpio name typos
  ACPI: PM: Avoid attaching ACPI PM domain to certain devices
  ACPI: EC: Rework flushing of pending work
  ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data()
  ACPI: OSL: only free map once in osl.c
  ACPI / hotplug / PCI: Allocate resources directly under the non-hotplug bridge
  ACPI: LPSS: Add dmi quirk for skipping _DEP check for some device-links
  ACPI: LPSS: Add LNXVIDEO -> BYT I2C1 to lpss_device_links
  ACPI: LPSS: Add LNXVIDEO -> BYT I2C7 to lpss_device_links
  ACPI / utils: Move acpi_dev_get_first_match_dev() under CONFIG_ACPI
  ALSA: hda/realtek - Line-out jack doesn't work on a Dell AIO
  ALSA: oxfw: fix return value in error path of isochronous resources reservation
  ALSA: fireface: fix return value in error path of isochronous resources reservation
  cpufreq: powernv: fix stack bloat and hard limit on number of CPUs
  PM / devfreq: Lock devfreq in trans_stat_show
  intel_th: pci: Add Tiger Lake CPU support
  intel_th: pci: Add Ice Lake CPU support
  intel_th: Fix a double put_device() in error path
  powerpc/perf: Disable trace_imc pmu
  drm/panfrost: Open/close the perfcnt BO
  perf tests: Fix out of bounds memory access
  erofs: zero out when listxattr is called with no xattr
  cpuidle: use first valid target residency as poll time
  cpuidle: teo: Fix "early hits" handling for disabled idle states
  cpuidle: teo: Consider hits and misses metrics of disabled states
  cpuidle: teo: Rename local variable in teo_select()
  cpuidle: teo: Ignore disabled idle states that are too deep
  cpuidle: Do not unset the driver if it is there already
  media: cec.h: CEC_OP_REC_FLAG_ values were swapped
  media: radio: wl1273: fix interrupt masking on release
  media: bdisp: fix memleak on release
  media: vimc: sen: remove unused kthread_sen field
  media: hantro: Fix picture order count table enable
  media: hantro: Fix motion vectors usage condition
  media: hantro: Fix s_fmt for dynamic resolution changes
  s390/mm: properly clear _PAGE_NOEXEC bit when it is not supported
  ar5523: check NULL before memcpy() in ar5523_cmd()
  wil6210: check len before memcpy() calls
  cgroup: pids: use atomic64_t for pids->limit
  blk-mq: avoid sysfs buffer overflow with too many CPU cores
  md: improve handling of bio with REQ_PREFLUSH in md_flush_request()
  ASoC: fsl_audmix: Add spin lock to protect tdms
  ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report
  ASoC: rt5645: Fixed typo for buddy jack support.
  ASoC: rt5645: Fixed buddy jack support.
  workqueue: Fix pwq ref leak in rescuer_thread()
  workqueue: Fix spurious sanity check failures in destroy_workqueue()
  dm zoned: reduce overhead of backing device checks
  dm writecache: handle REQ_FUA
  hwrng: omap - Fix RNG wait loop timeout
  ovl: relax WARN_ON() on rename to self
  ovl: fix corner case of non-unique st_dev;st_ino
  ovl: fix lookup failure on multi lower squashfs
  lib: raid6: fix awk build warnings
  rtlwifi: rtl8192de: Fix missing enable interrupt flag
  rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer
  rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address
  btrfs: record all roots for rename exchange on a subvol
  Btrfs: send, skip backreference walking for extents with many references
  btrfs: Remove btrfs_bio::flags member
  btrfs: Avoid getting stuck during cyclic writebacks
  Btrfs: fix negative subv_writers counter and data space leak after buffered write
  Btrfs: fix metadata space leak on fixup worker failure to set range as delalloc
  btrfs: use refcount_inc_not_zero in kill_all_nodes
  btrfs: use btrfs_block_group_cache_done in update_block_group
  btrfs: check page->mapping when loading free space cache
  iwlwifi: pcie: fix support for transmitting SKBs with fraglist
  usb: typec: fix use after free in typec_register_port()
  phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role"
  usb: dwc3: ep0: Clear started flag on completion
  usb: dwc3: gadget: Clear started flag for non-IOC
  usb: dwc3: gadget: Fix logical condition
  usb: dwc3: pci: add ID for the Intel Comet Lake -H variant
  virtio-balloon: fix managed page counts when migrating pages between zones
  virt_wifi: fix use-after-free in virt_wifi_newlink()
  mtd: rawnand: Change calculating of position page containing BBM
  mtd: spear_smi: Fix Write Burst mode
  brcmfmac: disable PCIe interrupts before bus reset
  EDAC/altera: Use fast register IO for S10 IRQs
  tpm: Switch to platform_get_irq_optional()
  tpm: add check after commands attribs tab allocation
  usb: mon: Fix a deadlock in usbmon between mmap and read
  usb: core: urb: fix URB structure initialization function
  USB: adutux: fix interface sanity check
  usb: roles: fix a potential use after free
  USB: serial: io_edgeport: fix epic endpoint lookup
  USB: idmouse: fix interface sanity checks
  USB: atm: ueagle-atm: add missing endpoint check
  iio: adc: ad7124: Enable internal reference
  iio: adc: ad7606: fix reading unnecessary data from device
  iio: imu: inv_mpu6050: fix temperature reporting using bad unit
  iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting
  iio: adis16480: Fix scales factors
  iio: imu: st_lsm6dsx: fix ODR check in st_lsm6dsx_write_raw
  iio: adis16480: Add debugfs_reg_access entry
  ARM: dts: pandora-common: define wl1251 as child node of mmc3
  usb: common: usb-conn-gpio: Don't log an error on probe deferral
  interconnect: qcom: qcs404: Walk the list safely on node removal
  interconnect: qcom: sdm845: Walk the list safely on node removal
  xhci: make sure interrupts are restored to correct state
  xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default behaviour.
  xhci: Increase STS_HALT timeout in xhci_suspend()
  xhci: fix USB3 device initiated resume race with roothub autosuspend
  xhci: Fix memory leak in xhci_add_in_port()
  usb: xhci: only set D3hot for pci device
  staging: gigaset: add endpoint-type sanity check
  staging: gigaset: fix illegal free on probe errors
  staging: gigaset: fix general protection fault on probe
  staging: vchiq: call unregister_chrdev_region() when driver registration fails
  staging: rtl8712: fix interface sanity check
  staging: rtl8188eu: fix interface sanity check
  staging: exfat: fix multiple definition error of `rename_file'
  binder: fix incorrect calculation for num_valid
  usb: host: xhci-tegra: Correct phy enable sequence
  usb: Allow USB device to be warm reset in suspended state
  USB: documentation: flags on usb-storage versus UAS
  USB: uas: heed CAPACITY_HEURISTICS
  USB: uas: honor flag to avoid CAPACITY16
  media: venus: remove invalid compat_ioctl32 handler
  ceph: fix compat_ioctl for ceph_dir_operations
  compat_ioctl: add compat_ptr_ioctl()
  scsi: qla2xxx: Fix memory leak when sending I/O fails
  scsi: qla2xxx: Fix double scsi_done for abort path
  scsi: qla2xxx: Fix driver unload hang
  scsi: qla2xxx: Do command completion on abort timeout
  scsi: zfcp: trace channel log even for FCP command responses
  scsi: lpfc: Fix bad ndlp ptr in xri aborted handling
  Revert "nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T"
  nvme: Namepace identification descriptor list is optional
  usb: gadget: pch_udc: fix use after free
  usb: gadget: configfs: Fix missing spin_lock_init()
  mm: vmstat: add pageoutclean
  drivers: thermal: qmi_cooling: Add snapshot of QMI cooling device driver
  drivers: thermal: Add a snapshot of bcl soc driver
  drivers: thermal: bcl_pmic5: Add snapshot of bcl driver
  drivers: thermal: qmi_sensor: Add snapshot of qmi sensor driver
  drivers: thermal: cpu_isolate: Add a snapshot of cpu isolate
  msm: cvp: Fence path for Lahaina
  cpufreq: qcom-hw: cleanup the driver for HW driver
  coresight: stm: STM master side access control
  scsi: ufs-qti: port UFS driver changes for QTI configuration
  socinfo: add socinfo driver
  uio: Kconfig: Enable msm shared memory driver
  defconfig: lahaina: enable PCIe root complex and PCIe MSI for lahaina
  msm: pcie: remove deprecated explicit clock retention support
  msm: pcie: add lahaina PCI device ID to PCI table
  msm: pcie: update deprecated wakeup_source_* API
  msm: pcie: add snapshot of PCIe root complex bus driver
  usb: xhci: Add helper API to issue stop endpoint command
  usb: xhci: Add helper APIs to return xhci dma addresses
  usb: xhci: Add support for secondary interrupters
  defconfig: enable cdsp loader on Lahaina as DLKM module
  defconfig: lahaina: enable the UCSI Glink driver
  usb: typec: ucsi: add QTI UCSI Glink driver
  sched/walt: Improve the scheduler
  sched/walt: Improve the scheduler
  sched/fair: Avoid force newly idle load balance if have iowait task
  sched/fair: Improve the scheduler
  sched/fair: Force gold cpus to do idle lb when silver has big tasks
  defconfig: enable fastrpc driver on Lahaina
  BACKPORT: FROMLIST: scsi: ufs: Export query request interfaces
  defconfig: lahaina-gki: enable qpnp-power-on driver
  input: qpnp-power-on: add support for PON_GEN3 subtype PON peripherals
  dt-bindings: input: add qpnp-power-on bindings
  input: add snapshot of qpnp-power-on driver
  defconfig: lahaina-qgki: enable regmap debugfs features
  defconfig: lahaina-gki: enable gpio-keys driver
  defconfig: lahaina-gki: enable SPMI and PMIC drivers
  defconfig: lahaina-qgki: enable CONFIG_IIO
  pinctrl: qcom: spmi-gpio: define an irqchip for each pinctrl device
  pinctrl: qcom: spmi-gpio: add support for PMR735A and PMR735B PMIC variants
  pinctrl: Add wakeup gpio register and bit information
  msm: ipa: load IPA FW after smmu CB are probed
  iio: adc: Add support for PMIC7 VADC
  dt-bindings: iio: Add PMIC7 ADC support
  soc: qcom: reserve memory in memory dump probe
  slimbus: Add snapshot of slimbus driver
  msm: ipa4: Allocate coalescing close frame command payload
  coresight: enable stm logging for trace events, marker and printk
  arm64: defconfig: Enable QUPv3 and GPI drivers on lahaina
  coresight-tmc: Re-use ETR buffer across use cases
  coresight-tmc: add support to configure flush and reset CTIs
  coresight: Add snapshot of Coresight cti driver
  coresight: Add regulator and clock vote for coresight components
  msm: ipa: add support to updated wdi3 scratch register2 alone
  msm: ipa: Fix not sending QMI sync indication
  msm: ipa: Add graceful handling to skip partial packets
  msm: ipa: Fix not to update state during pipe reset
  msm: ipa: Update IPA register offsets and fields
  wil6210: fix iommu_unmap in IPA mode
  wil6210: new NL command to get driver capabilities
  wil6210: use wigig.ini as a configuration file
  wil6210: extend bus voting support for wider bandwidth
  wil6210: ipa stop/wake queue based on outstanding packets
  wil6210: add support for spi slave reset
  wil6210: update the disconnect sequence for the IPA disconnect
  wil6210: support VR profiles
  wil6210: add support for sensing over SPI
  wil6210: support IPA offload
  wil6210: support multiple desc and status rings handling
  wil6210: support NL_60G_GEN_FW_RESET UNSPEC vendor command
  wil6210: add support for pci linkdown recovery
  wil6210: add support for headroom configuration
  arm64: defconfig: Enable spcom driver on Lahaina
  cpufreq: qcom: Update cycle counter logic for CPUFREQ HW
  cpufreq: qcom-cpufreq-hw: Initialize the spinlock before usage
  cpufreq: qcom-hw: Add register offsets for non-epss devices
  cpufreq: qcom-hw: Update freq_scale from fast_switch path
  cpufreq: qcom-hw: Add support for EPSS CPUFREQ firmware
  net: cnss2: Update CNSS2 driver
  ANDROID: update abi with unbindable_ports sysctl
  BACKPORT: FROMLIST: net: introduce ip_local_unbindable_ports sysctl
  ANDROID: update abi for 5.4.3 merge
  ANDROID: update abi_gki_aarch64.xml for ion, drm changes
  ANDROID: drivers: gpu: drm: export drm_mode_convert_umode symbol
  ANDROID: ion: flush cache before exporting non-cached buffers
  Linux 5.4.3
  kselftest: Fix NULL INSTALL_PATH for TARGETS runlist
  perf script: Fix invalid LBR/binary mismatch error
  EDAC/ghes: Fix locking and memory barrier issues
  watchdog: aspeed: Fix clock behaviour for ast2600
  drm/mcde: Fix an error handling path in 'mcde_probe()'
  md/raid0: Fix an error message in raid0_make_request()
  cpufreq: imx-cpufreq-dt: Correct i.MX8MN's default speed grade value
  ALSA: hda - Fix pending unsol events at shutdown
  KVM: x86: fix out-of-bounds write in KVM_GET_EMULATED_CPUID (CVE-2019-19332)
  binder: Handle start==NULL in binder_update_page_range()
  binder: Prevent repeated use of ->mmap() via NULL mapping
  binder: Fix race between mmap() and binder_alloc_print_pages()
  Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices"
  vcs: prevent write access to vcsu devices
  thermal: Fix deadlock in thermal thermal_zone_device_check
  iomap: Fix pipe page leakage during splicing
  bdev: Refresh bdev size for disks without partitioning
  bdev: Factor out bdev revalidation into a common helper
  rfkill: allocate static minor
  RDMA/qib: Validate ->show()/store() callbacks before calling them
  can: ucan: fix non-atomic allocation in completion handler
  spi: Fix NULL pointer when setting SPI_CS_HIGH for GPIO CS
  spi: Fix SPI_CS_HIGH setting when using native and GPIO CS
  spi: atmel: Fix CS high support
  spi: stm32-qspi: Fix kernel oops when unbinding driver
  spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register
  crypto: user - fix memory leak in crypto_reportstat
  crypto: user - fix memory leak in crypto_report
  crypto: ecdh - fix big endian bug in ECC library
  crypto: ccp - fix uninitialized list head
  crypto: geode-aes - switch to skcipher for cbc(aes) fallback
  crypto: af_alg - cast ki_complete ternary op to int
  crypto: atmel-aes - Fix IV handling when req->nbytes < ivsize
  crypto: crypto4xx - fix double-free in crypto4xx_destroy_sdr
  KVM: x86: Grab KVM's srcu lock when setting nested state
  KVM: x86: Remove a spurious export of a static function
  KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES
  KVM: x86: do not modify masked bits of shared MSRs
  KVM: arm/arm64: vgic: Don't rely on the wrong pending table
  KVM: nVMX: Always write vmcs02.GUEST_CR3 during nested VM-Enter
  KVM: PPC: Book3S HV: XIVE: Set kvm->arch.xive when VPs are allocated
  KVM: PPC: Book3S HV: XIVE: Fix potential page leak on error path
  KVM: PPC: Book3S HV: XIVE: Free previous EQ page when setting up a new one
  arm64: dts: exynos: Revert "Remove unneeded address space mapping for soc node"
  arm64: Validate tagged addresses in access_ok() called from kernel threads
  drm/i810: Prevent underflow in ioctl
  drm: damage_helper: Fix race checking plane->state->fb
  drm/msm: fix memleak on release
  jbd2: Fix possible overflow in jbd2_log_space_left()
  kernfs: fix ino wrap-around detection
  nfsd: restore NFSv3 ACL support
  nfsd: Ensure CLONE persists data and metadata changes to the target file
  can: slcan: Fix use-after-free Read in slcan_open
  tty: vt: keyboard: reject invalid keycodes
  CIFS: Fix SMB2 oplock break processing
  CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks
  x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect
  x86/mm/32: Sync only to VMALLOC_END in vmalloc_sync_all()
  media: rc: mark input device as pointing stick
  Input: Fix memory leak in psxpad_spi_probe
  coresight: etm4x: Fix input validation for sysfs.
  Input: goodix - add upside-down quirk for Teclast X89 tablet
  Input: synaptics-rmi4 - don't increment rmiaddr for SMBus transfers
  Input: synaptics-rmi4 - re-enable IRQs in f34v7_do_reflash
  Input: synaptics - switch another X1 Carbon 6 to RMI/SMbus
  soc: mediatek: cmdq: fixup wrong input order of write api
  ALSA: hda: Modify stream stripe mask only when needed
  ALSA: hda - Add mute led support for HP ProBook 645 G4
  ALSA: pcm: oss: Avoid potential buffer overflows
  ALSA: hda/realtek - Fix inverted bass GPIO pin on Acer 8951G
  ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236
  ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop
  ALSA: hda/realtek - Enable internal speaker of ASUS UX431FLC
  SUNRPC: Avoid RPC delays when exiting suspend
  io_uring: ensure req->submit is copied when req is deferred
  io_uring: fix missing kmap() declaration on powerpc
  fuse: verify attributes
  fuse: verify write return
  fuse: verify nlink
  fuse: fix leak of fuse_io_priv
  io_uring: transform send/recvmsg() -ERESTARTSYS to -EINTR
  io_uring: fix dead-hung for non-iter fixed rw
  mwifiex: Re-work support for SDIO HW reset
  serial: ifx6x60: add missed pm_runtime_disable
  serial: 8250_dw: Avoid double error messaging when IRQ absent
  serial: stm32: fix clearing interrupt error flags
  serial: serial_core: Perform NULL checks for break_ctl ops
  serial: pl011: Fix DMA ->flush_buffer()
  tty: serial: msm_serial: Fix flow control
  tty: serial: fsl_lpuart: use the sg count from dma_map_sg
  serial: 8250-mtk: Use platform_get_irq_optional() for optional irq
  usb: gadget: u_serial: add missing port entry locking
  staging/octeon: Use stubs for MIPS && !CAVIUM_OCTEON_SOC
  mailbox: tegra: Fix superfluous IRQ error message
  time: Zero the upper 32-bits in __kernel_timespec on 32-bit
  lp: fix sparc64 LPSETTIMEOUT ioctl
  sparc64: implement ioremap_uc
  perf scripts python: exported-sql-viewer.py: Fix use of TRUE with SQLite
  arm64: tegra: Fix 'active-low' warning for Jetson Xavier regulator
  arm64: tegra: Fix 'active-low' warning for Jetson TX1 regulator
  rsi: release skb if rsi_prepare_beacon fails
  phy: phy-qcom-ufs: add receive line configuration
  ufs: qcom: port from msm-4.19
  scsi: ufs-qcom: Clock scaling code restructure
  defconfig: lahaina-gki: Enable USB Electrical and Link test support
  clk: dt-bindings: Define clock IDs supported by bolero codec
  FROMLIST: scsi: ufs: Fix ufshcd_hold() caused scheduling while atomic
  FROMLIST: scsi: ufs: Add dev ref clock gating wait time support
  FROMLIST: scsi: ufs-qcom: Adjust bus bandwidth voting and unvoting
  FROMLIST: scsi: ufs: Remove the check before call setup clock notify vops
  FROMLIST: scsi: ufs: set load before setting voltage in regulators
  FROMLIST: scsi: ufs: Flush exception event before suspend
  FROMLIST: scsi: ufs: Do not rely on prefetched data
  FROMLIST: scsi: ufs: Fix up clock scaling
  FROMGIT: scsi: ufs: Do not free irq in suspend
  FROMGIT: scsi: ufs: Do not clear the DL layer timers
  FROMGIT: scsi: ufs: Release clock if DMA map fails
  FROMGIT: scsi: ufs: Use DBD setting in mode sense
  FROMGIT: scsi: core: Adjust DBD setting in MODE SENSE for caching mode page per LLD
  FROMGIT: scsi: ufs: Complete pending requests in host reset and restore path
  FROMGIT: scsi: ufs: Avoid messing up the compl_time_stamp of lrbs
  FROMGIT: scsi: ufs: Update VCCQ2 and VCCQ min/max voltage hard codes
  FROMGIT: scsi: ufs: Recheck bkops level if bkops is disabled
  drivers: thermal: of-thermal: Add support for virtual sensor
  drivers: thermal: of-thermal: Add a snapshot of of-thermal
  drivers: thermal: Add QTI_THERMAL config
  clk: qcom: Fix orphaned sleep clocks for Lahaina
  arm64: defconfig: Remove IKHEADERS option
  drivers: thermal: cpu_cooling: Use Policy cpu as cdev ID
  thermal: Include qcom thermal drivers for CONFIG_ARCH_QCOM
  arm64: Remove cpu_soft_reset() prototype
  uapi: Fix QCOM headers to work with UAPI_HEADER_TEST
  Revert "perf: Set the DSU PMU to be readable from any CPU"
  msm: kgsl: Check the return value of sysfs functions
  dma-mapping-fast: Clean up common code
  dma-mapping-fast: Add support for DMA_ATTR_FORCE_CONTIGUOUS
  dma-mapping-fast: Do not clobber existing atomic pool
  dma-mapping-fast: Reorganize common behavior
  drivers: soc: qcom: Add snapshot of EUD driver
  msm: adsprpc: Remove IPC logging from fastrpc driver
  ANDROID: update abi_gki_aarch64.xml for LTO, CFI, and SCS
  ANDROID: gki_defconfig: enable LTO, CFI, and SCS
  wil6210: fix for "runtime PM when interface is down"
  wil6210: support FCC board file
  wil6210: force EDMG channel through debugfs
  wil6210: publish/receive WMI events/commands through nl
  wil6210: BRP antenna limit API
  wil6210: support configurable board file via sysfs
  wil6210: use country specific board file upon reg domain change
  wil6210: allow flashless boot when OTP is empty
  wil6210: drop RX probe reponses with low SNR
  wil6210: add sysfs for setting connect SNR threshold
  wil6210: support AOA in FTM session
  wil6210: potential buffer overflow in wmi_evt_aoa_meas
  wil6210: send uevent when creating sysfs files
  wil6210: add option to ignore OTA regulatory hints
  wil6210: add sysfs file for enable/disable fst link loss
  wil6210: add sysfs for thermal throttling configuration
  coresight: ost: Add snapshot of Coresight OST driver
  soc: qcom: subsys_notif: Add early SSR notifications for PCIe DRV
  ANDROID: update abi_gki_aarch64.xml for CONFIG_GNSS
  ANDROID: cuttlefish_defconfig: Enable CONFIG_GNSS
  rtc: rtc-pm8xxx: add support for PMK8350 RTC
  ANDROID: gki_defconfig: enable HID configs
  defconfig: lahaina-gki: Enable QTI Tri-LED driver
  arm64: defconfig: Enable tz_log driver for Lahaina
  firmware: qcom: Add TZ log driver snapshot for Lahaina
  Revert "soc: qcom: socinfo: Expose custom attributes"
  UPSTREAM: arm64: Validate tagged addresses in access_ok() called from kernel threads
  soc: qcom: spcom: add spcom as DLKM for GKI
  cpufreq: qcom-hw: use no_log when reading cpu counter val
  cpufreq: qcom-hw: Register child devices
  cpufreq: qcom-hw: Add ready callback to register CPU cooling device
  cpufreq: qcom-hw: add cycle counter support
  cpufreq: qcom-hw: remove check for hw enable during probe
  cpufreq: qcom-hw: Set dvfs_possible_from_any_cpu cpufreq driver flag
  cpufreq: qcom-hw: Notify the current frequency to the topology driver
  cpufreq: qcom-hw: register with Energy Model framework
  cpufreq: qcom: Read voltage LUT and populate OPP
  cpufreq: qcom-hw: use pre-defined core count for max cores
  cpufreq: qcom: Add snapshot of cpufreq-hw
  usb: host: xhci: Replace msleep with usleep_range
  usb: host: xhci: Change L1 timeout default to 128us
  usb: xhci: Add support for SINGLE_STEP_SET_FEATURE test of EHSET
  host: xhci-plat: Enable autosuspend functionality with root hub
  usb: core: Enable xhci irq after starting controller
  usb: xhci-plat: Remove system PM call backs
  xhci-plat: Use USB glue driver device as sysdev
  arm64: defconfig: Enable EPSS L3 Interconnect driver for Lahaina
  arm64: defconfig: Enable QCOM clock debug features
  firmware: qcom_scm: Export invoke callback response API
  firmware: qcom_scm: Move qseecom specific workarounds
  sched/fair: Improve the scheduler
  sched/fair: Improve the scheduler
  FROMLIST: sched/fair: Use wake_q length as a hint for wake_wide
  sched/fair: Improve the scheduler
  sched: use the CPU true capacity while sorting the min/mid/max CPUs
  cpuset: Restore tasks affinity while moving across cpusets
  PM / EM: Micro optimization in em_pd_energy
  sched: trace : Print current sched domain overutilization status
  ANDROID: sched/fair: Reduce balance interval to 1 jiffy if we have a misfit task
  ANDROID: trace/sched: Add tracepoint for sched_overutilized events
  ANDROID: sched: Per-Sched-domain over utilization
  sched: Add snapshot of task boost feature
  watchdog: use per_cpu_ptr() in watchdog_disable()
  Revert "softirq: Let ksoftirqd do its job"
  Revert "Mark HI and TASKLET softirq synchronous"
  genirq: Honour IRQ's affinity hint during migration
  softirq: Don't defer all softirq during RT task
  sched/cpupri: Exclude isolated CPUs from the lowest_mask
  softirq: defer softirq processing to ksoftirqd if CPU is busy with RT
  sched: avoid migrating when softint on tgt cpu should be short
  sched: avoid scheduling RT threads on cores currently handling softirqs
  sched/rt: Add snapshot of changes to RT class
  sched/fair: Add snapshot of load-balancing changes
  sched/fair: Add snapshot of placement changes
  sched: Add snapshot of preemption and IRQs disable callers
  sched: Add snapshot of sched_{up,down}migrate knobs
  kernel: Add snapshot of changes to support cpu isolation
  sched: Add sched_enq_deq_task trace point
  sched: Add snapshot of Window Assisted Load Tracking (WALT)
  interconnect: qcom: Prevent duplicate BCMs being added to commit list
  scripts: Makefile: Remove flags which are not support by EXT_DTC
  scripts: Makefile: add support to use external DTC
  scripts: Makefile: Add multi overlay dtbo-base apply verify
  scripts: Makefile: Change output overlay from .dtb to .tmp
  scripts: Makefile: add support to compile DT overlay blobs
  leds: Add snapshot of QTI Tri-LED driver
  soc: qcom: add secure processor communication (spcom) driver
  msm: kgsl: Remove legacy support for clock_set_flags
  msm: kgsl: Remove enhanced memory accounting
  msm: kgsl: Add an option to always enable I/O coherency
  msm: kgsl: bus dcvs fixes
  msm: kgsl: Generate TCS votes to send to the GMU
  msm: kgsl: Use bulk clock functions for GMU
  msm: kgsl: Modernize bus scaling
  msm: kgsl: Dynamically create an OPP table at runtime
  msm: kgsl: Move voltage levels to the GPU specific powerlevels
  msm: kgsl: Bring in the GPU bandwidth governor
  msm: kgsl: Fixup kernel API changes
  msm: kgsl: Bring in the GPU frequency governor
  msm: kgsl: Remove "zero" power level
  msm: kgsl: Move the system PM operations to adreno
  msm: kgsl: Re-export the UAPI header
  arm64: defconfig: Enable spss_utils driver on Lahaina
  coresight: funnel: add support for multiple output ports
  coresight: Kconfig: Add CORESIGHT_QGKI configuration
  ANDROID: kbuild: limit LTO inlining
  ANDROID: kbuild: merge module sections with LTO
  msm: adsprpc: Updating dependencies for fastrpc driver
  arm64: defconfig: Enable printing unhashed pointers on Lahaina
  arm64: defconfig: Enable devfreq drivers on Lahaina
  usb: gadget: f_fs: Add support for IPC logging
  defconfig: lahaina-gki: Enable PWM LPG driver
  pwm: Add snapshot of QTI PWM LPG driver
  defconfig: lahaina-gki: Enable MFD SPMI PMIC driver
  clk: qcom: Add additional clock debugfs support
  clk: add/modify debugfs support for clocks
  interconnect: qcom: Add EPSS L3 support for Lahaina
  dt-bindings: interconnect: Add epss l3 header for Lahaina
  drivers: llcc edac: Add Cache Error Reporting driver for llcc
  drivers: soc: qcom: Add snapshot of boot stats driver
  drivers: firmware: psci: Register with kernel restart handler
  msm: ipa: Free rx_wrapper for tmp_alloc pages
  ANDROID: f2fs: fix possible merge of unencrypted with encrypted I/O
  spi: spi-msm-geni: Add support to make SPI driver GKI compliant
  coresight: Add snapshot of remote etm driver
  coresight: Add snapshot of remote qdss driver
  wil6210: added sysfs file for FTM calibration
  wil6210: fix QCA_WLAN_VENDOR_ATTR_FREQ attribute ID
  wil6210: support FTM/AOA while unassociated
  wil6210: initial support for FTM and AOA
  ANDROID: gki_defconfig: Enable UCLAMP by default
  firmware: qcom_scm: Check for NULL before dereferencing __scm
  ANDROID: make sure proc mount options are applied
  ANDROID: sound: usb: Add helper APIs to enable audio stream
  devfreq: Do not allow tunable updates when device is suspended
  PM/devfreq: Do not switch governors from sysfs when device is suspended
  PM / devfreq: Fix race condition between suspend/resume and governor_store
  PM / devfreq: Introduce an event lock
  Revert "PM / devfreq: Modify the device name as devfreq(X) for sysfs"
  PM / devfreq: qoslat: Update voting level definitions
  devfreq: Allow bw_hwmon resume with zero resume freq
  devfreq: bwmon: Increase the IOPercentage limits to 400
  qcom-llcc-pmu: Update the LLCC PMU configurations for kona
  perf: Introduce a LLCC PMU
  PM / devfreq: Add support for memory latency QoS voting
  PM / devfreq: memlat: optimize freq and stall_pct calculations
  PM / devfreq: memlat: Aggregate memlat mons under a controller
  devfreq: detect ddr type and add frequency table accordingly
  PM / devfreq: bw_hwmon: use unsigned parameter for bytes_to_mbps
  devfreq: bimc_bwmon: Add support to enable BWMON clks
  devfreq: return error code when governor start fails
  devfreq: bw_mon: check for the return value of start_monitor
  devfreq: Do not round up bandwidth on BWMON4 devices
  PM / devfreq: bw_hwmon: Fix a race condition in hwmon stop
  devfreq: suppress platform driver bind / unbind feature
  devfreq: suppress platform driver bind / unbind feature
  devfreq: update freq variable in compute_freq function
  devfreq: memlat: Add suspend/resume for mem_latency
  PM / devfreq: icc: Switch to OPP APIs
  PM / devfreq: bw_hwmon: Reset clear bits for some hardware versions
  PM / devfreq: memlat: Add support for compute-bound logic
  msm: kgsl: Set up the adreno device at runtime
  msm: kgsl: Add dedicated boolean functions for adreno sysfs
  msm: kgsl: Make a child device just for the bwmon governor
  msm: kgsl: Remove nonsense around the a5xx and a6xx SMMU table update
  msm: kgsl: Move memory pool initialization to the KGSL core
  msm: kgsl: Cleanup the device tree probing for memory pools
  msm: kgsl: Use DMA APIs for memory pool cache maintenance
  msm: kgsl: Move kgsl_pool_allocate_pages()
  msm: kgsl: Legacy efuse doesn't need adreno_device
  msm: kgsl: Make the a6xx mbox client static
  msm: kgsl: Make switch out of secure more target specific
  msm: kgsl: Clean up preemption
  msm: kgsl: Make RGMU use the regular GPU powerlevels
  msm: kgsl: Cleanup iommu device tree probe
  msm: kgsl: Consolidate zap shader loading
  dmaengine: gpi: Add support to make GPI driver GKI compliant
  PM / devfreq: memlat: Look for min stall% in addition to ratio criteria
  devfreq: simple-dev: Make the freq-table property optional
  PM / devfreq: bw_hwmon: Add support for specifying count factor
  PM / devfreq: bw_hwmon: Add support for configuring byte MID match
  PM / devfreq: bw_hwmon: Add support for BWMON5 monitors
  PM / devfreq: bw_hwmon: Split out sw and hw paths
  PM / devfreq: bw_hwmon: Reflow some code
  PM / devfreq: bw_hwmon: irq can be negative
  PM / devfreq: bimc-bwmon: Add support for version 4
  PM / devfreq: bw_hwmon: Add HW offload support to governor
  PM / devfreq: Introduce a memory-latency governor
  PM / devfreq: bw_hwmon: Expose a throttle adjust tunable
  devfreq: devfreq_simple_dev: Add support for preparing device clock
  PM / devfreq: bw_hwmon: Update to low latency, high sampling rate algorithm
  PM / devfreq: governor_cache_hwmon: Fix race in monitor start/stop
  PM / devfreq: bimc-bwmon: set a floor_mbps for irq threshold
  PM / devfreq: cache_hwmon: Use array for reporting monitor stats
  PM / devfreq: cache_hwmon: Move IRQ handling to device drivers
  PM / devfreq: Refactor Cache HWmon governor to be more generic
  PM / devfreq: bimc-bwmon: Add support for version 2
  usb: gadget: ffs: Use local copy of descriptors for userspace copy
  soc: qcom: ssr: Export find_subsys_device function
  ALSA: compress: Add support to send codec specific data
  arm64: defconfig: Enable Lazy DMA Mapping on Lahaina GKI
  msm:ipa: changing err prints to dbg prints
  drivers: thermal: Add a snapshot of thermal framework
  usb: dwc3-msm: Add soft dependency on phy drivers
  msm: ipa3: SRAM NAT, DDR NAT, back-and-forth NAT
  iommu/arm-smmu: Reduce log spam from ECATS translation timeouts
  ANDROID: Update ABI representation
  ANDROID: Don't base allmodconfig on gki_defconfig
  ANDROID: Disable UNWINDER_ORC for allmodconfig
  ANDROID: ASoC: Fix 'allmodconfig' build break
  dmaengine: gpi: Add support for 32-bit kernel
  dmaengine: gpi: Capture GPI hardware status during GSI General interrupt
  uio: msm_sharedmem: Fix format specifier to print resource_size_t
  uio: msm_sharedmem: Use proper format to print phys_addr_t
  uio: msm_sharedmem: Add support for HYP call
  uio: Add snapshot of MSM sharedmem driver
  iommu/arm-smmu: Express fastmap domain geometries correctly
  ANDROID: sched, cpuidle: Track cpuidle state index in the scheduler
  topology: Add snapshot of possible sibling cpu mask changes
  sched: Add snapshot of affinity changes
  sched: reduce sleep duration in wait_task_inactive()
  power: em: correct increasing freq/power ratio
  sched/topology: Enable EAS on SMP systems also
  ANDROID: sched/fair: Avoid unnecessary balancing of asymmetric capacity groups
  Revert "sched/deadline: Remove cpu_active_mask from cpudl_find()"
  trace/sched: set priority to 150 for deadline tasks
  sched: turn off the TTWU_QUEUE feature
  cpu/hotplug: Ensure that sched domains are rebuilt before hotplug
  sched: Introduce PANIC_ON_SCHED_BUG
  timer: Add function to migrate timers
  hrtimer: make sure PINNED flag is cleared after removing hrtimer
  hrtimer.h: prevent pinned timer state from breaking inactive test
  hrtimer: create hrtimer_quiesce_cpu() to isolate CPU from hrtimers
  timer: create timer_quiesce_cpu() to isolate CPU from timers
  hrtimer: update timer->state with 'pinned' information
  serial: Add UART port for EUD
  Linux 5.4.2
  platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size
  platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer
  HID: core: check whether Usage Page item is after Usage ID items
  crypto: talitos - Fix build error by selecting LIB_DES
  Revert "jffs2: Fix possible null-pointer dereferences in jffs2_add_frag_to_fragtree()"
  ext4: add more paranoia checking in ext4_expand_extra_isize handling
  r8169: fix resume on cable plug-in
  r8169: fix jumbo configuration for RTL8168evl
  selftests: pmtu: use -oneline for ip route list cache
  tipc: fix link name length check
  selftests: bpf: correct perror strings
  selftests: bpf: test_sockmap: handle file creation failures gracefully
  net/tls: use sg_next() to walk sg entries
  net/tls: remove the dead inplace_crypto code
  selftests/tls: add a test for fragmented messages
  net: skmsg: fix TLS 1.3 crash with full sk_msg
  net/tls: free the record on encryption error
  net/tls: take into account that bpf_exec_tx_verdict() may free the record
  openvswitch: remove another BUG_ON()
  openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info()
  sctp: cache netns in sctp_ep_common
  slip: Fix use-after-free Read in slip_open
  sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook
  openvswitch: fix flow command message size
  net: sched: fix `tc -s class show` no bstats on class with nolock subqueues
  net: psample: fix skb_over_panic
  net: macb: add missed tasklet_kill
  net: dsa: sja1105: fix sja1105_parse_rgmii_delays()
  mdio_bus: don't use managed reset-controller
  macvlan: schedule bc_work even if error
  gve: Fix the queue page list allocated pages count
  x86/fpu: Don't cache access to fpu_fpregs_owner_ctx
  thunderbolt: Power cycle the router if NVM authentication fails
  mei: me: add comet point V device id
  mei: bus: prefix device names on bus with the bus name
  USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P
  staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids
  staging: rtl8723bs: Drop ACPI device ids
  staging: rtl8192e: fix potential use after free
  staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param()
  usb: dwc2: use a longer core rest timeout in dwc2_core_reset()
  driver core: platform: use the correct callback type for bus_find_device
  crypto: inside-secure - Fix stability issue with Macchiatobin
  net: disallow ancillary data for __sys_{send,recv}msg_file()
  net: separate out the msghdr copy from ___sys_{send,recv}msg()
  io_uring: async workers should inherit the user creds
  PM / devfreq: icc: Add suspend/resume APIs
  PM / devfreq: governor_bw_hwmon: Add suspend/resume support
  PM / devfreq: Add MSM BIMC bwmon support for bw_hwmon governor
  msm: devfreq_icc: Add devfreq driver for device bandwidth voting
  devfreq: Add CPUBW HW monitor governor
  arm64: defconfig: Enable RPMh clock driver for Lahaina
  wil6210: add module parameter for alternate interface name
  ANDROID: Update ABI representation
  arm64: defconfig: Enable CONFIG_I2C_RTC6226_QCA on Lahaina
  defconfig: enable fastrpc driver on Lahaina
  media: v4l2-core: guard code against ABI breakage
  msm: cvp: Disabe sys cache and dsp initialization
  checkpatch: check symlinks while searching compatible strings
  UPSTREAM: of: property: Add device link support for interrupt-parent, dmas and -gpio(s)
  UPSTREAM: of: property: Fix the semantics of of_is_ancestor_of()
  UPSTREAM: i2c: of: Populate fwnode in of_i2c_get_board_info()
  UPSTREAM: regulator: core: Don't try to remove device links if add failed
  UPSTREAM: driver core: Clarify documentation for fwnode_operations.add_links()
  mm: cma: Reduce dmesg spam
  mm: cma: make writeable CMA debugfs optional
  mm: cma: restrict base_pfn exposure
  clk: qcom: add clk rpmh support for Lahaina
  dt-bindings: clock: Add rpmh header for Lahaina
  mm: cma: Print region name on failure
  dt-bindings: sound: Add GPR device tree bindings
  lib/vsprintf: Less restrictive hashed pointer printing
  firmware: qcom_scm: Add MODULE_LICENSE
  firmware: qcom-scm: Fix formatting errors in the trace string
  msm: kgsl: Make secure memory depend on QCOM_SECURE_BUFFER
  msm: kgsl: Fix context refcounting for adreno debugfs
  msm: kgsl: Fix linked sysfs files
  msm: kgsl: Replace the sorted dispatcher pending list
  msm: kgsl: Use a simpler algorithm to find SVM addresses
  msm: kgsl: Move globals to the KGSL device handle
  msm: kgsl: Reorganize the shared memory APIs
  msm: kgsl: Stop using KGSL_MEMDESC_CONTIG
  msm: kgsl: Remove unneeded static inline functions
  msm: kgsl: Make 'globals' a device level debugfs file
  msm: kgsl: Remove a few unused device tree properties
  msm: kgsl: Move always on timer reads to target specific code
  msm: kgsl: Cleanup GPU regulators
  msm: kgsl: Make coresight optional
  msm: kgsl: Add support for the Adreno GPU
  ANDROID: Update ABI representation
  ANDROID: gki_defconfig: IIO=y
  msm: ipa: Add PIL driver as soft dependency for IPA
  msm: ipa3: Fix to hold the clock until replenish the descriptors
  msm: ipa3: Fix to increase timeout value for send command
  ANDROID: Update ABI representation
  coresight: funnel: add support for duplicating funnel devices
  msm: adsprpc: Fix adsprpc info leak
  mm, page_owner: record time and pid
  iommu: arm-smmu: clear TBU halt request when halt times out
  iommu/arm-smmu: fix stale fault reporting in ecats operation
  clk: qcom: dispcc: Fix stuck on warning for disp_cc_mdss_mdp_lut_clk
  clk: qcom: gpucc: Voltage voting support for Lahaina
  clk: qcom: camcc: Voltage voting support for Lahaina
  clk: qcom: gcc: Voltage voting support for Lahaina
  ANDROID: ASoC: core - add hostless DAI support
  mm: usercopy: skip stack page span check
  ANDROID: gki_defconfig: =m's applied for virtio configs in arm64
  arm64: defconfig: Enable the MSM ION heaps on Lahaina GKI
  arm64: defconfig: Enable secure buffer driver on Lahaina GKI
  msm: ipa3: Fix to avoid buffer overread
  serial: msm_geni_serial: Ensure to set clock freq correctly
  soc: qcom: Add spss transport for Glink Probe driver
  ANDROID: Update ABI representation after 5.4.1 merge
  Linux 5.4.1
  KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel
  powerpc/book3s64: Fix link stack flush on context switch
  staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
  USB: serial: option: add support for Foxconn T77W968 LTE modules
  USB: serial: option: add support for DW5821e with eSIM support
  USB: serial: mos7840: fix remote wakeup
  USB: serial: mos7720: fix remote wakeup
  USB: serial: mos7840: add USB ID to support Moxa UPort 2210
  appledisplay: fix error handling in the scheduled work
  USB: chaoskey: fix error case of a timeout
  usb-serial: cp201x: support Mark-10 digital force gauge
  usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit()
  usbip: tools: fix fd leakage in the function of read_attr_usbip_status
  USBIP: add config dependency for SGL_ALLOC
  ALSA: hda - Disable audio component for legacy Nvidia HDMI codecs
  media: mceusb: fix out of bounds read in MCE receiver buffer
  media: imon: invalid dereference in imon_touch_event
  media: cxusb: detect cxusb_ctrl_msg error in query
  media: b2c2-flexcop-usb: add sanity checking
  media: uvcvideo: Fix error path in control parsing failure
  futex: Prevent exit livelock
  futex: Provide distinct return value when owner is exiting
  futex: Add mutex around futex exit
  futex: Provide state handling for exec() as well
  futex: Sanitize exit state handling
  futex: Mark the begin of futex exit explicitly
  futex: Set task::futex_state to DEAD right after handling futex exit
  futex: Split futex_mm_release() for exit/exec
  exit/exec: Seperate mm_release()
  futex: Replace PF_EXITPIDONE with a state
  futex: Move futex exit handling into futex code
  cpufreq: Add NULL checks to show() and store() methods of cpufreq
  media: usbvision: Fix races among open, close, and disconnect
  media: usbvision: Fix invalid accesses after device disconnect
  media: vivid: Fix wrong locking that causes race conditions on streaming stop
  media: vivid: Set vid_cap_streaming and vid_out_streaming to true
  ALSA: usb-audio: Fix Scarlett 6i6 Gen 2 port data
  ALSA: usb-audio: Fix NULL dereference at parsing BADD
  futex: Prevent robust futex exit race
  x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3
  x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make the CPU_ENTRY_AREA_PAGES assert precise
  selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel
  selftests/x86/mov_ss_trap: Fix the SYSENTER test
  x86/entry/32: Fix NMI vs ESPFIX
  x86/entry/32: Unwind the ESPFIX stack earlier on exception entry
  x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL
  x86/entry/32: Use %ss segment where required
  x86/entry/32: Fix IRET exception
  x86/cpu_entry_area: Add guard page for entry stack on 32bit
  x86/pti/32: Size initial_page_table correctly
  x86/doublefault/32: Fix stack canaries in the double fault handler
  x86/xen/32: Simplify ring check in xen_iret_crit_fixup()
  x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout
  x86/stackframe/32: Repair 32-bit Xen PV
  nbd: prevent memory leak
  x86/speculation: Fix redundant MDS mitigation message
  x86/speculation: Fix incorrect MDS/TAA mitigation status
  x86/insn: Fix awk regexp warnings
  md/raid10: prevent access of uninitialized resync_pages offset
  Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues"
  Revert "Bluetooth: hci_ll: set operational frequency earlier"
  ath10k: restore QCA9880-AR1A (v1) detection
  ath10k: Fix HOST capability QMI incompatibility
  ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
  ath9k_hw: fix uninitialized variable data
  Bluetooth: Fix invalid-free in bcsp_close()
  serial: msm_geni_serial: Add missing changes from 4.19 kernel
  msm: ipa: Enable IPA compilation for Lahaina
  drivers: soc: qcom: Add snapshot of driver for FSA4480 I2C device
  i3c: i3c-master-qcom-geni: Add I3C GENI driver snapshot
  firmware: qcom_scm: Add trace points to scm driver
  ANDROID: gki_defconfig: enable CONFIG_REGULATOR_FIXED_VOLTAGE
  soc: qcom: Remove downstream scm driver
  FROMLIST: crypto: arm64/sha: fix function types
  ANDROID: arm64: kvm: disable CFI
  ANDROID: arm64: add __nocfi to __apply_alternatives
  ANDROID: arm64: add __pa_function
  ANDROID: arm64: add __nocfi to functions that jump to a physical address
  ANDROID: arm64: bpf: implement arch_bpf_jit_check_func
  ANDROID: bpf: validate bpf_func when BPF_JIT is enabled with CFI
  ANDROID: add support for Clang's Control Flow Integrity (CFI)
  ANDROID: arm64: allow LTO_CLANG and THINLTO to be selected
  FROMLIST: arm64: fix alternatives with LLVM's integrated assembler
  FROMLIST: arm64: lse: fix LSE atomics with LLVM's integrated assembler
  ANDROID: arm64: disable HAVE_ARCH_PREL32_RELOCATIONS with LTO_CLANG
  ANDROID: arm64: vdso: disable LTO
  ANDROID: irqchip/gic-v3: rename gic_of_init to work around a ThinLTO+CFI bug
  ANDROID: soc/tegra: disable ARCH_TEGRA_210_SOC with LTO
  ANDROID: init: ensure initcall ordering with LTO
  ANDROID: drivers/misc/lkdtm: disable LTO for rodata.o
  ANDROID: efi/libstub: disable LTO
  ANDROID: scripts/mod: disable LTO for empty.c
  ANDROID: kbuild: fix dynamic ftrace with clang LTO
  ANDROID: kbuild: add support for Clang LTO
  ANDROID: kbuild: add CONFIG_LD_IS_LLD
  FROMGIT: driver core: platform: use the correct callback type for bus_find_device
  FROMLIST: arm64: implement Shadow Call Stack
  FROMLIST: arm64: disable SCS for hypervisor code
  FROMLIST: arm64: vdso: disable Shadow Call Stack
  FROMLIST: arm64: efi: restore x18 if it was corrupted
  FROMLIST: arm64: preserve x18 when CPU is suspended
  FROMLIST: arm64: reserve x18 from general allocation with SCS
  FROMLIST: arm64: disable function graph tracing with SCS
  FROMLIST: scs: add support for stack usage debugging
  FROMLIST: scs: add accounting
  FROMLIST: add support for Clang's Shadow Call Stack (SCS)
  FROMLIST: arm64: kernel: avoid x18 in __cpu_soft_restart
  FROMLIST: arm64: kvm: stop treating register x18 as caller save
  FROMLIST: arm64/lib: copy_page: avoid x18 register in assembler code
  FROMLIST: arm64: mm: avoid x18 in idmap_kpti_install_ng_mappings
  ANDROID: clang: update to 10.0.1
  clk: qcom: dispcc: Voltage voting support for Lahaina
  clk: qcom: videocc: Voltage voting support for Lahaina
  msm: cvp: Avoid CVP loading at boot
  ANDROID: update ABI representation
  ABI: aarch64: Update ABI snapshot based on v5.4
  msm: ipa: fix ipa driver compilation issue
  iommu: dma-mapping-fast: fix iova alloc wrap
  ALSA: pcm: use lock to protect substream runtime resource
  ALSA: pcm: add locks for accessing runtime resource
  ALSA: compress: Memset timestamp structure to zero
  kconfig: add new config AUDIO_QGKI for audio
  Asoc: Add audio backend to hwdep interface
  kernel: Create and export kernel headers
  usb: dwc3-msm: Delete sysfs files on driver remove
  FROMLIST: pwm: Convert period and duty cycle to u64
  drivers: pinctrl: msm: remove redundant call to set handler
  ANDROID: gki_defconfig: FW_CACHE to no
  FROMGIT: firmware_class: make firmware caching configurable
  msm: adsprpc: Making adsprpc gki compliant
  ANDROID: gki_defconfig: removed CONFIG_PM_WAKELOCKS
  ANDROID: gki_defconfig: enable CONFIG_IKHEADERS as m
  ANDROID: update ABI representation
  FROMLIST: reboot: Export reboot_mode
  FROMLIST: iommu/arm-smmu: Update my email address in MODULE_AUTHOR()
  FROMLIST: iommu/arm-smmu: Allow building as a module
  FROMLIST: iommu/arm-smmu: Unregister IOMMU and bus ops on device removal
  FROMLIST: iommu/arm-smmu-v3: Allow building as a module
  FROMLIST: iommu/arm-smmu-v3: Unregister IOMMU and bus ops on device removal
  FROMLIST: iommu/arm-smmu: Prevent forced unbinding of Arm SMMU drivers
  FROMLIST: Revert "iommu/arm-smmu: Make arm-smmu explicitly non-modular"
  FROMLIST: Revert "iommu/arm-smmu: Make arm-smmu-v3 explicitly non-modular"
  FROMLIST: drivers/iommu: Allow IOMMU bus ops to be unregistered
  FROMLIST: iommu/of: Take a ref to the IOMMU driver during ->of_xlate()
  FROMLIST: drivers/iommu: Take a ref to the IOMMU driver prior to ->add_device()
  FROMLIST: PCI: Export pci_ats_disabled() as a GPL symbol to modules
  FROMLIST: iommu/of: Request ACS from the PCI core when configuring IOMMU linkage
  FROMLIST: drivers/iommu: Export core IOMMU API symbols to permit modular drivers
  FROMGIT: of: property: Add device link support for "iommu-map"
  Revert "FROMLIST: iommu: Export core IOMMU functions to kernel modules"
  Revert "FROMLIST: PCI: Export PCI ACS and DMA searching functions to modules"
  Revert "FROMLIST: of: Export of_phandle_iterator_args() to modules"
  usb: typec: ucsi: Optimise ucsi_unregister()
  usb: typec: ucsi: New error codes
  usb: typec: ucsi: Remove all bit-fields
  usb: typec: ucsi: Remove struct ucsi_control
  usb: typec: ucsi: Remove the old API
  usb: typec: ucsi: ccg: Move to the new API
  usb: typec: ucsi: acpi: Move to the new API
  usb: typec: ucsi: Simplified registration and I/O API
  usb: typec: Remove the callback members from struct typec_capability
  usb: typec: ucsi: Start using struct typec_operations
  usb: typec: tps6598x: Start using struct typec_operations
  usb: typec: tcpm: Start using struct typec_operations
  usb: typec: Separate the operations vector
  usb: typec: Introduce typec_get_drvdata()
  usb: typec: Copy everything from struct typec_capability during registration
  ANDROID: initial branch preparations for 5.4
  soc: qcom: spss_utils: fix emulation logic for lahaina rumi
  i2c: i2c-msm-geni: Add support to make I2C driver GKI compliant
  ALSA: uapi: add new macro SNDRV_AUDIO_QGKI
  ALSA: compress: Add APTX format support in ALSA
  uapi: sound : update audio decoder format headers
  SoC: soc-core: export function to find components
  defconfig: lahaina-gki: enable the fixed regulator driver
  regulator: fixed: add support for proxy consumers
  arm64: defconfig: Enable aop-qmp clock driver for Lahaina
  clk: qcom: clk-aop-qmp: Update CLK_ENABLE_HAND_OFF flag to 0
  clk: qcom: clk-aop-qmp: Add module support to this driver
  arm64: defconfig: Enable IPC IRQ bridge for Lahaina
  arm64: defconfig: Enable GLINK Packet driver for Lahaina
  usb: dt-bindings: Add USB QMP PHY registers definition
  arm64: defconfig: Disable hvc console for lahaina SoC
  usb: dwc3-msm: Don't use devm_ioremap when ringing GSI DB
  usb: dwc3-msm: Simplify GSI register macros
  regulator: rpmh-regulator: add support for proxy consumers
  defconfig: lahaina-gki: enable the regulator proxy consumer library
  regulator: add proxy consumer library
  mm: oom_kill: reap memory of a task that receives SIGKILL
  ion: msm: Move msm_ion probe to subsys_initcall_sync
  soc: qcom: secure_buffer: Move to subsys_initcall
  drivers: irqchip: qcom-pdc: remove SPI config in SCM
  msm: cvp: Init reserved cdsp_mem
  defconfig: Enable qcom_scm as a module
  firmware: qcom_scm: Add calls for watchdog tests
  firmware: qcom_scm: Add calls for seccam
  firmware: qcom_scm: Add calls for csptest
  firmware: qcom_smc: Add compatibility layer for qseecom
  soc: qcom: Migrate SCM calls in secure_buffer
  soc: qcom: secure_buffer: Migrate to qcom_scm usage
  firmware: qcom_scm: Add support to assign multiple memory regions
  firmware: qcom_scm: Permit early SCM calls before driver probe
  soc: qcom: Prune unused SCM calls
  soc: qcom: Migrating to upstream SCM driver in smcinvoke
  firmware: qcom_scm: Add memory protection API for MDF
  firmware: qcom_scm: Add a scm calls for displace memory protect
  thermal: qcom: Migrate SCM calls in msm_lmh_dcvs
  thermal: qcom: Migrate SCM calls in lmh_dbg
  msm: cvp: Migrate SCM calls
  firmware: qcom_scm: Add support for protecting videos
  input: touchscreen: synaptics_dsx: Migrate SCM calls
  firmware: qcom_scm: Add calls for camera
  soc: qcom: Migrate SCM calls in remoteqdss
  firmware: qcom: Migrate SCM calls in tz_log
  soc: qcom: Migrate SCM calls in PIL
  firmware: qcom_scm: Add calls for pfk_ice
  msm: kgsl: Migrate SCM calls in GPU bus governor
  coresight: tpdm: Migrate SCM calls
  soc: qcom: Migrate SCM calls in qtee_shmbridge
  soc: qcom: Migrate SCM calls in msm_tz_smmu
  msm: kgsl: Migrate SCM calls in kgsl iommu
  usb: dwc3: Issue core soft reset upon controller halt failure
  usb: dwc3: gadget: Clear pending events when stopping controller
  usb: gadget: Prevent race between composite_setup & USB disconnect
  msm: ipa4: add MAC filtering for 802_1Q packets
  platform: msm: Migrate SCM calls in IPAv3
  soc: qcom: Migrate SCM calls in jtagv8
  crypto: ice: Migrate SCM calls
  iommu/arm-smmu: Migrate SCM IO calls in arm-smmu
  soc: qcom: Migrate SCM calls in core hang
  msm: kgsl: Migrate SCM calls in adreno
  soc: qcom: Migrate SCM call to disable watchdog
  firmware: qcom_scm: Use qtee_shmbridge if available
  firmware: qcom_scm: Merge qtee_shmbridge and qcom_scm
  firmware: qcom_scm: Rename -64 -> -smc, remove -32
  msm: ipa: Update WDI3.0 specific GSI interface for Lahaina
  arm64: defconfig: Enable the ARM SMMU module on Lahaina
  iommu/arm-smmu: Allow the ARM-SMMU driver to be a module
  Revert "iommu/arm-smmu: Make arm-smmu explicitly non-modular"
  iommu/arm-smmu: Fix atomic domain handling
  iommu/arm-smmu: Use a bitmap for the SMMU domain attributes
  clk: qcom: gpucc: Fix gpll0 parent names
  usb: phy: Remove unused register offsets
  techpack: Replace xtype with type while searching for sub-dirs
  iommu/arm-smmu: Remove legacy bindings bus initialization initcall
  msm: ipa: replace dma_zalloc_coherent()
  soc: qcom: Add Kconfig dependency for SENSORS_SSC
  msm: ipa: Adapt IPA driver to several DLKMs
  msm: ipa: Update IPA driver Kconfig
  iommu/arm-smmu: Remove DOMAIN_ATTR_BITMAP_IOVA_ALLOCATOR
  usb: dwc3-msm: Fix usage of find_matching_dbm_ep()
  usb: dwc3-msm: Fix invalid usb_psy access during remove
  msm: adsprpc: fix compilation errors in fastrpc driver on lahaina
  iommu/arm-smmu: Fix atomic domain attribute check
  ANDROID: usb: gadget: configfs: Support multiple android instances
  clk: qcom: clk-dummy: convert into a platform driver
  usb: dwc3: Suppress error message about optional clks
  msm: ipa: add a thin parsing option for status packets
  msm: ipa: Added an option to enable NAPI in 11ad
  ASoC: core: add debug log for cpu dais
  msm: ipa4: Update mask and shift values for aggr force close register
  clk: qcom: gcc: Fix num_parent count for gcc_usb3 clk init data
  msm: ipa3: Fix to memory allocation failure
  arm64: defconfig: Enable CVP driver
  PM / devfreq: Add cache HW monitor governor
  soc: qcom: secure_buffer: Add missing dma_unmap_single
  firmware: qcom_scm: Support SCM calls before qcom_scm probe
  firmware: qcom_scm: Enable legacy convention in qcom_scm-64.c
  firmware: qcom_scm: Merge legacy and SMCCC conventions
  firmware: qcom_scm-32: Add device argument to atomic calls
  firmware: qcom_scm-32: Create common legacy atomic call
  firmware: qcom_scm-32: Fill SMCCC register in qcom_scm_call
  firmware: qcom_scm-32: Use qcom_scm_desc in non-atomic calls
  firmware: qcom_scm-32: Use SMC arch wrappers
  firmware: qcom_scm-64: Improve SMC convention detection
  firmware: qcom_scm-64: Fill SMC registers in qcom_scm_call_smccc
  firmware: qcom_scm-64: Remove qcom_scm_call_do_smccc
  firmware: qcom_scm-64: Add SCM results to descriptor
  firmware: qcom_scm-64: Move svc/cmd/owner into qcom_scm_desc
  firmware: qcom_scm: Remove unused qcom_scm_get_version
  firmware: qcom_scm: Order functions, definitions by svc/cmd
  firmware: qcom_scm: Apply consistent naming scheme to command IDs
  firmware: qcom_scm-64: Make SMCCC macros less magical
  firmware: qcom_scm: Add funcnum IDs
  firmware: qcom_scm: Rename macros and structures
  firmware/qcom_scm: Add scm call to handle smmu errata
  firmware: qcom_scm-64: Add atomic version of qcom_scm_call
  defconfig: Enable QCOM_SCM on Lahaina QGKI
  defconfig: lahaina: Add QTI_PMIC_GLINK driver
  soc: qcom: Add PMIC Glink driver
  PM / devfreq: Add devfreq driver for simple device
  soc: qcom: qsee_ipc_irq_bridge: Use __poll_t for qiib_poll
  msm: ipa: Bus Scaling/Interconnect Migration
  arm64: defconfig: Enable CONFIG_MSM_BT_POWER on Lahaina
  msm: ipa4: Fix to overcome KW issues
  msm: ipa: IMD command bugfixes
  msm: ipa: update ipa driver APIs for recent wakeup_source and dma
  ASoC: core: Fix possible NULL pointer dereference
  soc: qcom: Add snapshot of watchdog driver
  interconnect: qcom: add virt_clk provider and QUP nodes
  platform: msm-geni-se: Add missing fixes from msm-4.19
  ASoC: msm: Add compressed TX and passthrough support
  Subject: [PATCH 2/3] ABI: aarch64: Update ABI snapshot based on v5.4-rc6
  msm: adsprpc: update driver to latest version from msm-4.19
  msm: gsi: close coal frame before HPS CLEAR
  msm: cvp: Port CVP driver to 5.x kernel
  msm: ipa3: Fix to race condition in updating current polling state
  msm: ipa4: Fix to use common PM handle for coalescing and default pipe
  ASoC: core: update NAME_SIZE to 64
  arm64: defconfig: Enable cam cc clock driver for Lahaina
  msm:ipa: stop the UL MHIP channels  after probe
  msm: ipa: typo in ioctl ipa3_ioctl_mdfy_flt_rule_v2 function
  usb: dwc3-msm: Set vbus_active in peripheral only mode
  ALSA: core: Expose sound card online/offline state
  msm: ipa4: add generic header processing context
  defconfig: lahaina-gki: enable USB PHY drivers
  ASoC: msm: fix integer overflow for long duration offload playback
  ALSA: jack: update jack types
  spi: spi-msm-geni: Add SPI GENI driver snapshot
  clk: qcom: clk-rcg2: add callbacks to deal with voltage voting
  clk: qcom: clk-alpha-pll: add callbacks to deal with voltage voting
  clk: qcom: regmap: Add regmap support for voltage voting
  arm64: defconfig: Enable USB DIAG driver on Lahaina
  usb: phy: Make phy drivers GKI compatible
  arm64: defconfig: Enable CONFIG_ION_POOL_AUTO_REFILL on Lahaina
  arm64: defconfig: Enable QRTR on Lahaina
  soc: qcom: qpnp-pbs: replace #ifdef with #if IS_ENABLED()
  platform: msm: qpnp-revid: replace #ifdef with #if IS_ENABLED()
  soc: qcom: secure_buffer: change the way of divide
  clk: qcom: add vdd-class voltage regulator voting support
  defconfig: Lahaina: Enable support for console UART
  usb: phy: Remove reset link training related workaround
  usb: gadget: Add snapshot of USB GSI function driver
  regmap: Make regmap debugfs write optional
  regmap: improve debugfs interface to dump specific addresses
  usb: gadget: f_qdss: Fix compilation errors
  msm: ipa: Enable NAPI on IPA LAN CONS pipe
  msm: ipa3: add VLAN ID filtering
  arm64: defconfig: Enable global synx driver
  arm64: defconfig: Enable global synx driver
  usb: dwc3: Set vbus_active in peripheral-only mode
  spmi: regmap: enable userspace writes
  nvmem: Add snapshot of QTI SDAM driver
  soc: qcom: Add snapshot of QTI PBS driver
  soc: qcom: Add snapshot of GLINK_PKT Driver
  arm64: defconfig: Enable SPSS GLINK driver on Lahaina
  pinctrl: qcom: Expose ufs_reset as gpio on Lahaina
  soc: qcom: SSR: Fix registration order for wakeup source
  clk: qcom: Add cam cc clock driver for Lahaina
  platform: qpnp-revid: Add REVID support for PM8008, SMB1355 and SMB1390
  platform: qpnp-revid: Add REVID support for PM6125
  platform: qpnp-revid: Add REVID support for PM7250B
  platform: msm: Add snapshot of QPNP_REVID driver
  spmi: spmi-pmic-arb-debug: Change the probe init order
  spmi: spmi-pmic-arb-debug: add clock management support
  spmi: add SPMI PMIC arbiter debug bus driver
  mfd: introduce I2C PMIC controller
  msm: ipa : Fix update of buffer recycle stats
  thermal: qcom-spmi-temp-alarm: add support for GEN2 rev 1 PMIC peripherals
  pinctrl: qcom: spmi-gpio: add support for PM*8350* PMIC variants
  pinctrl: qcom: spmi-gpio: correct parent irqspec translation
  pinctrl: qcom: spmi-gpio: Fix the GPIO strength mapping
  pinctrl: qcom: spmi-gpio: add support to enable/disable output
  mfd: qcom-spmi-pmic: instantiate pmic peripherals at arch_initcall
  mfd: qcom-spmi-pmic: add support for slow SPMI busses
  spmi: spmi-pmic-arb: Fix hw_irq overflow
  spmi: pmic-arb: support updating interrupt type flags
  spmi: spmi-pmic-arb: increase SPMI transaction timeout delay
  spmi: spmi-pmic-arb: block access for invalid PMIC arbiter v5 SPMI writes
  spmi: spmi-pmic-arb: correct duplicate APID to PPID mapping logic
  spmi-pmic-arb: add support to dispatch interrupt based on IRQ status
  spmi: spmi-pmic-arb: check apid against limits before calling irq handler
  spmi: pmic-arb: do not ack and clear peripheral interrupts in cleanup_irq
  spmi: pmic_arb: add a print in cleanup_irq
  spmi: pmic-arb: instantiate spmi_devices at arch_initcall
  iommu/arm-smmu: Move the SMMU driver to subsys_initcall
  defconfig: lahaina-gki: enable USB_DWC3_MSM
  spmi: pmic-arb: Use asynchronous probe
  bluetooth: Add bluetooth slimbus slave drivers
  clk: qcom: Set BRANCH_HALT_SKIP for clocks controlled by PMU
  clk: dt-bindings: gcc: Add PCIE AXI clocks
  clk: qcom: Update gcc clk parent mappings and hw ctrl flag
  interconnect: Move Lahaina interconnect driver to core_initcall
  msm: ipa: Add stats for page recycling
  coresight: byte-cntr: Add support for streaming interface for ETR
  Coresight: byte-cntr: Don't read byte-cntr when etr is diasbled
  msm:ipa: unvote PCIe clock only if it was voted before
  msm: ipa: fix race condition between USB connect and modem SSR
  msm: gsi: Set cookie correctly for GCI channel TREs
  msm: ipa3: Change smmu mapping logs to low priority
  coresight: Add snapshot of Coresight byte counter driver
  msm: ipa: Disable csum offload and status for ODL pipe
  msm: ipa: Retry gsi channel stop for producer channels
  clk: dt-bindings: gcc: Add USB PIPE clocks
  clk: qcom: clk-alpha-pll: Remove zonda pll set rate delay
  clk: qcom: clk-alpha-pll: Add support for controlling zonda5lpe PLL
  arm64: defconfig: Enable gpu cc clock driver for Lahaina
  clk: qcom: Add gpu cc clock driver for Lahaina
  arm64: defconfig: Enable global synx driver
  serial: msm_geni_serial: Double clock-divider for kona based hw
  serial: msm-geni-serial: Remove usage of wakeup_source_init API
  drivers: pinctrl: msm: Add fwnode when setting up hireachy
  ASoC: msm: qdsp6v2: Get path delay support in compress path
  techpack: Fix uapi headers_install
  ion: Assume in-kernel clients for prefetch and drain
  soc: qcom: smp2p: Don't check for NULL before ipc_log_string()
  rpmsg: Don't check for NULL before ipc_log_string()
  net: cnss2: Don't check for NULL before ipc_log_string()
  mailbox: Don't check for NULL before ipc_log_string()
  msm: adsprpc: Don't check for NULL before ipc_log_string()
  usb: dwc3: Fix string format warnings
  iommu/arm-smmu: Fix string format warnings
  regulator: Fix formatting warnings in rpmh-regulator
  scsi: ufs: Fix compiler warning
  arm64: defconfig: Enable shmbridge driver
  shmbridge: GKI change for shmbridge
  cnss2: Switch to new genl structure
  cnss_genl: Use new structure for genl
  cnss_prealloc: Use new API to print stack trace
  i2c: i2c-msm-geni: Add I2C GENI driver snapshot
  media: v4l2-core: Enable VIDIOC_DQBUF ioctl functionality
  dmaengine: gpi: add GPI dmaengine driver snapshot
  usb: gadget: Add support for usb runtime pm APIs
  usb: gadget: rndis: Add packet filter handling for hw accelerated path
  USB: rndis: Honor dl_max_packet_size value sent by host
  usb: gadget: rndis: Add new rndis parameters
  usb: gadget: Add support for rndis flow control callback
  usb: Add support for rndis uplink aggregation
  usb: dwc3-msm: Allow xo_clk to be optional
  usb: dwc3-msm: Get usb power_supply from device tree
  usb: dwc3-msm: Add usb_ep_autoconfig_by_name
  usb: dwc3: Enable PHY deep low power mode in L1 suspend
  msm: ipa3: Ratelimit the error logs for pkts with invalid status
  usb: dwc3: Add DWC3 MSM driver
  coresight: tmc: migrate byte counter to new tmc framework
  coresight: tmc: Read the TMC mode register only if clk is enabled
  of: reserved-memory: Bypass rmem initialization check for carveouts
  msm: synx: Porting synx driver to 5.x kernel
  net: qrtr: Use proper endianness when logging
  usb: phy: Add snapshot of QTI USB PHY drivers
  platform: msm: Add snapshot of USB BAM driver
  usb: gadget: Add snapshot of USB CDEV function driver
  usb: gadget: Add snapshot of CCID function driver
  soc: qcom: spss_utils: add spss_utils as DLKM for GKI
  soc: qcom: add secure processor subsystem (spss) utils driver
  defconfig: enable power drivers for lahaina
  cpuidle: lpm-levels: Update functions to static
  shmbridge: Add shmbridge driver snapshot for lahaina
  coresight: csr: Add msr support
  dcc_v2: Remove duplicate function
  usb: dwc3: Allow dwc_usb31 to operate in dual-role
  usb: dwc3: Fix use after free crash from dwc3 interrupt handler
  usb: dwc3: Prevent continuous retries on error event
  usb: gadget: Add new ipc log buffer to log request and dma
  usb: dwc3: Check USB LPM status before accessing registers
  usb: dwc3: Stop active transfer on control endpoints
  usb: dwc3: Disable the irq before clearing run_stop bit
  dwc3: gadget: Take copy of dwc->gadget_driver before releasing lock
  usb: dwc3: gadget: Enable SUSPEND event after CONNECT DONE
  usb: dwc3: Check return value for debugfs_create_dir()
  usb: dwc3: gadget: Ensure no control transfers in progress when stopping
  usb: dwc3: gadget: Fix runtime PM vote from pull_up handler
  usb: dwc3: Avoid NULL pointer access
  usb: dwc3: request 2mA VBUS current when suspending
  usb: dwc3: Add support for PM suspend and hibernation in host mode
  usb: dwc3: ep0: Fail enqueue() when racing with vbus_sess disconnect
  dwc3: gadget: Don't queue USB request if pull up is getting disabled
  usb: dwc3: Fix USB gadget initialization sequence
  usb: dwc3: Avoid NULL pointer access in dwc3_calc_trbs_left
  usb: dwc3: Do not traverse list using list_for_each_safe
  usb: dwc3: gadget: delay clearing run/stop when setup just arrived
  dwc3: gadget: Stop active transfer pending on ep0 out/in during reset
  usb: dwc3: Fix incorrect ep0 state on reset
  usb: dwc3: resize txfifo of IN/INT endpoint before enabling it
  usb: dwc3: Add QTI MSM platform specific feature and other changes
  msm-geni-se : Correct the icc src/dst read logic for single path
  usb: gadget: Add snapshot of USB QDSS function driver
  arm64: Kconfig: Don't select COMMON_CLK_QCOM in ARCH_LAHAINA
  defconfig: lahaina-gki: Enable support for QCOM clock drivers
  soc: qcom: Add snapshot of IPC IRQ bridge driver
  msm: qdsp6v2: Add timestamp support for compress capture
  drivers: cpuidle: lpm-levels-of: conform to arm,idle-state definition
  drivers: soc: qcom: snapshot of sleep drivers for Lahaina
  ion: msm: Remove dentry_path() usage on heap debugfs file creation errors
  synx: Add synx cancel signaling status
  usb: gadget: Add check gadget function bind or not
  iommu/arm-smmu: bypass hypervisor and read sync/inval status register
  usb: dwc3: gadget: Keep track of IRQ timing statistics
  usb: dwc3: Keep track of interrupt statistics
  usb: dwc3: debug: Add logging APIs using IPC logging framework
  usb: xhci-plat: Add DT parameter to program xhci imod_interval
  usb: dwc3: Increase the inter packet gap for USB 2.0
  net: qrtr: Fix wakeup_source_register
  net: qrtr: Add IPC logging for qrtr
  interconnect: qcom: lahaina: Remove stub functions
  interconnect: qcom: fix up endianness for rpmh messages
  icc: qcom: Refactor icc rpmh support
  iommu/arm-smmu: report BID, PID and MID of client on context fault
  mm: cma: add trace events for CMA alloc perf testing
  mm: vmscan: support complete shrinker reclaim
  mm: vmscan: support equal reclaim for anon and file pages
  arm64: defconfig: Enable CONFIG_VM_EVENT_COUNTERS on Lahaina
  mm: run the showmem notifier in alloc failure
  mm, oom: run the showmem notifier in oom
  mm: cma: retry only on EBUSY
  mm: cma: Increase retries if less blocks available
  mm: cma: Register with show_mem notification framework
  mm: cma: sleep between retries in cma_alloc
  mm: swap: free up swap on mm reap
  iommu/io-pgtable: Deprecate IO_PGTABLE_QUIRK_NO_DMA
  iommu/arm-smmu: Use existing facilities for I/O Coherent PTWs
  ion: msm: Add support for ION heaps to implement prefetch and drain
  dma-mapping: Remove exposure of dma_get_[base/size]
  ion: Simplify carveout heap base/size retrieval/error handling
  ion: msm: Remove [cma/dma]_get_[base/size] usage
  ion: Conditionally compile page pool refill code
  usb: gadget: f_ncm: allocate/free net device upon driver bind/unbind
  msm: ADSPRPC: Fix buffer length for capability API
  msm: ipa3: Query stats from Q6 NLO PROD/CONS
  msm: ipa3: Fix to check DMA address valid or not before unmap
  msm: ipa4: Fix to increase coaleascing common event ring size
  pinctrl: qcom: lahaina: add GPIO wakeup interrupt map
  pinctrl: qcom: setup GPIO chip in hierarchy
  drivers: qcom: Add SoC sleep stats driver
  drivers: soc: qcom: Add ddr stats driver
  ASoC: Add a debug message to track widget power up/down
  ASoC: Change info logs to debug
  ABI: aarch64: Update ABI snapshot based on v5.4-rc3
  msm: IPA: mhi_proxy: correct the mhi vote for both bus and device
  msm: camera: Add camera dt binding definitions
  msm: ipa: Add IPA producer and consumer clients for AQC
  scsi: qcom-ufs: Add support for bus voting using ICB framework
  clk: dt-bindings: gpu-cc: Update gpu clock driver header for Lahaina
  defconfig: lahaina-gki: Enable DISP_CC clock driver
  clk: qcom: Add DISP_CC clock driver for Lahaina
  defconfig: lahaina-gki: Enable VIDEO_CC clock driver
  clk: qcom: Add VIDEO_CC clock driver for Lahaina
  usb: gadget: Add snapshot of USB DIAG function driver
  ABI: aarch64: Update ABI snapshot based on v5.4-rc1
  msm: ipa3: get ipa clk for issuing uc cmds
  soc: qcom: scm: Fix SCM device initialization
  mm: showmem: make the notifiers atomic
  mm: Add notifier framework for showing memory
  mm: allow page poisoning to be enabled by default
  arm64: defconfig: Enable RPMSG drivers on Lahaina
  soc: qcom: Add snapshot for Glink Probe driver
  usb: dwc3: gadget: Update chain bit correctly when using sg list
  mm: ratelimit swap write errors
  mm: slub: panic for object and slab errors
  mm: Kconfig: Add DEBUG_SLUB_PANIC_ON option
  mm/page_owner: ask users about default setting of PAGE_OWNER
  defconfig: lahaina-qgki: enable QTI regulator debugfs features
  regulator: core: add support to log enabled regulators during suspend
  regulator: core: add debugfs regulator monitoring and control features
  net: qrtr: Send HELLO message on endpoint register
  net: qrtr: Add pm_wakeup_event() support
  net: qrtr: Make qrtr rx threads as RT priorities
  net: qrtr: Move rx worker to separate worker thread
  net: qrtr: Add support to read qrtr packet size
  net: qrtr: Handle IPCR control port format of older targets
  net: qrtr: Return success if control port is not bound
  net: qrtr: Add dynamic node id configuration
  net: qrtr: Add permission rules for QTI targets
  net: qrtr: Add support for DEL_PROC control message
  net: qrtr: Add forwarding support based on net id
  net: qrtr: Add non blocking option for tx_resume
  net: qrtr: Move tx_resume handling to work context
  net: qrtr: Send BYE message for all nodes on ept
  net: qrtr: Add node assignment on new server
  net: qrtr: Rename qrtr_all_nodes to qrtr_all_epts
  net: qrtr: Add support for multiple nodes on a single ept
  net: qrtr: use alloc_skb_with_frags() in rx path
  net: qrtr: Check function pointer before calling
  net: qrtr: Prevent stale ports from sending
  net: qrtr: Detach socket from sock during release
  msm: ipa3: Fix to not remove endpoint delay if stop channel fails
  arm64: defconfig: Enable IPC IRQ driver for Lahaina
  soc: qcom: Add snapshot for QSEE IPC IRQ driver
  rpmsg: Add snapshot of RPMSG glink driver for spss
  drivers: pinctrl: Add QUP macros for read/write on Lahaina
  pinctrl: Add api to enable/disable wakeup capability for a gpio
  drivers: pinctrl: Add support for read/write of QUP registers
  msm: ipa3: remove ipa3_ctx access from wan driver and qmi service
  msm: ipa: mark the IPA clock on in virtual/emulation mode
  msm: gsi: gsi channel QoS register update
  lib: Ignore kasan errors from find_next_bit and last bit
  net: qrtr: Change port allocation to use cyclic idr
  net: qrtr: Change node mutex to a rw_semaphore
  net: qrtr: Add socket mode optimization
  net: qrtr: Do not send packets before hello negotiation
  ion: msm: Correct OF node refcount handling in error paths
  msm: ipa: Allocate pages in a wq context
  pinctrl: qcom: Add EGPIO feature support to pinctrl driver
  clk: qcom: Export clk_lucid_5lpe_pll_configure()
  msm: ipa: update mem_part table for IPA SRAM
  msm: gsi: gsi 2.9 upgrade
  msm: ipa: Configure IPA pipes and group resources for Lahaina IPA 4.9
  net: qrtr: Align header and payload
  net: qrtr: Remove receive worker
  soc: qcom: qmi_interface: Protect sk_user_data with RCU
  arm64: defconfig: Enable CONFIG_QGKI for Non GKI build
  soc: qcom: Add a config flag to know the build variant
  ion: msm: enable debugfs for ion heaps
  ion: Allow the system heap to expose debug information
  ion: msm: Expose ION API to query buffer VM information
  ion: msm: Assume devicetree support
  ion: msm: Correct msm_ion_parse_dt() error propagation
  ion: msm: Upgrade the ION ABI version
  ion: msm: Rename msm_ion_of.[c/h] to msm_ion.[c/h]
  ion: msm: Fix several errors in the MSM ION kernel header
  of: Make of_get_ddrtype module friendly
  soc: qcom: secure_buffer: Fix secure buffer device initialization
  iommu/arm-smmu: Fix context fault interrupt test
  iommu/arm-smmu: Use bitfields for the TBU debug registers
  serial: msm_geni_serial:Add snapshot of serial UART driver
  platform: msm: Add snapshot of GENI serial engine driver
  regulator: add verbose error messages for invalid voltage requests
  usb: dwc3: qcom: Use GDSC regulator if available
  defconfig: lahaina-gki: enable refgen regulator driver
  regulator: add refgen regulator driver
  arm64: defconfig: Enable gcc clock driver for Lahaina
  clk: qcom: Override clks halt check with BRANCH_HALT_VOTED
  clk: qcom: Add gcc clock driver for Lahaina
  clk: dt-bindings: gcc: Update gcc clock driver header for Lahaina
  defconfig: lahaina-gki: enable rpmh-regulator driver
  net: qrtr: Make qrtr_port_lookup() use RCU
  net: qrtr: Implement outgoing flow control
  net: qrtr: Migrate node lookup tree to spinlock
  net: qrtr: Move resume-tx transmission to recvmsg
  net: qrtr: Stop rx_worker before freeing node
  rpmsg: Add snapshot of RPMSG drivers for lahaina
  iommu: iommu-debug: check valid pfn before performing ATOS ops
  msm: ipa3: SRAM NAT, DDR NAT, back-and-forth NAT
  irqchip: qcom-pdc: Add IPC logging support
  irqchip: qcom-pdc: Additionally set type in SPI config registers
  irqchip: qcom-pdc: add irqchip set/get state calls
  drivers: qcom: rpmh-rsc: add IPC logging support for RSC driver
  soc: qcom: rpmh-rsc: log interrupt status when TCS is busy
  soc: qcom: rpmh: Fix sending incorrect data during rpmh flush
  ARM: smp: export pending IPI state
  drivers: clksource: add API to return cval
  msm: ipa4: Fix to add wake up handle for coalescing pipe
  iommu: iommu-debug: Add support for page table dump
  dma-mapping-fast: add support for atomic fastmap allocations
  defconfig: enable reserved memory check on Lahaina
  of: reserved_mem: Check that memory reserved in device tree is in use
  msm: ipa: add the version check for FnR stats ioctl
  msm: kgsl: Add the kgsl uapi header file
  ipa3: add hasting AP+STA quota/stats support
  iommu/arm-smmu: Adopt bitfield model for remaining SMMU registers
  iommu/arm-smmu: Add reset implementation hook
  iommu/arm-smmu: Add context init implementation hook
  iommu/arm-smmu: Move Secure access quirk to implementation
  iommu/arm-smmu: Add configuration implementation hook
  iommu/arm-smmu: Add implementation infrastructure
  iommu/arm-smmu: Rename arm-smmu-regs.h
  iommu/arm-smmu: Abstract GR0 accesses
  iommu/arm-smmu: Abstract context bank accesses
  iommu/arm-smmu: Abstract GR1 accesses
  iommu/arm-smmu: Get rid of weird "atomic" write
  iommu/arm-smmu: Split arm_smmu_tlb_inv_range_nosync()
  iommu/arm-smmu: Rework cb_base handling
  iommu/arm-smmu: Convert context bank registers to bitfields
  iommu/arm-smmu: Convert GR1 registers to bitfields
  iommu/arm-smmu: Convert GR0 registers to bitfields
  iommu/arm-smmu: Fix SMMU derivation in arm_smmu_power_off_atomic
  of: reserved_mem: add missing of_node_put() for proper ref-counting
  msm: ipa3: remove ipa3_ctx access from wan driver and qmi service
  msm: ipa: add additional checks to prevent use-after free errors
  soc: qcom: qmi_interface: Remove ineffective mutex lock from txn struct
  soc: qcom: qmi_interface: Release mutex lock before return
  soc: qcom: qmi_interface: Add send timeout helper
  soc: qcom: qmi_interface: Fix race between net_reset and release
  soc: qcom: qmi: Remove txn idr entry in qmi  handle release
  soc: qcom: qmi_interface: sync release and data_ready callback
  ion: msm: Correct memory-region of_node reference counting
  ion: msm: Prevent log-spam from ION dmabuf mmap failures
  Revert "staging: android: ion: Use the MSM dmabuf ops when possible"
  ion: Update the heaps to use the MSM ION dmabuf ops for CMO
  ion: msm: Update the heap IDs as per the ION core standards
  include: dt-bindings: ion: Add header for the MSM ION heap IDs
  ion: msm: Define heap IDs as constants in their own file
  clk: qcom: clk-alpha-pll: Add support for controlling Lucid5lpe PLLs
  arm64: defconfig: Enable SSR, PIL, Sysmon, and PDR drivers
  soc: qcom: Fix printk format warnings from subsystem restart
  soc: qcom: Select MSM_PIL for SUBSYSTEM_RESTART
  drivers: irqchip: add PDC irqdomain for wakeup capable GPIOs
  msm: ipa: Enable qmi send request to remove last connection
  msm: ipa: remove unneeded files
  ion: remove cpu binding of pool refill kthreads
  staging: android: ion: Ratelimit warning message
  iommu/arm-smmu: Mask TLBI address correctly
  ion: msm: Relocate MSM ION header directly to include/uapi/linux
  ion: Fail system secure heap creation if system heap is unavailable
  msm: ipa: Fix KW P1 issue
  msm:ipa : enable HOLB drop timeout on MHIP producer channels
  msm: ipa: Fix accessing coal registers when clock is off
  msm: ipa3: Fix to memory allocation failure
  msm: ipa: Decrease refcount of the pages held in cache before freeing
  msm: ipa: Fix race condition between timer expiry for wq and pipe teardown
  iommu: iommu-debug: select IOMMU_DEBUGFS for iommu tests
  msm: ipa: Enable USB DPL end point
  regulator: add rpmh-regulator driver
  dt-bindings: regulator: rpmh-regulator: add new intermediate voltage levels
  dt-bindings: regulator: rpmh-regulator: add SVS_L2 voltage level
  dt-binding: regulator: rpmh-regulator: define RPMh sets and regulator modes
  drivers: llcc-lahaina: Update the SCT table for MMUHWT
  soc: qcom: qmi_interface: Add new error enum
  msm: ipa4: Fix to update the polling mode for coalescing channel
  driver: pinctrl: Add reserved GPIOs for Lahaina
  soc: qcom: pil: Correct memory-region of_node reference counting
  msm: ipa: Fix the double unmap page recycling cleanup on ssr
  drivers: irqchip: pdc: Do not toggle IRQ_ENABLE during mask/unmask
  genirq: Introduce irq_chip_get/set_parent_state calls
  msm: IPA: mhi_proxy: correct the return for mhi unvote on ssr
  msm: ipa: Fix the missing page recycling cleanup on ssr
  coresight: Add snapshot of Coresight hwevent driver
  coresight: csr: Add multiple CSR devices support
  coresight: Add snapshot of Coresight dummy driver
  ABI: aarch64: Update ABI snapshot based on v5.3
  msm: ipa: Ignore empty ipa config file
  msm: ipa4: Set return value if coalescing frame open
  msm: ipa4: Don't decrease the client count if suspend fail
  msm: ipa4: support coalescing pipe suspend
  msm: ipa: allow abort for disable_clks
  msm: ipa4: add masked ipa_wigig debug registers values
  msm: ipa: Use Qtimer for DPL IPA timer
  techpack: Kbuild: Fix to compile the techpack completely
  arm64: defconfig: Clean the lines for unset CONFIGs
  msm: ipa4: Update endpoint prefetch config for lito
  msm: ipa4: Don't query wigig client tethering stats for all targets
  ABI: aarch64: Update ABI snapshot based on v5.3-rc6
  coresight: Add snapshot of Coresight tgu driver
  coresight-etm4x: Merge ETM changes
  radio: RTC6226: Make the rtc6226 driver compatible with QTI platform
  driver: pinctrl: Update pinctrl mappings for Lahiana
  soc: qcom: secure_buffer: Trace hyp_assign calls
  trace: secure_buffer: Introduce trace events for secure buffer
  coresight: Add snapshot of Coresight csr driver
  dcc_v2: Don't set the default value to sram when dcc is enabled
  msm: CDSP: add CDSP loader driver
  irqdomain: add bus token DOMAIN_BUS_WAKEUP
  ion: Use correct heap when freeing secure system heap buffers
  ion: msm: Remove unnecessary free when destroying an ION buffer
  ion: msm: Only check heap IDs if the heap has been initialized
  Bluetooth: btpower: Add snapshot of BT power driver
  defconfig: Add MSM Core Hang Detection as module
  drivers: soc: Add snapshot of MSM Core Hang Detection
  msm: ipa: Add snapshot of IPA driver
  msm: adsprpc: add fastrpc driver files
  ABI: Update ABI snapshot with latest kernel build tools
  scripts: Consider env vaiables while running 'make'
  techpack: replace type with xtype while searching for sub-dirs
  synx : Add snapshot for global synx driver support
  soc: qcom: configure ipcc interrupt as wakeup capable
  coresight: Add snapshot of Coresight TPDM and TPDA driver
  coresight: Add common header file
  coresight: etm: Add check of trace unit power property
  drivers: qcom: rpmh: Add standalone mode support for RPMH
  drivers: qcom: rpmh-rsc: write PDC data
  drivers: qcom: rpmh-rsc: return if the controller is idle
  drivers: qcom: rpmh-rsc: optimize redundant read to determine TCS idle
  drivers: qcom: rpmh-rsc: clear active mode configuration for waketcs
  drivers: qcom: rpmh-rsc: output debug information from RSC
  drivers: qcom: rpmh: add 'solver' state support for RSC controllers
  drivers: qcom: rpmh-rsc: do not read back the register write on trigger
  soc: qcom: dcc: Support new DCC HW feature
  soc: qcom: Add snapshot of the dcc v2 driver
  dt-bindings: Add dt bindings head file for dcc
  soc: qcom: Add snapshot of the memory dump v2 driver
  qseecom: add uapi headfile for Lahaina bring up
  clk: qcom: clk-debug: Unflatten mux tree
  clk: qcom: clk-debug: Add custom measure operators for mccc_clk
  clk: qcom: clk-debug: Add support for enable mask for debug clk
  clk: qcom: clk-debug: Disable the DEBUG clocks when not being used
  clk: clk-debug: Update file permission for clk_measure debugfs
  clk: qcom: Add support for debugfs measure clock
  clk: avoid returning local variable pointers during clock registration
  dt-bindings: clock: Add rpmh clock binding IDs for Kona
  clk: qcom: define vdd_levels enum and vdd_corner[] map
  clk: qcom: Add support for divider flags and table
  clk: qcom: common: only register reset controllers which define resets
  clk: qcom: common: add device tree consumer support for clk_hws
  clk: qcom: add clk rpmh support for Kona
  clk: qcom: clk-spmi-pmic-div: avoid potential divide-by-0
  clk: qcom: clk-spmi-pmic-div: add support for clock-output-names
  clk: qcom: clk-aop-qmp: use correct name pointer before clock registration
  clk: qcom: clk-aop-qmp: pass mbox pointer by reference in qmp_update_client
  clk: qcom: clk-aop-qmp: Fix issue with registering the clock provider
  clk: qcom: clk-aop-qmp: correct mailbox channel request logic
  clk: qcom: clk-aop-qmp: Do not send duplicate requests to AOP
  clk: qcom: Add support for AOP clock controller
  clk: qcom: gdsc: Remove global mutex lock in enable/disable callbacks
  clk: qcom: gdsc-regulator: Remove polling logic when disabling GDSC HW CTL
  clk: qcom: gdsc-regulator: refactor gdsc_probe() to reduce complexity
  clk: qcom: gdsc-regulator: add support for enabling retention registers
  clk: qcom: gdsc-regulator: Add MMCX specific logic
  clk: qcom: gdsc-regulator: Place a min operational vote on GDSC parent
  clk: qcom: Add support for regulator based GDSC control
  clk: qcom: Add support for hardware control branch clocks
  clk: qcom: clk-rcg2: correct set rate handling for FORCE_ENABLE_RCG
  clk: qcom: rcg2: Add support for hardware control mode
  clk: qcom: rcg2: Remove support for update_src_map
  clk: qcom: clk-rcg2: Read RCG source before calculating clk rate
  clk: qcom: Retrieve pre_div from freq_tbl for shared RCG
  clk: qcom: rcg2: Add DIV_ROUND_CLOSEST_ULL to roundoff RCG frequency
  clk: qcom: add null pointer checks for parent clocks
  clk: qcom: clk-rcg2: Fix QUPV3 DFSR M and N register mode overwrite
  clk: qcom: clk-rcg: update DEFINE_RCG_DFS() macro
  clk: qcom: Add support for clock dependency
  clk: Add additional checking to some clock driver functions
  clk: qcom: Add RCG support for DP source
  clk: qcom: Add support for RCGs with dynamic and fixed sources
  clk: qcom: clk-rcg2: Add support to force enable an RCG
  clk: qcom: clk-rcg2: Configure the RCGs to a safe frequency as needed
  clk: qcom: clk-alpha-pll: check pcal_done from mode register
  clk: qcom: clk-alpha-pll: add FREQ_DET support to Zonda PLL lock detection
  clk: qcom: alpha: do not configure PLL during probe if already enabled
  clk: qcom: clk-alpha-pll: add support to reconfigure PLLs during prepare
  clk: qcom: clk-alpha-pll: add support for custom register initialization
  clk: qcom: clk-alpha-pll: Remove reconfiguration of PLLs
  clk: qcom: clk-alpha-pll: Add support for controlling zonda pll
  clk: qcom: clk-alpha-pll: add additional configuration support for PLLs
  clk: qcom: clk-alpha-pll: Add support for controlling Lucid PLLs
  arm64: defconfig: Enable sensors_ssc on Lahaina
  drivers: of: Add API to find ddr device type
  radio: Add snapshot for FM radio support
  radio: RTC6226: Add support for RTC6226 FM chip
  include: rmnet_data: Add snapshot of headers
  drivers: sensors: add sensors ssc driver
  drivers: qcom: rpmh-rsc: modularize RSC controller driver
  drivers: qcom: cmd-db: Dump resource data via debugfs
  pinctrl-lahaina: Correct the pinconfig base address
  arm64: defconfig: Enable llcc perfmon drivers
  drivers: llcc_perfmon: support for dual memory controller added
  drivers: llcc_perfmon: Add llcc_perfmon support
  net: cnss_prealloc: Add snapshot of cnss_prealloc driver
  defconfig: Update test configs for debug defconfig
  drivers: GICv3: Enable logging of interrupts that triggered wakeup
  defconfig: Enable fastmap on Lahaina
  net: cnss_genl: Add snapshot of cnss_genl driver
  soc: qcom: qmi_interface: Abort pending transaction
  soc: qcom: qmi_interface: Add default send timeout
  soc: qcom: qmi_interface: Do not print error for 0 pkt
  arm64: defconfig: Enable SMP2P Sleepstate on Lahaina
  arm64: defconfig: Enable MSM QMP driver for Lahaina
  arm64: defconfig: Enable QMP DEBUGFS driver on Lahaina
  arm64: defconfig: Enable SMP2P and dependencies on Lahaina
  arm64: defconfig: Enable IPC logging driver on Lahaina
  soc: qcom: Add snapshot of smp2p sleepstate driver
  soc: qcom: smp2p: Fix two warnings
  soc: qcom: smp2p: Prevent suspend for threaded irq
  soc: qcom: smp2p: Add enable_irq_wake to SMP2P IRQ
  soc: qcom: smp2p: Add logs in smp2p_update_bits
  soc: qcom: smp2p: Add IPC logging support
  defconfig: Enable the MSM ION heaps on Lahaina
  staging: android: ion: Use the MSM dmabuf ops when possible
  staging: android: ion: Do not assign heap IDs as heaps register
  Revert "staging: android: ion: Remove file ion_carveout_heap.c"
  ion: Merge all ION related changes from msm-4.19 to msm-lahaina
  net: cnss_utils: Add snapshot of cnss_utils driver
  ABI: aarch64: Update ABI snapshot based on v5.3-rc4
  coresight: add node to reset all coresight devices
  trace: rtb: add msm_rtb tracing
  perf: Set the DSU PMU to be readable from any CPU
  qcom: soc: minidump: Add snapshot of minidump.h
  soc: qcom: Add snapshot of SSR, PIL, Sysmon, and PDR drivers
  coresight: add support to enable multiple coresight paths
  arm64: defconfig: Enable CONFIG_SPARSEMEM_VMEMMAP on Lahaina
  iommu: io-pgtable-fast: Use the DMA APIs for cache cleaning
  defconfig: arm64: Enable uncompressed kernel for Lahaina
  epoll: drop struct epoll_event definition
  drivers: qcom: cmd-db: Report if command DB is initialized as standalone
  drivers: qcom: cmd-db: modularize commandDB driver
  drivers: irqchip: enable PDC irqchip for QCOM Lahaina SoC
  spdx: Modify spdx tag from GPL-2.0 to GPL-2.0-only
  coresight: Set clk rate for all coresight devices
  soc: qcom: smp2p: Add restart ack feature
  soc: qcom: smp2p: Introduce pending state for virtual irq
  drivers: mailbox: fix race resulting in multiple message submission
  soc: qcom: smem: Update max processors in soc
  Revert "checkpatch: forbid filesystem accesses from within the kernel."
  Revert "checkpatch: close filp_open loophole."
  Revert "checkpatch: deprecate unbounded string functions."
  Revert "checkpatch: Add warnings for use of mdelay()"
  iommu: Update the offset of the extended domain attributes
  iommu/arm-smmu: Fix a few compiler warnings
  Revert "checkpatch: complain about the use of dsb()."
  Revert "checkpatch: Add exceptions for "dsb" keyword usage"
  iommu/dma-iommu: Allow dma_info_to_prot to be used globally
  mailbox: Add snapshot of MSM QMP driver
  soc: qcom: Add snapshot of MSM QMP debugfs client
  trace: Add snapshot of ipc logging driver
  ufs: ufshcd: Prevent sleeping in IRQ context
  coresight: add support for device names
  ABI: aarch64: Update ABI snapshot based on v5.3-rc1
  ARM64: smp: Fix function prototypes
  net: cnss2: Add snapshot of CNSS2 driver
  arm64: defconfig: Enable EDAC drivers
  drivers: edac: Add Cache Error Reporting driver
  edac: Allow panic on correctable errors (CE)
  sched: Add a check for cpu unbound deferrable timers
  timer: Initialize global deferrable timer
  ARM64: Flush the caches for non panicking CPUs in case of a kernel panic
  ARM64: smp: Save CPU registers before IPI_CPU_STOP processing
  arm64: msm: Add support for uncompressed kernel image
  ARM: arch_timer: force re-selection of the best clocksource
  clocksource: add API to force re-selection of the best clocksource
  defconfig: Disable ZONE_DMA32 on Lahaina
  iommu: Align QCOM_IOMMU_IO_PGTABLE_QUIRKS with other configs
  defconfig: Enable panics on TLB_SYNC timeouts on Lahaina
  defconfig: Enable all IOMMU related configs on Lahaina
  arm64: defconfig: Enable IPCC driver as a module
  kernel: rcu: Panic on RCU stall
  soc: qcom: ipcc: Add snapshot of IPCC controller
  irqdomain: Implement and expose API to clear IRQ mapping for radix tree
  drivers: irq: Add debug information for irq type warnings
  timer: Add a global deferrable timer
  dtc: add integer overflow checks in fdt header
  arm64: mm: Log the process id in the rtb
  ARM: gic-v3: Log the IRQs in RTB before handling an IRQ
  PM / wakeup: Add msm_show_resume_irq_mask to print off wakeup irq
  iommu/arm-smmu: Merge all IOMMU changes from msm-4.19 to msm-lahaina
  printk: Make the console flush configurable in hotplug path
  arm64: defconfig: Enable LLCC driver
  drivers: llcc: Add LLCC driver for Lahaina
  Revert "arm64: kill flush_cache_all()"
  Revert "arm64: Remove unused macros from assembler.h"
  Revert "arm64: Remove unused daif related functions/macros"
  cpu-hotplug: Always use real time scheduling when hotplugging a CPU
  smp: Allow booting a specific subset of CPUs
  cpu/hotplug: Add cpuhp_latency trace event
  workqueue: fix possible livelock with concurrent mod_delayed_work()
  usb : dwc3: Initialize kernel stack variables properly
  arm64: Dump stack for all CPUs on SMP CPU stop
  drivers: llcc: Add new usecase IDs
  drivers: llcc: Create child platform device for llcc_perfmon
  drivers: llcc: Support targets that can write to llcc registers
  drivers: llcc: Write to sub-cache register based on version
  drivers: llcc: Configure cache override registers
  ABI: aarch64: Update the ABI snapshot for v5.2
  irq-chip: gic-v3: remove print message in irq driver
  defconfig: lahaina-gki: enable qualcomm ufs driver
  ufs: ufs-qcom: Add support for presilicon configuration
  ufs: ufshcd: Add check for broken auto-h8 support
  defconfig: lahaina-gki: enable presilicon ufs phy driver
  ABI: aarch64: Update ABI snapshot based for v5.2
  arm64: Apply erratum 1024718 to Cortex A55 r2p0
  phy: qcom-ufs-qrbtc: Add ufs phy driver for presilicon
  defonfig: Enable QCOM UFS Phy driver
  defconfig: lahaina-gki: enable lahaina icc driver
  arm64: defconfig: Enable USB drivers on Lahaina
  usb: host: xhci-plat: Avoid unneeded internal declaration warning
  usb: phy-qcom-emu: Fix typo for memory resource name
  usb: phy: Add driver for USB PHY on QTI emulation platform
  phy: phy-qcom-ufs: Modify phy voltage limits
  rpmsg : glink: validate head and tail index before fifo read write
  soc: qcom: qmi_encdec: Restrict string length in decode
  soc: qcom: smem: validate fields of shared structures
  arm64: Add 32-bit sigcontext definition to uapi signcontext.h
  net: core: neighbour: Change the print format for addresses
  scripts: gki: Clean the generted files by hand instead of mrproper
  elf: Add elf headers helpers support
  interconnect: qcom: Add Lahaina interconnect provider driver
  icc: dt-bindings: add endpoint IDs for Lahaina interconnects
  ABI: Update ABI snapshot due to rolling kernel upgrade
  Merge remote-tracking branch 'remotes/origin/tmp-f686d9f' into msm-lahaina
  arm64: defconfig: Enable the QCOM SCM driver
  soc: qcom: scm: Add snapshot of QCOM SCM driver
  arm64: defconfig: Enable the pinctrl-lahaina driver
  pinctrl: qcom: Add lahaina pinctrl driver
  pinctrl-msm: Allow the driver to be compiled as a module
  checkpatch: Fix commit log check for a filename
  clk: qcom: clk-dummy: Add a dummy clock provider
  msm_rtb: Add _no_log variants
  msm_rtb: Add snapshot of msm_rtb.h
  defconfig: lahaina-gki: enable stub-regulator driver
  regulator: dt-bindings: rpmh-regulator: add header for voltage levels
  regulator: add stub-regulator driver
  .gitignore: Add device tree vendor directories to gitignore
  techpack: add tech package support
  scripts: gki: Fix setting of a CONFIG if it's unset in base defconfig
  ABI: Update ABI snapshot due to libabigail tool changes
  clk: dt-bindings: add clock IDs for Lahaina clock controllers
  .gitignore: Add techpack directory to gitignore
  .gitignore: Exclude the GKI generated defconfigs
  ABI: Update ABI snapshot based on new code baseline
  checkpatch: Handle continuation headers
  ABI: Update to the ABI definition file
  hvc_dcc: Disable preemption when cheking for smp_processor_id
  arm64: defconfig: Enable ARM DCC driver
  hvc_dcc: Make dcc driver read/write from CPU0
  ABI: Add initial ABI definition based on gki_defconfig
  checkpatch: Treat duplicate signatures as a different error class
  checkpatch: allow copyright statements > 80 columns
  checkpatch: Use upstream commit text length checks
  checkpatch: Excuse reverts from "summary line over 75 characters" check
  checkpatch: require commit text
  checkpatch: Don't complain about MIME headers.
  checkpatch: Fix the commit log false positive warnings
  checkpatch: warn on long summary, commit text lines
  checkpatch: complain about the use of dsb().
  checkpatch: warn on subject line not followed by blank line
  checkpatch: Add exceptions for "dsb" keyword usage
  checkpatch: close filp_open loophole.
  checkpatch: Handle long multi-line macros better.
  checkpatch: deprecate unbounded string functions.
  checkpatch: forbid implied-barrier I/O functions.
  checkpatch: forbid filesystem accesses from within the kernel.
  checkpatch: Check for illegal return codes
  checkpatch: Add warnings for use of mdelay()
  checkpatch: Exceptions for CLK_* macros and some spaces in macros
  arm64: defconfig: Enable Lahaina platform
  arm64: Kconfig: Add config option for Lahaina
  ARM: dts: qcom: Add vendor directory to the Makefile
  docs: Makefile: Don't look for Makefiles in bindings
  Documentation: devicetree: Remove devicetree bindings from kernel
  defconfig: Add initial defconfig fragments for Lahaina
  scripts: gki: Add GKI support
  scripts: snapshot of kernel build utility scripts
  Makefile: Disable undefined-optimized and add -fno-builtin
  ANDROID: HACK: arm64, LLVMLinux: use -mno-implicit-float
  kbuild: Check for 'clang' string in the entire --version output

Change-Id: Ie31e65a8b2960eca7d7e52e7a2201a656ac4825d
Signed-off-by: Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
Elliot Berman 2020-06-01 08:26:23 -07:00
commit 792b143158
1423 changed files with 900575 additions and 3747 deletions

8
.gitignore vendored
View File

@ -146,3 +146,11 @@ x509.genkey
# Clang's compilation database file
/compile_commands.json
# GKI generated defconfigs
arch/*/configs/vendor/*-gki_defconfig
arch/*/configs/vendor/*-qgki_defconfig
arch/*/configs/vendor/*-qgki-debug_defconfig
# vendor device tree directories
arch/arm64/boot/dts/vendor/

45
Android.bp Normal file
View File

@ -0,0 +1,45 @@
cc_binary_host {
name: "unifdef",
srcs: ["scripts/unifdef.c"],
sanitize: {
never: true,
},
}
genrule {
name: "gen-headers_install.sh",
srcs: ["scripts/headers_install.sh"],
tools: ["unifdef"],
out: ["headers_install.sh"],
cmd: "sed 's+scripts/unifdef+$(location unifdef)+g' $(in) > $(out)",
}
cc_prebuilt_binary {
name: "headers_install.sh",
device_supported: false,
host_supported: true,
srcs: [":gen-headers_install.sh"],
}
// Use the following for verbose output from kernel_headers.py.
// kernel_headers_verbose = "--verbose "
// Use the following for minimal output from kernel_headers.py.
kernel_headers_verbose = ""
build = ["gen_headers_arm.bp", "gen_headers_arm64.bp"]
cc_library_headers {
name: "qti_kernel_headers",
arch: {
arm: {
generated_headers: ["qti_generate_kernel_headers_arm"],
export_generated_headers: ["qti_generate_kernel_headers_arm"],
},
arm64: {
generated_headers: ["qti_generate_kernel_headers_arm64"],
export_generated_headers: ["qti_generate_kernel_headers_arm64"],
},
},
vendor: true,
recovery_available: true,
}

View File

@ -2,7 +2,7 @@
# Makefile for Sphinx documentation
#
subdir-y := devicetree/bindings/
subdir-y :=
# Check for broken documentation file references
ifeq ($(CONFIG_WARN_MISSING_DOCUMENTS),y)

View File

@ -432,6 +432,10 @@
embedded devices based on command line input.
See Documentation/block/cmdline-partition.rst
boot_cpus= [SMP]
Rather than attempting to online all possible CPUs at
boot time, only online the specified set of CPUs.
boot_delay= Milliseconds to delay each printk during boot.
Values larger than 10 seconds (10000) are changed to
no delay (0).

View File

@ -0,0 +1,361 @@
Introduction
============
This module will be used to log the events by any module/driver which
enables Inter Processor Communication (IPC). Some of the IPC drivers such
as Message Routers, Multiplexers etc. which act as a passive pipe need
some mechanism to log their events. Since all such IPC drivers handle a
large amount of traffic/events, using kernel logs renders kernel logs
unusable by other drivers and also degrades the performance of IPC
drivers. This new module will help in logging such high frequency IPC
driver events while keeping the standard kernel logging mechanism
intact.
Hardware description
====================
This module does not drive any hardware resource and will only use the
kernel memory-space to log the events.
Software description
====================
Design Goals
------------
This module is designed to
* support logging for drivers handling large amount of
traffic/events
* define & differentiate events/logs from different drivers
* support both id-based and stream-based logging
* support extracting the logs from both live target & memory dump
IPC Log Context
----------------
This module will support logging by multiple drivers. To differentiate
between the multiple drivers that are using this logging mechanism, each
driver will be assigned a unique context by this module. Associated with
each context is the logging space, dynamically allocated from the kernel
memory-space, specific to that context so that the events logged using that
context will not interfere with other contexts.
Event Logging
--------------
Every event will be logged as a <Type: Size: Value> combination. Type
field identifies the type of the event that is logged. Size field represents
the size of the log information. Value field represents the actual
information being logged. This approach will support both id-based logging
and stream-based logging. This approach will also support logging sub-events
of an event. This module will provide helper routines to encode/decode the
logs to/from this format.
Encode Context
---------------
Encode context is a temporary storage space that will be used by the client
drivers to log the events in <Type: Size: Value> format. The client drivers
will perform an encode start operation to initialize the encode context
data structure. Then the client drivers will log their events into the
encode context. Upon completion of event logging, the client drivers will
perform an encode end operation to finalize the encode context data
structure to be logged. Then this updated encode context data structure
will be written into the client driver's IPC Log Context. The maximum
event log size will be defined as 256 bytes.
Log Space
----------
Each context (Figure 1) has an associated log space, which is dynamically
allocated from the kernel memory-space. The log space is organized as a list of
1 or more kernel memory pages. Each page (Figure 2) contains header information
which is used to differentiate the log kernel page from the other kernel pages.
0 ---------------------------------
| magic_no = 0x25874452 |
---------------------------------
| nmagic_no = 0x52784425 |
---------------------------------
| version |
---------------------------------
| user_version |
---------------------------------
| log_id |
---------------------------------
| header_size |
---------------------------------
| |
| |
| name [20 chars] |
| |
| |
---------------------------------
| run-time data structures |
---------------------------------
Figure 1 - Log Context Structure
31 0
0 ---------------------------------
| magic_no = 0x52784425 |
---------------------------------
| nmagic_no = 0xAD87BBDA |
---------------------------------
|1| page_num |
---------------------------------
| read_offset | write_offset |
---------------------------------
| log_id |
---------------------------------
| start_time low word |
| start_time high word |
---------------------------------
| end_time low word |
| end_time high word |
---------------------------------
| context offset |
---------------------------------
| run-time data structures |
. . . . .
---------------------------------
| |
| Log Data |
. . .
. . .
| |
--------------------------------- PAGE_SIZE - 1
Figure 2 - Log Page Structure
In addition to extracting logs at runtime through DebugFS, IPC Logging has been
designed to allow extraction of logs from a memory dump. The magic numbers,
timestamps, and context offset are all added to support the memory-dump
extraction use case.
Design
======
Alternate solutions discussed include using kernel & SMEM logs which are
limited in size and hence using them render them unusable by other drivers.
Also kernel logging into serial console is slowing down the performance of
the drivers by multiple times and sometimes lead to APPs watchdog bite.
Power Management
================
Not-Applicable
SMP/multi-core
==============
This module uses spinlocks & mutexes to handle multi-core safety.
Security
========
Not-Applicable
Performance
===========
This logging mechanism, based on experimental data, is not expected to
cause a significant performance degradation. Under worst case, it can
cause 1 - 2 percent degradation in the throughput of the IPC Drivers.
Interface
=========
Exported Data Structures
------------------------
struct encode_context {
struct tsv_header hdr;
char buff[MAX_MSG_SIZE];
int offset;
};
struct decode_context {
int output_format;
char *buff;
int size;
};
Kernel-Space Interface APIs
----------------------------
/*
* ipc_log_context_create: Create a ipc log context
*
* @max_num_pages: Number of pages of logging space required (max. 10)
* @mod_name : Name of the directory entry under DEBUGFS
* @user_version : Version number of user-defined message formats
*
* returns reference to context on success, NULL on failure
*/
void *ipc_log_context_create(int max_num_pages, const char *mod_name,
uint16_t user_version);
/*
* msg_encode_start: Start encoding a log message
*
* @ectxt: Temporary storage to hold the encoded message
* @type: Root event type defined by the module which is logging
*/
void msg_encode_start(struct encode_context *ectxt, uint32_t type);
/*
* msg_encode_end: Complete the message encode process
*
* @ectxt: Temporary storage which holds the encoded message
*/
void msg_encode_end(struct encode_context *ectxt);
/*
* tsv_timestamp_write: Writes the current timestamp count
*
* @ectxt: Context initialized by calling msg_encode_start()
*
* Returns 0 on success, -ve error code on failure
*/
int tsv_timestamp_write(struct encode_context *ectxt);
/*
* tsv_pointer_write: Writes a data pointer
*
* @ectxt: Context initialized by calling msg_encode_start()
* @pointer: Pointer value to write
*
* Returns 0 on success, -ve error code on failure
*/
int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
/*
* tsv_int32_write: Writes a 32-bit integer value
*
* @ectxt: Context initialized by calling msg_encode_start()
* @n: Integer to write
*
* Returns 0 on success, -ve error code on failure
*/
int tsv_int32_write(struct encode_context *ectxt, int32_t n);
/*
* tsv_byte_array_write: Writes a byte array
*
* @ectxt: Context initialized by calling msg_encode_start()
* @data: Location of data
* @data_size: Size of data to be written
*
* Returns 0 on success, -ve error code on failure
*/
int tsv_byte_array_write(struct encode_context *ectxt,
void *data, int data_size);
/*
* ipc_log_write: Write the encoded message into the log space
*
* @ctxt: IPC log context where the message has to be logged into
* @ectxt: Temporary storage containing the encoded message
*/
void ipc_log_write(unsigned long ctxt, struct encode_context *ectxt);
/*
* ipc_log_string: Helper function to log a string
*
* @dlctxt: IPC Log Context created using ipc_log_context_create()
* @fmt: Data specified using format specifiers
*/
int ipc_log_string(unsigned long dlctxt, const char *fmt, ...);
/*
* tsv_timestamp_read: Reads a timestamp
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_timestamp_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_pointer_read: Reads a data pointer
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_pointer_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_int32_read: Reads a 32-bit integer value
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_int32_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* tsv_byte_array_read: Reads a byte array/string
*
* @ectxt: Context retrieved by reading from log space
* @dctxt: Temporary storage to hold the decoded message
* @format: Output format while dumping through DEBUGFS
*/
void tsv_byte_array_read(struct encode_context *ectxt,
struct decode_context *dctxt, const char *format);
/*
* add_deserialization_func: Register a deserialization function to
* to unpack the subevents of a main event
*
* @ctxt: IPC log context to which the deserialization function has
* to be registered
* @type: Main/Root event, defined by the module which is logging, to
* which this deserialization function has to be registered.
* @dfune: Deserialization function to be registered
*
* return 0 on success, -ve value on FAILURE
*/
int add_deserialization_func(unsigned long ctxt, int type,
void (*dfunc)(struct encode_context *,
struct decode_context *));
Driver parameters
=================
Not-Applicable
Config options
==============
Not-Applicable
Dependencies
============
This module will partially depend on CONFIG_DEBUGFS, in order to dump the
logs through debugfs. If CONFIG_DEBUGFS is disabled, the above mentioned
helper functions will perform no operation and return appropriate error
code if the return value is non void. Under such circumstances the logs can
only be extracted through the memory dump.
User space utilities
====================
DEBUGFS
Other
=====
Not-Applicable
Known issues
============
None
To do
=====
None

276
Documentation/mhi.txt Normal file
View File

@ -0,0 +1,276 @@
Overview of Linux kernel MHI support
====================================
Modem-Host Interface (MHI)
=========================
MHI used by the host to control and communicate with modem over high speed
peripheral bus. Even though MHI can be easily adapt to any peripheral buses,
primarily used with PCIe based devices. The host has one or more PCIe root
ports connected to modem device. The host has limited access to device memory
space, including register configuration and control the device operation.
Data transfers are invoked from the device.
All data structures used by MHI are in the host system memory. Using PCIe
interface, the device accesses those data structures. MHI data structures and
data buffers in the host system memory regions are mapped for device.
Memory spaces
-------------
PCIe Configurations : Used for enumeration and resource management, such as
interrupt and base addresses. This is done by mhi control driver.
MMIO
----
MHI MMIO : Memory mapped IO consists of set of registers in the device hardware,
which are mapped to the host memory space through PCIe base address register
(BAR)
MHI control registers : Access to MHI configurations registers
(struct mhi_controller.regs).
MHI BHI register: Boot host interface registers (struct mhi_controller.bhi) used
for firmware download before MHI initialization.
Channel db array : Doorbell registers (struct mhi_chan.tre_ring.db_addr) used by
host to notify device there is new work to do.
Event db array : Associated with event context array
(struct mhi_event.ring.db_addr), host uses to notify device free events are
available.
Data structures
---------------
Host memory : Directly accessed by the host to manage the MHI data structures
and buffers. The device accesses the host memory over the PCIe interface.
Channel context array : All channel configurations are organized in channel
context data array.
struct __packed mhi_chan_ctxt;
struct mhi_ctxt.chan_ctxt;
Transfer rings : Used by host to schedule work items for a channel and organized
as a circular queue of transfer descriptors (TD).
struct __packed mhi_tre;
struct mhi_chan.tre_ring;
Event context array : All event configurations are organized in event context
data array.
struct mhi_ctxt.er_ctxt;
struct __packed mhi_event_ctxt;
Event rings: Used by device to send completion and state transition messages to
host
struct mhi_event.ring;
struct __packed mhi_tre;
Command context array: All command configurations are organized in command
context data array.
struct __packed mhi_cmd_ctxt;
struct mhi_ctxt.cmd_ctxt;
Command rings: Used by host to send MHI commands to device
struct __packed mhi_tre;
struct mhi_cmd.ring;
Transfer rings
--------------
MHI channels are logical, unidirectional data pipes between host and device.
Each channel associated with a single transfer ring. The data direction can be
either inbound (device to host) or outbound (host to device). Transfer
descriptors are managed by using transfer rings, which are defined for each
channel between device and host and resides in the host memory.
Transfer ring Pointer: Transfer Ring Array
[Read Pointer (RP)] ----------->[Ring Element] } TD
[Write Pointer (WP)]- [Ring Element]
- [Ring Element]
--------->[Ring Element]
[Ring Element]
1. Host allocate memory for transfer ring
2. Host sets base, read pointer, write pointer in corresponding channel context
3. Ring is considered empty when RP == WP
4. Ring is considered full when WP + 1 == RP
4. RP indicates the next element to be serviced by device
4. When host new buffer to send, host update the Ring element with buffer
information
5. Host increment the WP to next element
6. Ring the associated channel DB.
Event rings
-----------
Events from the device to host are organized in event rings and defined in event
descriptors. Event rings are array of EDs that resides in the host memory.
Transfer ring Pointer: Event Ring Array
[Read Pointer (RP)] ----------->[Ring Element] } ED
[Write Pointer (WP)]- [Ring Element]
- [Ring Element]
--------->[Ring Element]
[Ring Element]
1. Host allocate memory for event ring
2. Host sets base, read pointer, write pointer in corresponding channel context
3. Both host and device has local copy of RP, WP
3. Ring is considered empty (no events to service) when WP + 1 == RP
4. Ring is full of events when RP == WP
4. RP - 1 = last event device programmed
4. When there is a new event device need to send, device update ED pointed by RP
5. Device increment RP to next element
6. Device trigger and interrupt
Example Operation for data transfer:
1. Host prepare TD with buffer information
2. Host increment Chan[id].ctxt.WP
3. Host ring channel DB register
4. Device wakes up process the TD
5. Device generate a completion event for that TD by updating ED
6. Device increment Event[id].ctxt.RP
7. Device trigger MSI to wake host
8. Host wakes up and check event ring for completion event
9. Host update the Event[i].ctxt.WP to indicate processed of completion event.
Time sync
---------
To synchronize two applications between host and external modem, MHI provide
native support to get external modems free running timer value in a fast
reliable method. MHI clients do not need to create client specific methods to
get modem time.
When client requests modem time, MHI host will automatically capture host time
at that moment so clients are able to do accurate drift adjustment.
Example:
Client request time @ time T1
Host Time: Tx
Modem Time: Ty
Client request time @ time T2
Host Time: Txx
Modem Time: Tyy
Then drift is:
Tyy - Ty + <drift> == Txx - Tx
Clients are free to implement their own drift algorithms, what MHI host provide
is a way to accurately correlate host time with external modem time.
To avoid link level latencies, controller must support capabilities to disable
any link level latency.
During Time capture host will:
1. Capture host time
2. Trigger doorbell to capture modem time
It's important time between Step 2 to Step 1 is deterministic as possible.
Therefore, MHI host will:
1. Disable any MHI related to low power modes.
2. Disable preemption
3. Request bus master to disable any link level latencies. Controller
should disable all low power modes such as L0s, L1, L1ss.
MHI States
----------
enum MHI_STATE {
MHI_STATE_RESET : MHI is in reset state, POR state. Host is not allowed to
access device MMIO register space.
MHI_STATE_READY : Device is ready for initialization. Host can start MHI
initialization by programming MMIO
MHI_STATE_M0 : MHI is in fully active state, data transfer is active
MHI_STATE_M1 : Device in a suspended state
MHI_STATE_M2 : MHI in low power mode, device may enter lower power mode.
MHI_STATE_M3 : Both host and device in suspended state. PCIe link is not
accessible to device.
MHI Initialization
------------------
1. After system boots, the device is enumerated over PCIe interface
2. Host allocate MHI context for event, channel and command arrays
3. Initialize context array, and prepare interrupts
3. Host waits until device enter READY state
4. Program MHI MMIO registers and set device into MHI_M0 state
5. Wait for device to enter M0 state
Linux Software Architecture
===========================
MHI Controller
--------------
MHI controller is also the MHI bus master. In charge of managing the physical
link between host and device. Not involved in actual data transfer. At least
for PCIe based buses, for other type of bus, we can expand to add support.
Roles:
1. Turn on PCIe bus and configure the link
2. Configure MSI, SMMU, and IOMEM
3. Allocate struct mhi_controller and register with MHI bus framework
2. Initiate power on and shutdown sequence
3. Initiate suspend and resume
Usage
-----
1. Allocate control data structure by calling mhi_alloc_controller()
2. Initialize mhi_controller with all the known information such as:
- Device Topology
- IOMMU window
- IOMEM mapping
- Device to use for memory allocation, and of_node with DT configuration
- Configure asynchronous callback functions
3. Register MHI controller with MHI bus framework by calling
of_register_mhi_controller()
After successfully registering controller can initiate any of these power modes:
1. Power up sequence
- mhi_prepare_for_power_up()
- mhi_async_power_up()
- mhi_sync_power_up()
2. Power down sequence
- mhi_power_down()
- mhi_unprepare_after_power_down()
3. Initiate suspend
- mhi_pm_suspend()
4. Initiate resume
- mhi_pm_resume()
MHI Devices
-----------
Logical device that bind to maximum of two physical MHI channels. Once MHI is in
powered on state, each supported channel by controller will be allocated as a
mhi_device.
Each supported device would be enumerated under
/sys/bus/mhi/devices/
struct mhi_device;
MHI Driver
----------
Each MHI driver can bind to one or more MHI devices. MHI host driver will bind
mhi_device to mhi_driver.
All registered drivers are visible under
/sys/bus/mhi/drivers/
struct mhi_driver;
Usage
-----
1. Register driver using mhi_driver_register
2. Before sending data, prepare device for transfer by calling
mhi_prepare_for_transfer
3. Initiate data transfer by calling mhi_queue_transfer
4. After finish, call mhi_unprepare_from_transfer to end data transfer

View File

@ -200,5 +200,23 @@ Then in some part of your code after your wiphy has been registered:
Statically compiled regulatory database
---------------------------------------
When a database should be fixed into the kernel, it can be provided as a
firmware file at build time that is then linked into the kernel.
In most situations the userland solution using CRDA as described
above is the preferred solution. However in some cases a set of
rules built into the kernel itself may be desirable. To account
for this situation, a configuration option has been provided
(i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled,
the wireless database information contained in net/wireless/db.txt is
used to generate a data structure encoded in net/wireless/regdb.c.
That option also enables code in net/wireless/reg.c which queries
the data in regdb.c as an alternative to using CRDA.
The file net/wireless/db.txt should be kept up-to-date with the db.txt
file available in the git repository here:
git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git
Again, most users in most situations should be using the CRDA package
provided with their distribution, and in most other situations users
should be building and using CRDA on their own rather than using
this option. If you are not absolutely sure that you should be using
CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.

View File

@ -183,6 +183,10 @@ partial drain
EOF is reached and now DSP can start skipping padding delay. Also next write
data would belong to next track
- set_next_track_param
This routine is called to send to DSP codec specific data of subsequent track
in gapless before first write.
Sequence flow for gapless would be:
- Open
- Get caps / codec caps

View File

@ -406,7 +406,7 @@ KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS)
# Make variables (CC, etc...)
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
REAL_CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
@ -427,6 +427,14 @@ PYTHON3 = python3
CHECK = sparse
BASH = bash
ifndef DISABLE_WRAPPER
# Use the wrapper for the compiler. This wrapper scans for new
# warnings and causes the build to stop upon encountering them
CC = $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)
else
CC = $(REAL_CC)
endif
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
NOSTDINC_FLAGS :=
@ -524,7 +532,7 @@ ifdef building_out_of_srctree
{ echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
endif
ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
ifneq ($(shell $(CC) --version 2>&1 | grep clang),)
ifneq ($(CROSS_COMPILE),)
CLANG_TRIPLE ?= $(CROSS_COMPILE)
CLANG_FLAGS += --target=$(notdir $(CLANG_TRIPLE:%-=%))
@ -1252,17 +1260,27 @@ PHONY += archheaders archscripts
hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj
techpack-dirs := $(shell find $(srctree)/techpack -maxdepth 1 -mindepth 1 -type d -not -name ".*")
techpack-dirs := $(subst $(srctree)/,,$(techpack-dirs))
PHONY += headers
headers: $(version_h) scripts_unifdef uapi-asm-generic archheaders archscripts
$(if $(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/Kbuild),, \
$(error Headers not exportable for the $(SRCARCH) architecture))
$(Q)$(MAKE) $(hdr-inst)=include/uapi
$(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi
$(Q)for d in $(techpack-dirs); do \
$(MAKE) $(hdr-inst)=$$d/include/uapi; \
done
# Deprecated. It is no-op now.
PHONY += headers_check
headers_check:
@:
headers_check: headers
$(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
$(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi HDRCHECK=1
$(Q)for d in $(techpack-dirs); do \
$(MAKE) $(hdr-inst)=$$d/include/uapi HDRCHECK=1; \
done
ifdef CONFIG_HEADERS_INSTALL
prepare: headers

250772
abi_gki_aarch64.xml Normal file

File diff suppressed because it is too large Load Diff

859
abi_gki_aarch64_whitelist Normal file
View File

@ -0,0 +1,859 @@
[abi_whitelist]
add_timer
add_uevent_var
add_wait_queue
alloc_chrdev_region
__alloc_disk_node
alloc_etherdev_mqs
alloc_netdev_mqs
alloc_pages_exact
__alloc_pages_nodemask
__alloc_percpu
__alloc_skb
alloc_workqueue
arch_bpf_jit_check_func
__arch_copy_from_user
__arch_copy_to_user
arm64_const_caps_ready
autoremove_wake_function
bcmp
blk_cleanup_queue
blk_execute_rq
blk_get_queue
blk_get_request
blk_mq_alloc_tag_set
blk_mq_complete_request
__blk_mq_end_request
blk_mq_end_request
blk_mq_free_tag_set
blk_mq_init_queue
blk_mq_quiesce_queue
blk_mq_requeue_request
blk_mq_run_hw_queues
blk_mq_start_request
blk_mq_start_stopped_hw_queues
blk_mq_stop_hw_queue
blk_mq_unquiesce_queue
blk_mq_virtio_map_queues
blk_put_queue
blk_put_request
blk_queue_alignment_offset
blk_queue_bounce_limit
blk_queue_can_use_dma_map_merging
blk_queue_flag_clear
blk_queue_flag_set
blk_queue_io_min
blk_queue_io_opt
blk_queue_logical_block_size
blk_queue_max_discard_sectors
blk_queue_max_discard_segments
blk_queue_max_hw_sectors
blk_queue_max_segments
blk_queue_max_segment_size
blk_queue_max_write_zeroes_sectors
blk_queue_physical_block_size
blk_queue_rq_timeout
blk_queue_write_cache
blk_rq_map_kern
blk_rq_map_sg
blk_status_to_errno
blk_update_request
bpf_prog_add
bpf_prog_put
bpf_prog_sub
bpf_stats_enabled_key
bpf_trace_run10
bpf_trace_run2
bpf_trace_run8
bpf_warn_invalid_xdp_action
build_skb
bus_register
bus_unregister
call_netdevice_notifiers
call_rcu
cancel_delayed_work
cancel_delayed_work_sync
cancel_work_sync
capable
cdev_add
cdev_alloc
cdev_del
cdev_device_add
cdev_device_del
cdev_init
cfg80211_connect_done
cfg80211_disconnected
cfg80211_inform_bss_data
cfg80211_put_bss
cfg80211_scan_done
__cfi_slowpath
check_disk_change
__check_object_size
__class_create
class_destroy
__class_register
class_unregister
clear_page
clk_disable
clk_enable
clk_get_rate
clk_prepare
clk_unprepare
complete
complete_all
completion_done
console_suspend_enabled
__const_udelay
consume_skb
_copy_from_iter_full
copy_page
_copy_to_iter
cpu_bit_bitmap
cpufreq_generic_attr
cpufreq_register_driver
cpufreq_unregister_driver
__cpuhp_remove_state
__cpuhp_setup_state
__cpuhp_state_add_instance
__cpuhp_state_remove_instance
cpu_hwcap_keys
cpu_hwcaps
cpumask_next
cpumask_next_wrap
cpu_number
__cpu_online_mask
cpus_read_lock
cpus_read_unlock
cpu_topology
crypto_ablkcipher_type
crypto_dequeue_request
crypto_enqueue_request
crypto_init_queue
crypto_register_alg
crypto_unregister_alg
datagram_poll
debugfs_attr_read
debugfs_attr_write
debugfs_create_dir
debugfs_create_file
debugfs_create_file_unsafe
debugfs_create_x32
debugfs_remove
debugfs_remove_recursive
debug_smp_processor_id
default_llseek
default_wake_function
delayed_work_timer_fn
del_gendisk
del_timer
del_timer_sync
destroy_workqueue
dev_add_pack
dev_close
dev_driver_string
_dev_err
dev_fwnode
__dev_get_by_index
dev_get_by_index
dev_get_by_index_rcu
dev_get_stats
device_add
device_add_disk
device_create
device_create_file
device_del
device_destroy
device_for_each_child
device_initialize
device_init_wakeup
device_property_present
device_property_read_u32_array
device_register
device_remove_file
device_unregister
_dev_info
__dev_kfree_skb_any
devm_clk_get
dev_mc_sync_multiple
dev_mc_unsync
devm_gpiod_get_index
devm_ioremap
devm_kasprintf
devm_kfree
devm_kmalloc
devm_platform_ioremap_resource
devm_regulator_get_optional
__devm_request_region
devm_request_threaded_irq
__devm_reset_control_get
devm_rtc_allocate_device
_dev_notice
dev_open
dev_pm_domain_attach
dev_pm_domain_detach
dev_printk
dev_queue_xmit
dev_remove_pack
devres_add
__devres_alloc_node
devres_destroy
devres_free
dev_set_mtu
dev_set_name
dev_uc_sync_multiple
dev_uc_unsync
_dev_warn
disable_irq
dma_alloc_attrs
dma_direct_map_page
dma_direct_map_sg
dma_direct_sync_sg_for_cpu
dma_direct_sync_sg_for_device
dma_direct_sync_single_for_cpu
dma_direct_sync_single_for_device
dma_direct_unmap_page
dma_direct_unmap_sg
dma_fence_context_alloc
dma_fence_enable_sw_signaling
dma_fence_init
dma_fence_match_context
dma_fence_release
dma_fence_signal
dma_fence_signal_locked
dma_fence_wait_timeout
dma_free_attrs
dma_get_merge_boundary
dma_max_mapping_size
dma_resv_add_excl_fence
dma_resv_add_shared_fence
dma_resv_copy_fences
dma_resv_fini
dma_resv_init
dma_resv_reserve_shared
dma_resv_test_signaled_rcu
dma_resv_wait_timeout_rcu
dma_set_coherent_mask
dma_set_mask
driver_register
driver_unregister
drm_add_edid_modes
drm_add_modes_noedid
drm_atomic_helper_check
drm_atomic_helper_cleanup_planes
drm_atomic_helper_commit
drm_atomic_helper_commit_hw_done
drm_atomic_helper_commit_modeset_disables
drm_atomic_helper_commit_modeset_enables
drm_atomic_helper_commit_planes
drm_atomic_helper_connector_destroy_state
drm_atomic_helper_connector_duplicate_state
drm_atomic_helper_connector_reset
drm_atomic_helper_crtc_destroy_state
drm_atomic_helper_crtc_duplicate_state
drm_atomic_helper_crtc_reset
drm_atomic_helper_dirtyfb
drm_atomic_helper_disable_plane
drm_atomic_helper_page_flip
drm_atomic_helper_plane_destroy_state
drm_atomic_helper_plane_duplicate_state
drm_atomic_helper_plane_reset
drm_atomic_helper_set_config
drm_atomic_helper_shutdown
drm_atomic_helper_update_plane
drm_atomic_helper_wait_for_vblanks
drm_class_device_register
drm_class_device_unregister
drm_clflush_pages
drm_compat_ioctl
drm_connector_attach_edid_property
drm_connector_attach_encoder
drm_connector_cleanup
drm_connector_init
drm_connector_register
drm_connector_unregister
drm_connector_update_edid_property
drm_crtc_cleanup
drm_crtc_init_with_planes
drm_crtc_send_vblank_event
drm_cvt_mode
drm_dbg
drm_debugfs_create_files
drm_dev_alloc
drm_dev_put
drm_dev_register
drm_dev_set_unique
drm_dev_unregister
drm_do_get_edid
drm_encoder_cleanup
drm_encoder_init
drm_err
drm_framebuffer_init
drm_gem_fb_create_handle
drm_gem_fb_destroy
drm_gem_handle_create
drm_gem_object_init
drm_gem_object_lookup
drm_gem_object_put_unlocked
drm_gem_object_release
drm_gem_prime_fd_to_handle
drm_gem_prime_handle_to_fd
drm_gem_prime_mmap
drm_helper_hpd_irq_event
drm_helper_mode_fill_fb_struct
drm_helper_probe_single_connector_modes
drm_ioctl
drm_kms_helper_hotplug_event
drm_mm_init
drm_mm_insert_node_in_range
drm_mm_print
drm_mm_remove_node
drm_mm_takedown
drm_mode_config_cleanup
drm_mode_config_init
drm_mode_config_reset
drm_mode_probed_add
drm_open
drm_plane_cleanup
drm_poll
drm_prime_pages_to_sg
drm_printf
__drm_printfn_debug
drm_put_dev
drm_read
drm_release
drm_set_preferred_mode
drm_universal_plane_init
drm_vma_offset_add
drm_vma_offset_lookup_locked
drm_vma_offset_manager_destroy
drm_vma_offset_manager_init
drm_vma_offset_remove
eth_commit_mac_addr_change
ether_setup
eth_prepare_mac_addr_change
__ethtool_get_link_ksettings
ethtool_op_get_link
ethtool_op_get_ts_info
eth_type_trans
eth_validate_addr
event_triggers_call
fasync_helper
fd_install
find_next_bit
finish_wait
flow_keys_basic_dissector
flush_work
flush_workqueue
fput
free_irq
free_netdev
__free_pages
free_pages_exact
free_percpu
freezing_slow_path
fsl8250_handle_irq
generic_file_llseek
get_device
get_random_bytes
__get_task_comm
get_unused_fd_flags
gpiod_cansleep
gpiod_get_raw_value
gpiod_get_raw_value_cansleep
gpiod_get_value
gpiod_get_value_cansleep
gpiod_is_active_low
gpiod_set_debounce
gpiod_to_irq
hrtimer_active
hrtimer_cancel
hrtimer_forward
hrtimer_init
hrtimer_start_range_ns
hvc_alloc
hvc_instantiate
hvc_kick
hvc_poll
hvc_remove
__hvc_resize
hwrng_register
hwrng_unregister
ida_alloc_range
ida_destroy
ida_free
init_net
init_timer_key
init_wait_entry
__init_waitqueue_head
input_alloc_absinfo
input_allocate_device
input_event
input_free_device
input_mt_init_slots
input_register_device
input_set_abs_params
input_unregister_device
iomem_resource
__ioremap
iounmap
irq_dispose_mapping
irq_set_affinity_hint
irq_set_irq_wake
jiffies
jiffies_to_msecs
kernel_kobj
kfree
kfree_skb
kill_fasync
kimage_vaddr
kimage_voffset
__kmalloc
kmalloc_caches
kmalloc_order_trace
kmem_cache_alloc
kmem_cache_alloc_trace
kmem_cache_create
kmem_cache_destroy
kmem_cache_free
kmemdup
kobject_del
kobject_init_and_add
kobject_put
kobject_uevent
kobject_uevent_env
kstrtoull
kthread_create_on_node
kthread_create_worker
kthread_destroy_worker
kthread_queue_work
kthread_should_stop
kthread_stop
ktime_get
ktime_get_mono_fast_ns
ktime_get_real_seconds
ktime_get_ts64
ktime_get_with_offset
kvfree
kvmalloc_node
kzfree
led_classdev_register_ext
led_classdev_unregister
led_trigger_event
led_trigger_register_simple
led_trigger_unregister_simple
__local_bh_enable_ip
lock_sock_nested
mark_page_accessed
memcpy
__memcpy_fromio
__memcpy_toio
memdup_user
memmove
memparse
memset
__memset_io
misc_deregister
misc_register
mod_timer
__module_get
module_put
__msecs_to_jiffies
msleep
__mutex_init
mutex_is_locked
mutex_lock
mutex_lock_interruptible
mutex_trylock
mutex_unlock
__napi_alloc_skb
napi_complete_done
napi_consume_skb
napi_disable
napi_gro_receive
napi_hash_del
__napi_schedule
napi_schedule_prep
__netdev_alloc_skb
netdev_change_features
netdev_err
netdev_increment_features
netdev_info
netdev_lower_state_changed
netdev_master_upper_dev_link
netdev_notify_peers
netdev_pick_tx
netdev_rx_handler_register
netdev_rx_handler_unregister
netdev_upper_dev_link
netdev_upper_dev_unlink
netdev_warn
netif_carrier_off
netif_carrier_on
netif_device_attach
netif_device_detach
netif_napi_add
netif_napi_del
netif_receive_skb
netif_rx
netif_rx_ni
netif_schedule_queue
netif_set_real_num_rx_queues
netif_set_real_num_tx_queues
__netif_set_xps_queue
netif_stacked_transfer_operstate
netif_tx_stop_all_queues
netif_tx_wake_queue
netlink_capable
__netlink_dump_start
net_ratelimit
nf_conntrack_destroy
nla_memcpy
__nla_parse
nla_put
__nlmsg_put
no_llseek
nonseekable_open
noop_llseek
nr_cpu_ids
nr_swap_pages
nsecs_to_jiffies
__num_online_cpus
of_address_to_resource
of_alias_get_id
of_device_get_match_data
of_device_is_big_endian
of_device_is_compatible
of_find_property
of_get_child_by_name
of_get_next_child
of_get_property
of_irq_get
of_parse_phandle
of_property_read_u64
of_property_read_variable_u32_array
panic
param_ops_bool
param_ops_int
param_ops_uint
passthru_features_check
pci_alloc_irq_vectors_affinity
pci_bus_type
pci_disable_device
pci_enable_device
pci_find_capability
pci_find_ext_capability
pci_find_next_capability
pci_free_irq_vectors
pci_iomap_range
pci_irq_get_affinity
pci_irq_vector
pci_read_config_byte
pci_read_config_dword
__pci_register_driver
pci_release_selected_regions
pci_request_selected_regions
pci_set_master
pci_unregister_driver
PDE_DATA
__per_cpu_offset
perf_trace_buf_alloc
perf_trace_run_bpf_submit
physvirt_offset
pipe_lock
pipe_unlock
platform_device_add
platform_device_add_data
platform_device_alloc
platform_device_del
platform_device_put
platform_device_register_full
platform_device_unregister
__platform_driver_register
platform_driver_unregister
platform_get_irq
platform_get_resource
pm_generic_resume
pm_generic_runtime_resume
pm_generic_runtime_suspend
pm_generic_suspend
__pm_runtime_disable
pm_runtime_enable
__pm_runtime_idle
__pm_runtime_resume
pm_runtime_set_autosuspend_delay
__pm_runtime_set_status
__pm_runtime_suspend
__pm_runtime_use_autosuspend
pm_wakeup_dev_event
prandom_u32
preempt_count_add
preempt_count_sub
preempt_schedule
preempt_schedule_notrace
prepare_to_wait
prepare_to_wait_event
printk
proc_create_net_single
proc_mkdir_data
proto_register
proto_unregister
__put_cred
put_device
put_disk
__put_page
put_unused_fd
queue_delayed_work_on
queue_work_on
___ratelimit
_raw_read_lock
_raw_read_unlock
_raw_spin_lock
_raw_spin_lock_bh
_raw_spin_lock_irq
_raw_spin_lock_irqsave
_raw_spin_trylock
_raw_spin_unlock
_raw_spin_unlock_bh
_raw_spin_unlock_irq
_raw_spin_unlock_irqrestore
_raw_write_lock_bh
_raw_write_unlock_bh
rcu_barrier
__rcu_read_lock
__rcu_read_unlock
refcount_dec_and_test_checked
refcount_inc_checked
refcount_inc_not_zero_checked
__refrigerator
register_blkdev
__register_chrdev
register_netdev
register_netdevice
register_netdevice_notifier
register_pernet_subsys
register_pm_notifier
register_shrinker
regulator_count_voltages
regulator_disable
regulator_enable
regulator_get_current_limit
regulator_get_voltage
regulator_is_supported_voltage
regulator_list_voltage
regulator_set_voltage
release_sock
remove_proc_entry
remove_wait_queue
__request_module
request_threaded_irq
reservation_ww_class
reset_control_assert
reset_control_deassert
revalidate_disk
round_jiffies
__rtc_register_device
rtc_time64_to_tm
rtc_tm_to_time64
rtc_update_irq
rtnl_is_locked
rtnl_link_register
rtnl_link_unregister
rtnl_lock
rtnl_register_module
rtnl_unlock
rtnl_unregister
rtnl_unregister_all
sched_clock
sched_setscheduler
schedule
schedule_timeout
scnprintf
security_sock_graft
seq_lseek
seq_printf
seq_putc
seq_puts
seq_read
serial8250_get_port
serial8250_register_8250_port
serial8250_resume_port
serial8250_suspend_port
serial8250_unregister_port
set_disk_ro
set_page_dirty
sg_alloc_table
__sg_alloc_table_from_pages
sg_copy_from_buffer
sg_copy_to_buffer
sg_free_table
sg_init_one
sg_init_table
sg_miter_next
sg_miter_start
sg_miter_stop
sg_nents
sg_nents_for_len
sg_next
shmem_file_setup
shmem_read_mapping_page_gfp
si_mem_available
si_meminfo
simple_attr_open
simple_attr_read
simple_attr_release
simple_attr_write
simple_read_from_buffer
simple_strtoul
single_open
single_release
sk_alloc
skb_add_rx_frag
skb_clone
skb_coalesce_rx_frag
skb_copy
skb_dequeue
__skb_flow_dissect
skb_free_datagram
skb_page_frag_refill
skb_partial_csum_set
skb_put
skb_queue_purge
skb_queue_tail
skb_recv_datagram
skb_to_sgvec
skb_trim
skb_tstamp_tx
sk_free
snprintf
sock_alloc_send_skb
sock_diag_register
sock_diag_save_cookie
sock_diag_unregister
sock_efree
sock_gettstamp
sock_i_ino
sock_init_data
sock_no_accept
sock_no_bind
sock_no_connect
sock_no_getname
sock_no_getsockopt
sock_no_ioctl
sock_no_listen
sock_no_mmap
sock_no_sendpage
sock_no_setsockopt
sock_no_shutdown
sock_no_socketpair
sock_queue_rcv_skb
__sock_recv_ts_and_drops
sock_register
__sock_tx_timestamp
sock_unregister
softnet_data
__splice_from_pipe
sprintf
sscanf
__stack_chk_fail
__stack_chk_guard
strcmp
strcpy
string_get_size
strlcpy
strlen
strncmp
strncpy
strstr
swiotlb_max_segment
sync_file_create
sync_file_get_fence
synchronize_hardirq
synchronize_irq
synchronize_net
synchronize_rcu
sysfs_create_bin_file
sysfs_create_group
__sysfs_match_string
sysfs_remove_bin_file
sysfs_remove_group
system_freezable_wq
system_freezing_cnt
system_wq
__this_cpu_preempt_check
trace_define_field
trace_event_buffer_commit
trace_event_buffer_reserve
trace_event_ignore_this_pid
trace_event_raw_init
trace_event_reg
trace_handle_return
__tracepoint_dma_fence_emit
__tracepoint_xdp_exception
trace_print_symbols_seq
trace_raw_output_prep
trace_seq_printf
try_module_get
unlock_page
unmap_mapping_range
unregister_blkdev
__unregister_chrdev
unregister_chrdev_region
unregister_netdev
unregister_netdevice_many
unregister_netdevice_notifier
unregister_netdevice_queue
unregister_pernet_subsys
unregister_pm_notifier
unregister_shrinker
up_read
usb_add_gadget_udc
usb_add_hcd
usb_create_hcd
usb_create_shared_hcd
usb_del_gadget_udc
usb_disabled
usb_ep_set_maxpacket_limit
usb_gadget_giveback_request
usb_gadget_udc_reset
usb_get_dev
usb_hcd_check_unlink_urb
usb_hcd_giveback_urb
usb_hcd_is_primary_hcd
usb_hcd_link_urb_to_ep
usb_hcd_poll_rh_status
usb_hcd_resume_root_hub
usb_hcd_unlink_urb_from_ep
usb_put_dev
usb_put_hcd
usb_remove_hcd
usleep_range
vabits_actual
vmalloc_to_page
vmap
vmemmap
vmf_insert_mixed
vmf_insert_pfn
vm_get_page_prot
vunmap
wait_for_completion
wait_for_completion_killable
wait_woken
__wake_up
wake_up_process
__warn_printk
wiphy_free
wiphy_new_nm
wiphy_register
wiphy_unregister
woken_wake_function
ww_mutex_lock
ww_mutex_lock_interruptible
ww_mutex_unlock
xdp_convert_zc_to_xdp_frame
xdp_do_flush_map
xdp_do_redirect
xdp_return_frame
xdp_return_frame_rx_napi
xdp_rxq_info_reg
xdp_rxq_info_reg_mem_model
xdp_rxq_info_unreg

1351
abi_gki_qcom_whitelist Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,6 @@
extern void cpu_init(void);
void soft_restart(unsigned long);
extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
extern void (*arm_pm_idle)(void);
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR

View File

@ -18,7 +18,6 @@ typedef void (*phys_reset_t)(unsigned long, bool);
/*
* Function pointers to optional machine specific functions
*/
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@ -138,10 +137,7 @@ void machine_restart(char *cmd)
local_irq_disable();
smp_send_stop();
if (arm_pm_restart)
arm_pm_restart(reboot_mode, cmd);
else
do_kernel_restart(cmd);
do_kernel_restart(cmd);
/* Give a grace period for failure to restart of 1s */
mdelay(1000);

View File

@ -1073,6 +1073,20 @@ void __init hyp_mode_check(void)
#endif
}
static void (*__arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
static int arm_restart(struct notifier_block *nb, unsigned long action,
void *data)
{
__arm_pm_restart(action, data);
return NOTIFY_DONE;
}
static struct notifier_block arm_restart_nb = {
.notifier_call = arm_restart,
.priority = 128,
};
void __init setup_arch(char **cmdline_p)
{
const struct machine_desc *mdesc;
@ -1132,8 +1146,10 @@ void __init setup_arch(char **cmdline_p)
paging_init(mdesc);
request_standard_resources(mdesc);
if (mdesc->restart)
arm_pm_restart = mdesc->restart;
if (mdesc->restart) {
__arm_pm_restart = mdesc->restart;
register_restart_handler(&arm_restart_nb);
}
unflatten_device_tree();

View File

@ -52,6 +52,11 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ipi.h>
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
DEFINE_PER_CPU(bool, pending_ipi);
EXPORT_PER_CPU_SYMBOL(pending_ipi);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@ -523,6 +528,13 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
{
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
unsigned int cpu;
for_each_cpu(cpu, target)
per_cpu(pending_ipi, cpu) = true;
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
trace_ipi_raise_rcuidle(target, ipi_types[ipinr]);
__smp_cross_call(target, ipinr);
}
@ -697,6 +709,11 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
if ((unsigned)ipinr < NR_IPI)
trace_ipi_exit_rcuidle(ipi_types[ipinr]);
#ifdef CONFIG_QGKI_LPM_IPI_CHECK
this_cpu_write(pending_ipi, false);
#endif /* CONFIG_QGKI_LPM_IPI_CHECK */
set_irq_regs(old_regs);
}

View File

@ -64,11 +64,18 @@ static struct reset_controller_dev sirfsoc_reset_controller = {
#define SIRFSOC_SYS_RST_BIT BIT(31)
static void sirfsoc_restart(enum reboot_mode mode, const char *cmd)
static int sirfsoc_restart(struct notifier_block *nb, unsigned long action,
void *data)
{
writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base);
return NOTIFY_DONE;
}
static struct notifier_block sirfsoc_restart_nb = {
.notifier_call = sirfsoc_restart,
.priority = 192,
};
static int sirfsoc_rstc_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@ -79,7 +86,7 @@ static int sirfsoc_rstc_probe(struct platform_device *pdev)
}
sirfsoc_reset_controller.of_node = np;
arm_pm_restart = sirfsoc_restart;
register_restart_handler(&sirfsoc_restart_nb);
if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
reset_controller_register(&sirfsoc_reset_controller);

View File

@ -29,6 +29,7 @@
#include <linux/cpu.h>
#include <linux/console.h>
#include <linux/pvclock_gtod.h>
#include <linux/reboot.h>
#include <linux/time64.h>
#include <linux/timekeeping.h>
#include <linux/timekeeper_internal.h>
@ -180,11 +181,18 @@ void xen_reboot(int reason)
BUG_ON(rc);
}
static void xen_restart(enum reboot_mode reboot_mode, const char *cmd)
static int xen_restart(struct notifier_block *nb, unsigned long action,
void *data)
{
xen_reboot(SHUTDOWN_reboot);
return NOTIFY_DONE;
}
static struct notifier_block xen_restart_nb = {
.notifier_call = xen_restart,
.priority = 192,
};
static void xen_power_off(void)
{
@ -405,7 +413,7 @@ static int __init xen_pm_init(void)
return -ENODEV;
pm_power_off = xen_power_off;
arm_pm_restart = xen_restart;
register_restart_handler(&xen_restart_nb);
if (!xen_initial_domain()) {
struct timespec64 ts;
xen_read_wallclock(&ts);

View File

@ -278,15 +278,32 @@ config ZONE_DMA
default y
config ZONE_DMA32
bool "Support DMA32 zone" if EXPERT
bool "Enable or Disable Zone DMA"
default y
help
This option enables/disables the DMA zone.
config ARCH_ENABLE_MEMORY_HOTPLUG
depends on !NUMA
def_bool y
config ARCH_ENABLE_MEMORY_HOTREMOVE
def_bool y
config SMP
def_bool y
config HOTPLUG_SIZE_BITS
int "Memory hotplug block size(29 => 512MB 30 => 1GB)"
depends on SPARSEMEM
depends on MEMORY_HOTPLUG
default 30
help
Selects granularity of hotplug memory. Block
size for memory hotplug is represent as a power
of 2.
If unsure, stick with default value.
config KERNEL_MODE_NEON
def_bool y
@ -1022,9 +1039,34 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
if ARM64 && IOMMU_DMA
config ARM64_DMA_IOMMU_ALIGNMENT
int "Maximum PAGE_SIZE order of alignment for DMA IOMMU buffers"
range 4 9
default 9
help
DMA mapping framework by default aligns all buffers to the smallest
PAGE_SIZE order which is greater than or equal to the requested buffer
size. This works well for buffers up to a few hundreds kilobytes, but
for larger buffers it just a waste of address space. Drivers which has
relatively small addressing window (like 64Mib) might run out of
virtual space with just a few allocations.
With this parameter you can specify the maximum PAGE_SIZE order for
DMA IOMMU buffers. Larger buffers will be aligned only to this
specified order. The order is expressed as a power of two multiplied
by the PAGE_SIZE.
endif
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
def_bool y if PGTABLE_LEVELS > 2
config ARCH_MEMORY_PROBE
def_bool y
depends on MEMORY_HOTPLUG
# Supported by clang >= 7.0
config CC_HAVE_SHADOW_CALL_STACK
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
@ -1767,6 +1809,40 @@ config DMI
endmenu
choice
prompt "Kernel compression method"
default BUILD_ARM64_KERNEL_COMPRESSION_GZIP
help
Allows choice between gzip compressed or uncompressed
kernel image. Decision is based on whether the bootloader
can handle (un)compressed kernel images. Most BLs are capable
of decomprssing kernel images and this is the default choice.
config BUILD_ARM64_KERNEL_COMPRESSION_GZIP
bool "Build compressed kernel image"
help
Build a kernel image using gzip
compression. gzip is based on the DEFLATE
algorithm. Check if your bootloader is
capable of decompressing images.
config BUILD_ARM64_UNCOMPRESSED_KERNEL
bool "Build uncompressed kernel image"
help
Build a kernel image without
compression. An uncompressed kernel
image may improve performance in
certain situations.
endchoice
config BUILD_ARM64_DT_OVERLAY
bool "enable DT overlay compilation support"
depends on OF
help
This option enables support for DT overlay compilation.
Enabling this option sets required flags to add DT
overlay in the compilation.
config SYSVIPC_COMPAT
def_bool y
depends on COMPAT && SYSVIPC

View File

@ -187,6 +187,31 @@ config ARCH_QCOM
help
This enables support for the ARMv8 based Qualcomm chipsets.
config ARCH_LAHAINA
bool "Enable Support for Qualcomm Technologies, Inc. LAHAINA"
depends on ARCH_QCOM
help
This enables support for the Qualcomm Technologies, Inc.'s
LAHAINA chipset. If you do not wish to build a kernel that
runs on this chipset or if you are unsure, say 'N' here.
config ARCH_QTI_VM
bool "Enable Virtual Machines Support for Qualcomm Technologies, Inc."
depends on ARCH_QCOM
help
This enables support for the Qualcomm Technologies, Inc.'s
Virtual Machines. If you wish to build a kernel that doesn't
require VM support or if you are unsure,
say 'N' here.
config ARCH_SHIMA
bool "Enable Support for Qualcomm Technologies, Inc. SHIMA"
depends on ARCH_QCOM
help
This enables support for the Qualcomm Technologies, Inc.'s
SHIMA chipset. If you do not wish to build a kernel that
runs on this chipset or if you are unsure, say 'N' here.
config ARCH_REALTEK
bool "Realtek Platforms"
select RESET_CONTROLLER

View File

@ -125,12 +125,17 @@ core-y += arch/arm64/
libs-y := arch/arm64/lib/ $(libs-y)
core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
ifeq ($(CONFIG_BUILD_ARM64_KERNEL_COMPRESSION_GZIP),y)
KBUILD_TARGET := Image.gz
else
KBUILD_TARGET := Image
endif
# Default target when executing plain make
boot := arch/arm64/boot
KBUILD_IMAGE := $(boot)/Image.gz
all: Image.gz
KBUILD_IMAGE := $(boot)/$(KBUILD_TARGET)
all: $(KBUILD_TARGET)
Image: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@

View File

@ -28,3 +28,9 @@ subdir-y += synaptics
subdir-y += ti
subdir-y += xilinx
subdir-y += zte
dtstree := $(srctree)/$(src)
vendor := $(dtstree)/vendor
ifneq "$(wildcard $(vendor)/Makefile)" ""
subdir-y += vendor
endif

View File

@ -0,0 +1,114 @@
/{
dpe: dpe@E8600000 {
compatible = "hisilicon,hi3660-dpe";
status = "ok";
reg = <0x0 0xE8600000 0x0 0x80000>,
<0x0 0xFFF35000 0 0x1000>,
<0x0 0xFFF0A000 0 0x1000>,
<0x0 0xFFF31000 0 0x1000>,
<0x0 0xE86C0000 0 0x10000>;
interrupts = <0 245 4>;
clocks = <&crg_ctrl HI3660_ACLK_GATE_DSS>,
<&crg_ctrl HI3660_PCLK_GATE_DSS>,
<&crg_ctrl HI3660_CLK_GATE_EDC0>,
<&crg_ctrl HI3660_CLK_GATE_LDI0>,
<&crg_ctrl HI3660_CLK_GATE_LDI1>,
<&sctrl HI3660_CLK_GATE_DSS_AXI_MM>,
<&sctrl HI3660_PCLK_GATE_MMBUF>;
clock-names = "aclk_dss",
"pclk_dss",
"clk_edc0",
"clk_ldi0",
"clk_ldi1",
"clk_dss_axi_mm",
"pclk_mmbuf";
dma-coherent;
port {
dpe_out: endpoint {
remote-endpoint = <&dsi_in>;
};
};
iommu_info {
start-addr = <0x8000>;
size = <0xbfff8000>;
};
};
dsi: dsi@E8601000 {
compatible = "hisilicon,hi3660-dsi";
status = "ok";
reg = <0 0xE8601000 0 0x7F000>,
<0 0xFFF35000 0 0x1000>;
clocks = <&crg_ctrl HI3660_CLK_GATE_TXDPHY0_REF>,
<&crg_ctrl HI3660_CLK_GATE_TXDPHY1_REF>,
<&crg_ctrl HI3660_CLK_GATE_TXDPHY0_CFG>,
<&crg_ctrl HI3660_CLK_GATE_TXDPHY1_CFG>,
<&crg_ctrl HI3660_PCLK_GATE_DSI0>,
<&crg_ctrl HI3660_PCLK_GATE_DSI1>;
clock-names = "clk_txdphy0_ref",
"clk_txdphy1_ref",
"clk_txdphy0_cfg",
"clk_txdphy1_cfg",
"pclk_dsi0",
"pclk_dsi1";
#address-cells = <1>;
#size-cells = <0>;
mux-gpio = <&gpio2 4 0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi_in: endpoint {
remote-endpoint = <&dpe_out>;
};
};
port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
dsi_out0: endpoint@0 {
reg = <0>;
remote-endpoint = <&adv7533_in>;
};
dsi_out1: endpoint@1 {
reg = <1>;
remote-endpoint = <&panel0_in>;
};
};
};
panel@1 {
compatible = "hisilicon,mipi-hikey";
#address-cells = <2>;
#size-cells = <2>;
status = "ok";
reg = <1>;
panel-width-mm = <94>;
panel-height-mm = <151>;
vdd-supply = <&ldo3>;
pwr-en-gpio = <&gpio27 0 0>;
bl-en-gpio = <&gpio27 2 0>;
pwm-gpio = <&gpio22 6 0>;
port {
panel0_in: endpoint {
remote-endpoint = <&dsi_out1>;
};
};
};
};
};

View File

@ -0,0 +1,19 @@
/{
gpu: mali@E82C0000 {
compatible = "arm,malit6xx", "arm,mali-midgard";
#cooling-cells = <3>; /* min followed by max */
gpu_outstanding = <0x0>;
reg = <0x0 0xE82C0000 0x0 0x4000>;
interrupts = <0 258 4 0 259 4 0 260 4>;
interrupt-names = "JOB", "MMU", "GPU";
operating-points = <
/* <frequency> <voltage>*/
178000 650000
400000 700000
533000 800000
807000 900000
960000 1000000
1037000 1100000
>;
};
};

View File

@ -10,9 +10,13 @@
#include "hi3660.dtsi"
#include "hikey960-pinctrl.dtsi"
#include "hi3660-drm.dtsi"
#include "hi3660-gpu.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/usb/pd.h>
/ {
model = "HiKey960";
@ -45,6 +49,23 @@ reserved-memory {
#size-cells = <2>;
ranges;
fastboot_cma: fastboot-cma-mem {
reg = <0x0 0x16c00000 0x0 0x4000000>;
compatible = "shared-dma-pool";
hisi,cma-sec;
reusable;
};
uefi-reboot-mode {
reg = <0x0 0x32100000 0x0 0x00001000>;
no-map;
};
bl31 {
reg = <0x0 0x20200000 0x0 0x200000>;
no-map;
};
ramoops@32000000 {
compatible = "ramoops";
reg = <0x0 0x32000000 0x0 0x00100000>;
@ -52,6 +73,14 @@ ramoops@32000000 {
console-size = <0x00020000>;
ftrace-size = <0x00020000>;
};
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
reg = <0x0 0x20C00000 0x0 0x4000000>;
reusable;
linux,cma-default;
};
};
reboot-mode-syscon@32100000 {
@ -196,6 +225,59 @@ optee {
method = "smc";
};
};
hisi_hikey_usb: hisi_hikey_usb {
compatible = "hisilicon,gpio_hubv1";
typec-vbus-gpios = <&gpio25 2 GPIO_ACTIVE_HIGH>;
otg-switch-gpios = <&gpio25 6 GPIO_ACTIVE_HIGH>;
hub-vdd33-en-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usbhub5734_pmx_func>;
usb-role-switch;
port {
#address-cells = <1>;
#size-cells = <0>;
hikey_usb_ep0: endpoint@0 {
reg = <0>;
remote-endpoint = <&dwc3_role_switch>;
};
hikey_usb_ep1: endpoint@1 {
reg = <1>;
remote-endpoint = <&rt1711h_ep>;
};
};
};
i2s2: hi3660_i2s {
compatible = "hisilicon,hi3660-i2s-1.0";
reg = <0x0 0xe804f800 0x0 0x400>,
<0x0 0xe804e000 0x0 0x400>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2_pmx_func &i2s2_cfg_func>;
dmas = <&asp_dmac 18 &asp_dmac 19>;
dma-names = "rx", "tx";
#sound-dai-cells = <0>;
};
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "hikey-hdmi";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&sound_master>;
simple-audio-card,frame-master = <&sound_master>;
sound_master: simple-audio-card,cpu {
sound-dai = <&i2s2>;
};
simple-audio-card,codec {
sound-dai = <&adv7533>;
};
};
};
/*
@ -526,11 +608,54 @@ &i2c0 {
&i2c1 {
status = "okay";
rt1711h: rt1711h@4e {
compatible = "richtek,rt1711h";
reg = <0x4e>;
status = "ok";
interrupt-parent = <&gpio27>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usb_cfg_func>;
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
source-pdos = <PDO_FIXED(5000, 500, PDO_FIXED_USB_COMM)>;
sink-pdos = <PDO_FIXED(5000, 500, PDO_FIXED_USB_COMM)
PDO_VAR(5000, 5000, 1000)>;
op-sink-microwatt = <10000000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
usb_con_ss: endpoint {
remote-endpoint = <&dwc3_ss>;
};
};
};
};
port {
#address-cells = <1>;
#size-cells = <0>;
rt1711h_ep: endpoint@0 {
reg = <0>;
remote-endpoint = <&hikey_usb_ep1>;
};
};
};
adv7533: adv7533@39 {
status = "ok";
compatible = "adi,adv7533";
reg = <0x39>;
};
};
&i2c7 {

View File

@ -355,6 +355,12 @@ pctrl: pctrl@e8a09000 {
#clock-cells = <1>;
};
pmctrl: pmctrl@fff31000 {
compatible = "hisilicon,hi3660-pmctrl", "syscon";
reg = <0x0 0xfff31000 0x0 0x1000>;
#clock-cells = <1>;
};
pmuctrl: crg_ctrl@fff34000 {
compatible = "hisilicon,hi3660-pmuctrl", "syscon";
reg = <0x0 0xfff34000 0x0 0x1000>;
@ -367,6 +373,13 @@ sctrl: sctrl@fff0a000 {
#clock-cells = <1>;
};
reboot {
compatible = "hisilicon,hi3660-reboot";
pmu-regmap = <&pmuctrl>;
sctrl-regmap = <&sctrl>;
reboot-offset = <0x4>;
};
iomcu: iomcu@ffd7e000 {
compatible = "hisilicon,hi3660-iomcu", "syscon";
reg = <0x0 0xffd7e000 0x0 0x1000>;
@ -431,7 +444,28 @@ i2c1: i2c@ffd72000 {
resets = <&iomcu_rst 0x20 4>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pmx_func &i2c1_cfg_func>;
status = "disabled";
status = "ok";
adv7533: adv7533@39 {
status = "ok";
compatible = "adi,adv7533";
reg = <0x39>;
v1p2-supply = <&ldo3>;
vdd-supply = <&ldo3>;
interrupt-parent = <&gpio1>;
interrupts = <1 2>;
pd-gpio = <&gpio5 1 0>;
sel-gpio = <&gpio2 4 0>;
adi,dsi-lanes = <4>;
adi,disable-timing-generator;
#sound-dai-cells = <0>;
port {
adv7533_in: endpoint {
remote-endpoint = <&dsi_out0>;
};
};
};
};
i2c3: i2c@fdf0c000 {
@ -1152,6 +1186,70 @@ map1 {
};
};
};
usb3_otg_bc: usb3_otg_bc@ff200000 {
compatible = "syscon", "simple-mfd";
reg = <0x0 0xff200000 0x0 0x1000>;
usb_phy: usb-phy {
compatible = "hisilicon,hi3660-usb-phy";
#phy-cells = <0>;
hisilicon,pericrg-syscon = <&crg_ctrl>;
hisilicon,pctrl-syscon = <&pctrl>;
hisilicon,eye-diagram-param = <0x22466e4>;
};
};
dwc3: dwc3@ff100000 {
compatible = "snps,dwc3";
reg = <0x0 0xff100000 0x0 0x100000>;
clocks = <&crg_ctrl HI3660_CLK_ABB_USB>,
<&crg_ctrl HI3660_ACLK_GATE_USB3OTG>;
clock-names = "ref", "bus_early";
assigned-clocks = <&crg_ctrl HI3660_ACLK_GATE_USB3OTG>;
assigned-clock-rates = <229000000>;
resets = <&crg_rst 0x90 8>,
<&crg_rst 0x90 7>,
<&crg_rst 0x90 6>,
<&crg_rst 0x90 5>;
interrupts = <0 159 4>, <0 161 4>;
phys = <&usb_phy>;
phy-names = "usb3-phy";
dr_mode = "otg";
maximum-speed = "super-speed";
phy_type = "utmi";
snps,dis-del-phy-power-chg-quirk;
snps,lfps_filter_quirk;
snps,dis_u2_susphy_quirk;
snps,dis_u3_susphy_quirk;
snps,tx_de_emphasis_quirk;
snps,tx_de_emphasis = <1>;
snps,dis_enblslpm_quirk;
snps,gctl-reset-quirk;
usb-role-switch;
role-switch-default-mode = "host";
port {
#address-cells = <1>;
#size-cells = <0>;
dwc3_role_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&hikey_usb_ep0>;
};
dwc3_ss: endpoint@1 {
reg = <1>;
remote-endpoint = <&usb_con_ss>;
};
};
};
};
};

View File

@ -1,4 +1,3 @@
CONFIG_LOCALVERSION="-mainline"
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@ -119,7 +118,6 @@ CONFIG_IPV6_MIP6=y
CONFIG_IPV6_VTI=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NETFILTER=y
# CONFIG_BRIDGE_NETFILTER is not set
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_EVENTS=y
@ -364,15 +362,12 @@ CONFIG_DMADEVICES=y
CONFIG_UIO=y
CONFIG_STAGING=y
CONFIG_ASHMEM=y
CONFIG_ANDROID_VSOC=y
CONFIG_ION=y
CONFIG_ION_SYSTEM_HEAP=y
CONFIG_COMMON_CLK_SCPI=y
CONFIG_HWSPINLOCK=y
CONFIG_MAILBOX=y
CONFIG_ARM_SMMU=y
CONFIG_QCOM_COMMAND_DB=y
CONFIG_QCOM_RPMH=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
CONFIG_DEVFREQ_GOV_POWERSAVE=y
CONFIG_DEVFREQ_GOV_USERSPACE=y

View File

@ -1,4 +1,3 @@
CONFIG_LOCALVERSION="-mainline"
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

View File

@ -0,0 +1,162 @@
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_LAHAINA=y
CONFIG_ARCH_SHIMA=y
CONFIG_HVC_DCC=y
CONFIG_HVC_DCC_SERIALIZE_SMP=y
CONFIG_REGULATOR_STUB=m
CONFIG_REGULATOR_PROXY_CONSUMER=m
CONFIG_PINCTRL_LAHAINA=m
CONFIG_KEYBOARD_GPIO=m
# CONFIG_IKHEADERS is not set
CONFIG_SND_USB_AUDIO_QMI=m
CONFIG_EXTCON=m
CONFIG_SPMI_MSM_PMIC_ARB=m
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=m
CONFIG_SPMI_QTI_GLINK_DEBUG=m
CONFIG_MFD_I2C_PMIC=m
CONFIG_PINCTRL_QCOM_SPMI_PMIC=m
CONFIG_NVMEM_SPMI_SDAM=m
CONFIG_RTC_DRV_PM8XXX=m
CONFIG_QCOM_SPMI_ADC5=m
CONFIG_QCOM_SPMI_TEMP_ALARM=m
CONFIG_INPUT_QPNP_POWER_ON=m
CONFIG_INPUT_QCOM_HV_HAPTICS=m
CONFIG_NOP_USB_XCEIV=m
CONFIG_USB_QCOM_EMU_PHY=m
CONFIG_USB_XHCI_HCD=m
CONFIG_USB_DWC3=m
CONFIG_USB_DWC3_QCOM=m
CONFIG_USB_DWC3_MSM=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
CONFIG_USB_LINK_LAYER_TEST=m
CONFIG_USB_CONFIGFS_NCM=m
CONFIG_USB_CONFIGFS_F_DIAG=m
CONFIG_USB_CONFIGFS_F_CCID=m
CONFIG_USB_CONFIGFS_F_CDEV=m
CONFIG_USB_CONFIGFS_F_GSI=m
CONFIG_USB_CONFIGFS_MASS_STORAGE=m
CONFIG_USB_STORAGE=m
CONFIG_TYPEC=m
CONFIG_TYPEC_UCSI=m
CONFIG_UCSI_QTI_GLINK=m
CONFIG_INTERCONNECT_QCOM=m
CONFIG_INTERCONNECT_QCOM_LAHAINA=m
CONFIG_PHY_QCOM_UFS=m
CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m
CONFIG_PHY_QCOM_UFS_V4=m
CONFIG_SCSI_UFS_QCOM=m
CONFIG_SCSI_UFS_BSG=y
CONFIG_CHR_DEV_SG=m
CONFIG_MSM_CORE_HANG_DETECT=m
CONFIG_PANIC_ON_OOPS=y
CONFIG_QCOM_LLCC=m
CONFIG_QCOM_LAHAINA_LLCC=m
CONFIG_QCOM_IPCC=m
CONFIG_QCOM_WATCHDOG=m
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_SCM=m
CONFIG_QTEE_SHM_BRIDGE=y
# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y
CONFIG_HWSPINLOCK_QCOM=m
CONFIG_QCOM_GLINK_PKT=m
CONFIG_QCOM_SMEM=m
CONFIG_QCOM_SMP2P=m
CONFIG_QCOM_SMSM=m
CONFIG_MSM_QMP=m
CONFIG_QCOM_SMP2P_SLEEPSTATE=m
CONFIG_RPMSG_CHAR=m
CONFIG_RPMSG_QCOM_GLINK_SMEM=m
CONFIG_QCOM_GLINK=m
CONFIG_MSM_GLINK_SSR=m
CONFIG_QTI_PMIC_GLINK=m
CONFIG_QTI_BATTERY_CHARGER=m
CONFIG_QTI_BATTERY_GLINK_DEBUG=m
CONFIG_QTI_ALTMODE_GLINK=m
CONFIG_QRTR_MHI=m
CONFIG_QSEE_IPC_IRQ_BRIDGE=m
CONFIG_SENSORS_SSC=m
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_MSM_SUBSYSTEM_RESTART=m
CONFIG_SETUP_SSR_NOTIF_TIMEOUTS=y
CONFIG_SSR_SYSMON_NOTIF_TIMEOUT=20000
CONFIG_SSR_SUBSYS_NOTIF_TIMEOUT=20000
CONFIG_PANIC_ON_SSR_NOTIF_TIMEOUT=y
CONFIG_MSM_PIL_SSR_GENERIC=m
CONFIG_MSM_SERVICE_LOCATOR=m
CONFIG_MSM_SERVICE_NOTIFIER=m
CONFIG_QSEE_IPC_IRQ=m
CONFIG_RPMSG_QCOM_GLINK_SPSS=m
CONFIG_REGULATOR_RPMH=m
CONFIG_REGULATOR_FIXED_VOLTAGE=m
CONFIG_REGULATOR_QCOM_PM8008=m
CONFIG_MSM_GCC_LAHAINA=m
CONFIG_REGULATOR_REFGEN=m
CONFIG_MSM_VIDEOCC_LAHAINA=m
CONFIG_MSM_DISPCC_LAHAINA=m
CONFIG_COMMON_CLK_QCOM=m
CONFIG_MSM_GPUCC_LAHAINA=m
CONFIG_MSM_GLOBAL_SYNX=m
CONFIG_QRTR=m
CONFIG_QRTR_SMD=m
CONFIG_USB_MSM_SSPHY_QMP=m
CONFIG_MSM_HSUSB_PHY=m
CONFIG_MSM_CAMCC_LAHAINA=m
CONFIG_MSM_BT_POWER=m
CONFIG_ARM_SMMU=m
CONFIG_QTI_IOMMU_SUPPORT=m
CONFIG_MSM_CLK_AOP_QMP=m
CONFIG_MSM_SPSS_UTILS=m
CONFIG_IPA3=m
CONFIG_IPA_WDI_UNIFIED_API=y
CONFIG_CNSS2=m
CONFIG_CNSS2_QMI=y
CONFIG_CNSS_ASYNC=y
CONFIG_BUS_AUTO_SUSPEND=y
CONFIG_CNSS_QCA6490=y
CONFIG_CNSS_UTILS=m
CONFIG_CNSS_GENL=m
CONFIG_WCNSS_MEM_PRE_ALLOC=m
CONFIG_QCOM_SECURE_BUFFER=m
CONFIG_ION_MSM_HEAPS=m
CONFIG_QCOM_CLK_RPMH=m
CONFIG_QCOM_LAZY_MAPPING=m
CONFIG_MFD_SPMI_PMIC=m
CONFIG_PWM_QTI_LPG=m
CONFIG_INTERCONNECT_QCOM_EPSS_L3=m
CONFIG_LEDS_CLASS_FLASH=m
CONFIG_LEDS_QTI_FLASH=m
CONFIG_LEDS_QTI_TRI_LED=m
CONFIG_MSM_SPCOM=m
CONFIG_MSM_ADSPRPC=m
CONFIG_MSM_CDSP_LOADER=m
CONFIG_UIO_MSM_SHAREDMEM=m
CONFIG_QCOM_SOCINFO=m
CONFIG_BTFM_SLIM=m
CONFIG_VIRT_DRIVERS=y
CONFIG_HAVEN_DRIVERS=y
CONFIG_HH_MSGQ=m
CONFIG_HH_RM_DRV=m
CONFIG_HH_DBL=m
CONFIG_HVC_HAVEN=m
# CONFIG_HVC_HAVEN_CONSOLE is not set
# CONFIG_CFI_PERMISSIVE is not set
# CONFIG_SND_SOC_WCD9335 is not set
# CONFIG_SLIM_QCOM_CTRL is not set
# CONFIG_SLIM_QCOM_NGD_CTRL is not set
# CONFIG_SLIMBUS_MSM_CTRL is not set
# CONFIG_SLIMBUS_MSM_NGD is not set
CONFIG_USB_ROLE_SWITCH=m
CONFIG_MHI_BUS=m
CONFIG_MHI_UCI=m
# CONFIG_PCI_MSM is not set
CONFIG_EXTCON_USB_GPIO=m
CONFIG_PM_WAKELOCKS=y
CONFIG_MMC_SDHCI_MSM=m
# CONFIG_MSM_CVP is not set
# CONFIG_QSEECOM is not set
# CONFIG_POWER_RESET_MSM is not set
# CONFIG_MSM_QBT_HANDLER is not set
CONFIG_QCOM_COMMAND_DB=m
CONFIG_QCOM_RPMH=m
CONFIG_QCOM_RPMHPD=m

View File

@ -145,7 +145,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *);
static inline void __flush_icache_all(void)
static __always_inline void __flush_icache_all(void)
{
if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))
return;

View File

@ -64,6 +64,16 @@ static inline unsigned long local_daif_save(void)
return flags;
}
static inline void local_daif_unmask(void)
{
trace_hardirqs_on();
asm volatile(
"msr daifclr, #0xf // local_daif_unmask"
:
:
: "memory");
}
static inline void local_daif_restore(unsigned long flags)
{
bool irq_disabled = flags & PSR_I_BIT;

View File

@ -0,0 +1,223 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014,2016-2019, The Linux Foundation. All rights reserved.
*
*/
#ifndef __ASM_DEBUGV8_H
#define __ASM_DEBUGV8_H
#include <linux/types.h>
/* 32 bit register reads for aarch 64 bit */
#define dbg_readl(reg) RSYSL_##reg()
/* 64 bit register reads for aarch 64 bit */
#define dbg_readq(reg) RSYSQ_##reg()
/* 32 and 64 bit register writes for aarch 64 bit */
#define dbg_write(val, reg) WSYS_##reg(val)
#define MRSL(reg) \
({ \
uint64_t val; \
asm volatile("mrs %0, "#reg : "=r" (val)); \
val; \
})
#define MRSQ(reg) \
({ \
uint64_t val; \
asm volatile("mrs %0, "#reg : "=r" (val)); \
val; \
})
#define MSR(val, reg) \
({ \
asm volatile("msr "#reg", %0" : : "r" (val)); \
})
/*
* Debug Feature Register
*
* Read only
*/
#define RSYSQ_ID_AA64DFR0_EL1() MRSQ(ID_AA64DFR0_EL1)
/*
* Debug Registers
*
* Available only in DBGv8
*
* Read only
* MDCCSR_EL0, MDRAR_EL1, OSLSR_EL1, DBGDTRRX_EL0, DBGAUTHSTATUS_EL1
*
* Write only
* DBGDTRTX_EL0, OSLAR_EL1
*/
/* 32 bit registers */
#define RSYSL_DBGDTRRX_EL0() MRSL(DBGDTRRX_EL0)
#define RSYSL_MDCCSR_EL0() MRSL(MDCCSR_EL0)
#define RSYSL_MDSCR_EL1() MRSL(MDSCR_EL1)
#define RSYSL_OSDTRRX_EL1() MRSL(OSDTRRX_EL1)
#define RSYSL_OSDTRTX_EL1() MRSL(OSDTRTX_EL1)
#define RSYSL_OSDLR_EL1() MRSL(OSDLR_EL1)
#define RSYSL_OSLSR_EL1() MRSL(OSLSR_EL1)
#define RSYSL_MDCCINT_EL1() MRSL(MDCCINT_EL1)
#define RSYSL_OSECCR_EL1() MRSL(OSECCR_EL1)
#define RSYSL_DBGPRCR_EL1() MRSL(DBGPRCR_EL1)
#define RSYSL_DBGBCR0_EL1() MRSL(DBGBCR0_EL1)
#define RSYSL_DBGBCR1_EL1() MRSL(DBGBCR1_EL1)
#define RSYSL_DBGBCR2_EL1() MRSL(DBGBCR2_EL1)
#define RSYSL_DBGBCR3_EL1() MRSL(DBGBCR3_EL1)
#define RSYSL_DBGBCR4_EL1() MRSL(DBGBCR4_EL1)
#define RSYSL_DBGBCR5_EL1() MRSL(DBGBCR5_EL1)
#define RSYSL_DBGBCR6_EL1() MRSL(DBGBCR6_EL1)
#define RSYSL_DBGBCR7_EL1() MRSL(DBGBCR7_EL1)
#define RSYSL_DBGBCR8_EL1() MRSL(DBGBCR8_EL1)
#define RSYSL_DBGBCR9_EL1() MRSL(DBGBCR9_EL1)
#define RSYSL_DBGBCR10_EL1() MRSL(DBGBCR10_EL1)
#define RSYSL_DBGBCR11_EL1() MRSL(DBGBCR11_EL1)
#define RSYSL_DBGBCR12_EL1() MRSL(DBGBCR12_EL1)
#define RSYSL_DBGBCR13_EL1() MRSL(DBGBCR13_EL1)
#define RSYSL_DBGBCR14_EL1() MRSL(DBGBCR14_EL1)
#define RSYSL_DBGBCR15_EL1() MRSL(DBGBCR15_EL1)
#define RSYSL_DBGWCR0_EL1() MRSL(DBGWCR0_EL1)
#define RSYSL_DBGWCR1_EL1() MRSL(DBGWCR1_EL1)
#define RSYSL_DBGWCR2_EL1() MRSL(DBGWCR2_EL1)
#define RSYSL_DBGWCR3_EL1() MRSL(DBGWCR3_EL1)
#define RSYSL_DBGWCR4_EL1() MRSL(DBGWCR4_EL1)
#define RSYSL_DBGWCR5_EL1() MRSL(DBGWCR5_EL1)
#define RSYSL_DBGWCR6_EL1() MRSL(DBGWCR6_EL1)
#define RSYSL_DBGWCR7_EL1() MRSL(DBGWCR7_EL1)
#define RSYSL_DBGWCR8_EL1() MRSL(DBGWCR8_EL1)
#define RSYSL_DBGWCR9_EL1() MRSL(DBGWCR9_EL1)
#define RSYSL_DBGWCR10_EL1() MRSL(DBGWCR10_EL1)
#define RSYSL_DBGWCR11_EL1() MRSL(DBGWCR11_EL1)
#define RSYSL_DBGWCR12_EL1() MRSL(DBGWCR12_EL1)
#define RSYSL_DBGWCR13_EL1() MRSL(DBGWCR13_EL1)
#define RSYSL_DBGWCR14_EL1() MRSL(DBGWCR14_EL1)
#define RSYSL_DBGWCR15_EL1() MRSL(DBGWCR15_EL1)
#define RSYSL_DBGCLAIMSET_EL1() MRSL(DBGCLAIMSET_EL1)
#define RSYSL_DBGCLAIMCLR_EL1() MRSL(DBGCLAIMCLR_EL1)
#define RSYSL_DBGAUTHSTATUS_EL1() MRSL(DBGAUTHSTATUS_EL1)
#define RSYSL_DBGVCR32_EL2() MRSL(DBGVCR32_EL2)
#define RSYSL_MDCR_EL2() MRSL(MDCR_EL2)
#define RSYSL_MDCR_EL3() MRSL(MDCR_EL3)
/* 64 bit registers */
#define RSYSQ_DBGDTR_EL0() MRSQ(DBGDTR_EL0)
#define RSYSQ_MDRAR_EL1() MRSQ(MDRAR_EL1)
#define RSYSQ_DBGBVR0_EL1() MRSQ(DBGBVR0_EL1)
#define RSYSQ_DBGBVR1_EL1() MRSQ(DBGBVR1_EL1)
#define RSYSQ_DBGBVR2_EL1() MRSQ(DBGBVR2_EL1)
#define RSYSQ_DBGBVR3_EL1() MRSQ(DBGBVR3_EL1)
#define RSYSQ_DBGBVR4_EL1() MRSQ(DBGBVR4_EL1)
#define RSYSQ_DBGBVR5_EL1() MRSQ(DBGBVR5_EL1)
#define RSYSQ_DBGBVR6_EL1() MRSQ(DBGBVR6_EL1)
#define RSYSQ_DBGBVR7_EL1() MRSQ(DBGBVR7_EL1)
#define RSYSQ_DBGBVR8_EL1() MRSQ(DBGBVR8_EL1)
#define RSYSQ_DBGBVR9_EL1() MRSQ(DBGBVR9_EL1)
#define RSYSQ_DBGBVR10_EL1() MRSQ(DBGBVR10_EL1)
#define RSYSQ_DBGBVR11_EL1() MRSQ(DBGBVR11_EL1)
#define RSYSQ_DBGBVR12_EL1() MRSQ(DBGBVR12_EL1)
#define RSYSQ_DBGBVR13_EL1() MRSQ(DBGBVR13_EL1)
#define RSYSQ_DBGBVR14_EL1() MRSQ(DBGBVR14_EL1)
#define RSYSQ_DBGBVR15_EL1() MRSQ(DBGBVR15_EL1)
#define RSYSQ_DBGWVR0_EL1() MRSQ(DBGWVR0_EL1)
#define RSYSQ_DBGWVR1_EL1() MRSQ(DBGWVR1_EL1)
#define RSYSQ_DBGWVR2_EL1() MRSQ(DBGWVR2_EL1)
#define RSYSQ_DBGWVR3_EL1() MRSQ(DBGWVR3_EL1)
#define RSYSQ_DBGWVR4_EL1() MRSQ(DBGWVR4_EL1)
#define RSYSQ_DBGWVR5_EL1() MRSQ(DBGWVR5_EL1)
#define RSYSQ_DBGWVR6_EL1() MRSQ(DBGWVR6_EL1)
#define RSYSQ_DBGWVR7_EL1() MRSQ(DBGWVR7_EL1)
#define RSYSQ_DBGWVR8_EL1() MRSQ(DBGWVR8_EL1)
#define RSYSQ_DBGWVR9_EL1() MRSQ(DBGWVR9_EL1)
#define RSYSQ_DBGWVR10_EL1() MRSQ(DBGWVR10_EL1)
#define RSYSQ_DBGWVR11_EL1() MRSQ(DBGWVR11_EL1)
#define RSYSQ_DBGWVR12_EL1() MRSQ(DBGWVR12_EL1)
#define RSYSQ_DBGWVR13_EL1() MRSQ(DBGWVR13_EL1)
#define RSYSQ_DBGWVR14_EL1() MRSQ(DBGWVR14_EL1)
#define RSYSQ_DBGWVR15_EL1() MRSQ(DBGWVR15_EL1)
/* 32 bit registers */
#define WSYS_DBGDTRTX_EL0(val) MSR(val, DBGDTRTX_EL0)
#define WSYS_MDCCINT_EL1(val) MSR(val, MDCCINT_EL1)
#define WSYS_MDSCR_EL1(val) MSR(val, MDSCR_EL1)
#define WSYS_OSDTRRX_EL1(val) MSR(val, OSDTRRX_EL1)
#define WSYS_OSDTRTX_EL1(val) MSR(val, OSDTRTX_EL1)
#define WSYS_OSDLR_EL1(val) MSR(val, OSDLR_EL1)
#define WSYS_OSECCR_EL1(val) MSR(val, OSECCR_EL1)
#define WSYS_DBGPRCR_EL1(val) MSR(val, DBGPRCR_EL1)
#define WSYS_DBGBCR0_EL1(val) MSR(val, DBGBCR0_EL1)
#define WSYS_DBGBCR1_EL1(val) MSR(val, DBGBCR1_EL1)
#define WSYS_DBGBCR2_EL1(val) MSR(val, DBGBCR2_EL1)
#define WSYS_DBGBCR3_EL1(val) MSR(val, DBGBCR3_EL1)
#define WSYS_DBGBCR4_EL1(val) MSR(val, DBGBCR4_EL1)
#define WSYS_DBGBCR5_EL1(val) MSR(val, DBGBCR5_EL1)
#define WSYS_DBGBCR6_EL1(val) MSR(val, DBGBCR6_EL1)
#define WSYS_DBGBCR7_EL1(val) MSR(val, DBGBCR7_EL1)
#define WSYS_DBGBCR8_EL1(val) MSR(val, DBGBCR8_EL1)
#define WSYS_DBGBCR9_EL1(val) MSR(val, DBGBCR9_EL1)
#define WSYS_DBGBCR10_EL1(val) MSR(val, DBGBCR10_EL1)
#define WSYS_DBGBCR11_EL1(val) MSR(val, DBGBCR11_EL1)
#define WSYS_DBGBCR12_EL1(val) MSR(val, DBGBCR12_EL1)
#define WSYS_DBGBCR13_EL1(val) MSR(val, DBGBCR13_EL1)
#define WSYS_DBGBCR14_EL1(val) MSR(val, DBGBCR14_EL1)
#define WSYS_DBGBCR15_EL1(val) MSR(val, DBGBCR15_EL1)
#define WSYS_DBGWCR0_EL1(val) MSR(val, DBGWCR0_EL1)
#define WSYS_DBGWCR1_EL1(val) MSR(val, DBGWCR1_EL1)
#define WSYS_DBGWCR2_EL1(val) MSR(val, DBGWCR2_EL1)
#define WSYS_DBGWCR3_EL1(val) MSR(val, DBGWCR3_EL1)
#define WSYS_DBGWCR4_EL1(val) MSR(val, DBGWCR4_EL1)
#define WSYS_DBGWCR5_EL1(val) MSR(val, DBGWCR5_EL1)
#define WSYS_DBGWCR6_EL1(val) MSR(val, DBGWCR6_EL1)
#define WSYS_DBGWCR7_EL1(val) MSR(val, DBGWCR7_EL1)
#define WSYS_DBGWCR8_EL1(val) MSR(val, DBGWCR8_EL1)
#define WSYS_DBGWCR9_EL1(val) MSR(val, DBGWCR9_EL1)
#define WSYS_DBGWCR10_EL1(val) MSR(val, DBGWCR10_EL1)
#define WSYS_DBGWCR11_EL1(val) MSR(val, DBGWCR11_EL1)
#define WSYS_DBGWCR12_EL1(val) MSR(val, DBGWCR12_EL1)
#define WSYS_DBGWCR13_EL1(val) MSR(val, DBGWCR13_EL1)
#define WSYS_DBGWCR14_EL1(val) MSR(val, DBGWCR14_EL1)
#define WSYS_DBGWCR15_EL1(val) MSR(val, DBGWCR15_EL1)
#define WSYS_DBGCLAIMSET_EL1(val) MSR(val, DBGCLAIMSET_EL1)
#define WSYS_DBGCLAIMCLR_EL1(val) MSR(val, DBGCLAIMCLR_EL1)
#define WSYS_OSLAR_EL1(val) MSR(val, OSLAR_EL1)
#define WSYS_DBGVCR32_EL2(val) MSR(val, DBGVCR32_EL2)
#define WSYS_MDCR_EL2(val) MSR(val, MDCR_EL2)
#define WSYS_MDCR_EL3(val) MSR(val, MDCR_EL3)
/* 64 bit registers */
#define WSYS_DBGDTR_EL0(val) MSR(val, DBGDTR_EL0)
#define WSYS_DBGBVR0_EL1(val) MSR(val, DBGBVR0_EL1)
#define WSYS_DBGBVR1_EL1(val) MSR(val, DBGBVR1_EL1)
#define WSYS_DBGBVR2_EL1(val) MSR(val, DBGBVR2_EL1)
#define WSYS_DBGBVR3_EL1(val) MSR(val, DBGBVR3_EL1)
#define WSYS_DBGBVR4_EL1(val) MSR(val, DBGBVR4_EL1)
#define WSYS_DBGBVR5_EL1(val) MSR(val, DBGBVR5_EL1)
#define WSYS_DBGBVR6_EL1(val) MSR(val, DBGBVR6_EL1)
#define WSYS_DBGBVR7_EL1(val) MSR(val, DBGBVR7_EL1)
#define WSYS_DBGBVR8_EL1(val) MSR(val, DBGBVR8_EL1)
#define WSYS_DBGBVR9_EL1(val) MSR(val, DBGBVR9_EL1)
#define WSYS_DBGBVR10_EL1(val) MSR(val, DBGBVR10_EL1)
#define WSYS_DBGBVR11_EL1(val) MSR(val, DBGBVR11_EL1)
#define WSYS_DBGBVR12_EL1(val) MSR(val, DBGBVR12_EL1)
#define WSYS_DBGBVR13_EL1(val) MSR(val, DBGBVR13_EL1)
#define WSYS_DBGBVR14_EL1(val) MSR(val, DBGBVR14_EL1)
#define WSYS_DBGBVR15_EL1(val) MSR(val, DBGBVR15_EL1)
#define WSYS_DBGWVR0_EL1(val) MSR(val, DBGWVR0_EL1)
#define WSYS_DBGWVR1_EL1(val) MSR(val, DBGWVR1_EL1)
#define WSYS_DBGWVR2_EL1(val) MSR(val, DBGWVR2_EL1)
#define WSYS_DBGWVR3_EL1(val) MSR(val, DBGWVR3_EL1)
#define WSYS_DBGWVR4_EL1(val) MSR(val, DBGWVR4_EL1)
#define WSYS_DBGWVR5_EL1(val) MSR(val, DBGWVR5_EL1)
#define WSYS_DBGWVR6_EL1(val) MSR(val, DBGWVR6_EL1)
#define WSYS_DBGWVR7_EL1(val) MSR(val, DBGWVR7_EL1)
#define WSYS_DBGWVR8_EL1(val) MSR(val, DBGWVR8_EL1)
#define WSYS_DBGWVR9_EL1(val) MSR(val, DBGWVR9_EL1)
#define WSYS_DBGWVR10_EL1(val) MSR(val, DBGWVR10_EL1)
#define WSYS_DBGWVR11_EL1(val) MSR(val, DBGWVR11_EL1)
#define WSYS_DBGWVR12_EL1(val) MSR(val, DBGWVR12_EL1)
#define WSYS_DBGWVR13_EL1(val) MSR(val, DBGWVR13_EL1)
#define WSYS_DBGWVR14_EL1(val) MSR(val, DBGWVR14_EL1)
#define WSYS_DBGWVR15_EL1(val) MSR(val, DBGWVR15_EL1)
#endif

View File

@ -0,0 +1,379 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
*/
#ifndef __ASM_ETMV4X_H
#define __ASM_ETMV4X_H
#include <linux/types.h>
/* 32 bit register reads for AArch64 */
#define trc_readl(reg) RSYSL_##reg()
/* 64 bit register reads for AArch64 */
#define trc_readq(reg) RSYSQ_##reg()
/* 32 and 64 bit register writes for AArch64 */
#define trc_write(val, reg) WSYS_##reg(val)
#define MRSL(op0, op1, crn, crm, op2) \
({ \
uint64_t val; \
asm volatile("mrs %0, S"#op0"_"#op1"_"#crn"_"#crm"_"#op2 : "=r" (val)); \
val; \
})
#define MRSQ(op0, op1, crn, crm, op2) \
({ \
uint64_t val; \
asm volatile("mrs %0, S"#op0"_"#op1"_"#crn"_"#crm"_"#op2 : "=r" (val)); \
val; \
})
#define MSR(val, op0, op1, crn, crm, op2) \
({ \
asm volatile("msr S"#op0"_"#op1"_"#crn"_"#crm"_"#op2", %0" : : "r" (val)); \
})
/* Clock and Power Management Register */
#define RSYSL_CPMR_EL1() MRSL(3, 7, c15, c0, 5)
#define WSYS_CPMR_EL1(val) MSR(val, 3, 7, c15, c0, 5)
/*
* ETMv4 Registers
*
* Read only
* ETMAUTHSTATUS, ETMDEVARCH, ETMDEVID, ETMIDRn[0-13], ETMOSLSR, ETMSTATR
*
* Write only
* ETMOSLAR
*/
/* 32 bit registers */
#define RSYSL_ETMAUTHSTATUS() MRSL(2, 1, c7, c14, 6)
#define RSYSL_ETMAUXCTLR() MRSL(2, 1, c0, c6, 0)
#define RSYSL_ETMCCCTLR() MRSL(2, 1, c0, c14, 0)
#define RSYSL_ETMCIDCCTLR0() MRSL(2, 1, c3, c0, 2)
#define RSYSL_ETMCNTCTLR0() MRSL(2, 1, c0, c4, 5)
#define RSYSL_ETMCNTCTLR1() MRSL(2, 1, c0, c5, 5)
#define RSYSL_ETMCNTCTLR2() MRSL(2, 1, c0, c6, 5)
#define RSYSL_ETMCNTCTLR3() MRSL(2, 1, c0, c7, 5)
#define RSYSL_ETMCNTRLDVR0() MRSL(2, 1, c0, c0, 5)
#define RSYSL_ETMCNTRLDVR1() MRSL(2, 1, c0, c1, 5)
#define RSYSL_ETMCNTRLDVR2() MRSL(2, 1, c0, c2, 5)
#define RSYSL_ETMCNTRLDVR3() MRSL(2, 1, c0, c3, 5)
#define RSYSL_ETMCNTVR0() MRSL(2, 1, c0, c8, 5)
#define RSYSL_ETMCNTVR1() MRSL(2, 1, c0, c9, 5)
#define RSYSL_ETMCNTVR2() MRSL(2, 1, c0, c10, 5)
#define RSYSL_ETMCNTVR3() MRSL(2, 1, c0, c11, 5)
#define RSYSL_ETMCONFIGR() MRSL(2, 1, c0, c4, 0)
#define RSYSL_ETMDEVARCH() MRSL(2, 1, c7, c15, 6)
#define RSYSL_ETMDEVID() MRSL(2, 1, c7, c2, 7)
#define RSYSL_ETMEVENTCTL0R() MRSL(2, 1, c0, c8, 0)
#define RSYSL_ETMEVENTCTL1R() MRSL(2, 1, c0, c9, 0)
#define RSYSL_ETMEXTINSELR() MRSL(2, 1, c0, c8, 4)
#define RSYSL_ETMIDR0() MRSL(2, 1, c0, c8, 7)
#define RSYSL_ETMIDR1() MRSL(2, 1, c0, c9, 7)
#define RSYSL_ETMIDR10() MRSL(2, 1, c0, c2, 6)
#define RSYSL_ETMIDR11() MRSL(2, 1, c0, c3, 6)
#define RSYSL_ETMIDR12() MRSL(2, 1, c0, c4, 6)
#define RSYSL_ETMIDR13() MRSL(2, 1, c0, c5, 6)
#define RSYSL_ETMIDR2() MRSL(2, 1, c0, c10, 7)
#define RSYSL_ETMIDR3() MRSL(2, 1, c0, c11, 7)
#define RSYSL_ETMIDR4() MRSL(2, 1, c0, c12, 7)
#define RSYSL_ETMIDR5() MRSL(2, 1, c0, c13, 7)
#define RSYSL_ETMIDR6() MRSL(2, 1, c0, c14, 7)
#define RSYSL_ETMIDR7() MRSL(2, 1, c0, c15, 7)
#define RSYSL_ETMIDR8() MRSL(2, 1, c0, c0, 6)
#define RSYSL_ETMIDR9() MRSL(2, 1, c0, c1, 6)
#define RSYSL_ETMIMSPEC0() MRSL(2, 1, c0, c0, 7)
#define RSYSL_ETMOSLSR() MRSL(2, 1, c1, c1, 4)
#define RSYSL_ETMPRGCTLR() MRSL(2, 1, c0, c1, 0)
#define RSYSL_ETMRSCTLR10() MRSL(2, 1, c1, c10, 0)
#define RSYSL_ETMRSCTLR11() MRSL(2, 1, c1, c11, 0)
#define RSYSL_ETMRSCTLR12() MRSL(2, 1, c1, c12, 0)
#define RSYSL_ETMRSCTLR13() MRSL(2, 1, c1, c13, 0)
#define RSYSL_ETMRSCTLR14() MRSL(2, 1, c1, c14, 0)
#define RSYSL_ETMRSCTLR15() MRSL(2, 1, c1, c15, 0)
#define RSYSL_ETMRSCTLR2() MRSL(2, 1, c1, c2, 0)
#define RSYSL_ETMRSCTLR3() MRSL(2, 1, c1, c3, 0)
#define RSYSL_ETMRSCTLR4() MRSL(2, 1, c1, c4, 0)
#define RSYSL_ETMRSCTLR5() MRSL(2, 1, c1, c5, 0)
#define RSYSL_ETMRSCTLR6() MRSL(2, 1, c1, c6, 0)
#define RSYSL_ETMRSCTLR7() MRSL(2, 1, c1, c7, 0)
#define RSYSL_ETMRSCTLR8() MRSL(2, 1, c1, c8, 0)
#define RSYSL_ETMRSCTLR9() MRSL(2, 1, c1, c9, 0)
#define RSYSL_ETMRSCTLR16() MRSL(2, 1, c1, c0, 1)
#define RSYSL_ETMRSCTLR17() MRSL(2, 1, c1, c1, 1)
#define RSYSL_ETMRSCTLR18() MRSL(2, 1, c1, c2, 1)
#define RSYSL_ETMRSCTLR19() MRSL(2, 1, c1, c3, 1)
#define RSYSL_ETMRSCTLR20() MRSL(2, 1, c1, c4, 1)
#define RSYSL_ETMRSCTLR21() MRSL(2, 1, c1, c5, 1)
#define RSYSL_ETMRSCTLR22() MRSL(2, 1, c1, c6, 1)
#define RSYSL_ETMRSCTLR23() MRSL(2, 1, c1, c7, 1)
#define RSYSL_ETMRSCTLR24() MRSL(2, 1, c1, c8, 1)
#define RSYSL_ETMRSCTLR25() MRSL(2, 1, c1, c9, 1)
#define RSYSL_ETMRSCTLR26() MRSL(2, 1, c1, c10, 1)
#define RSYSL_ETMRSCTLR27() MRSL(2, 1, c1, c11, 1)
#define RSYSL_ETMRSCTLR28() MRSL(2, 1, c1, c12, 1)
#define RSYSL_ETMRSCTLR29() MRSL(2, 1, c1, c13, 1)
#define RSYSL_ETMRSCTLR30() MRSL(2, 1, c1, c14, 1)
#define RSYSL_ETMRSCTLR31() MRSL(2, 1, c1, c15, 1)
#define RSYSL_ETMSEQEVR0() MRSL(2, 1, c0, c0, 4)
#define RSYSL_ETMSEQEVR1() MRSL(2, 1, c0, c1, 4)
#define RSYSL_ETMSEQEVR2() MRSL(2, 1, c0, c2, 4)
#define RSYSL_ETMSEQRSTEVR() MRSL(2, 1, c0, c6, 4)
#define RSYSL_ETMSEQSTR() MRSL(2, 1, c0, c7, 4)
#define RSYSL_ETMSTALLCTLR() MRSL(2, 1, c0, c11, 0)
#define RSYSL_ETMSTATR() MRSL(2, 1, c0, c3, 0)
#define RSYSL_ETMSYNCPR() MRSL(2, 1, c0, c13, 0)
#define RSYSL_ETMTRACEIDR() MRSL(2, 1, c0, c0, 1)
#define RSYSL_ETMTSCTLR() MRSL(2, 1, c0, c12, 0)
#define RSYSL_ETMVICTLR() MRSL(2, 1, c0, c0, 2)
#define RSYSL_ETMVIIECTLR() MRSL(2, 1, c0, c1, 2)
#define RSYSL_ETMVISSCTLR() MRSL(2, 1, c0, c2, 2)
#define RSYSL_ETMSSCCR0() MRSL(2, 1, c1, c0, 2)
#define RSYSL_ETMSSCCR1() MRSL(2, 1, c1, c1, 2)
#define RSYSL_ETMSSCCR2() MRSL(2, 1, c1, c2, 2)
#define RSYSL_ETMSSCCR3() MRSL(2, 1, c1, c3, 2)
#define RSYSL_ETMSSCCR4() MRSL(2, 1, c1, c4, 2)
#define RSYSL_ETMSSCCR5() MRSL(2, 1, c1, c5, 2)
#define RSYSL_ETMSSCCR6() MRSL(2, 1, c1, c6, 2)
#define RSYSL_ETMSSCCR7() MRSL(2, 1, c1, c7, 2)
#define RSYSL_ETMSSCSR0() MRSL(2, 1, c1, c8, 2)
#define RSYSL_ETMSSCSR1() MRSL(2, 1, c1, c9, 2)
#define RSYSL_ETMSSCSR2() MRSL(2, 1, c1, c10, 2)
#define RSYSL_ETMSSCSR3() MRSL(2, 1, c1, c11, 2)
#define RSYSL_ETMSSCSR4() MRSL(2, 1, c1, c12, 2)
#define RSYSL_ETMSSCSR5() MRSL(2, 1, c1, c13, 2)
#define RSYSL_ETMSSCSR6() MRSL(2, 1, c1, c14, 2)
#define RSYSL_ETMSSCSR7() MRSL(2, 1, c1, c15, 2)
#define RSYSL_ETMSSPCICR0() MRSL(2, 1, c1, c0, 3)
#define RSYSL_ETMSSPCICR1() MRSL(2, 1, c1, c1, 3)
#define RSYSL_ETMSSPCICR2() MRSL(2, 1, c1, c2, 3)
#define RSYSL_ETMSSPCICR3() MRSL(2, 1, c1, c3, 3)
#define RSYSL_ETMSSPCICR4() MRSL(2, 1, c1, c4, 3)
#define RSYSL_ETMSSPCICR5() MRSL(2, 1, c1, c5, 3)
#define RSYSL_ETMSSPCICR6() MRSL(2, 1, c1, c6, 3)
#define RSYSL_ETMSSPCICR7() MRSL(2, 1, c1, c7, 3)
/* 64 bit registers */
#define RSYSQ_ETMACATR0() MRSQ(2, 1, c2, c0, 2)
#define RSYSQ_ETMACATR1() MRSQ(2, 1, c2, c2, 2)
#define RSYSQ_ETMACATR2() MRSQ(2, 1, c2, c4, 2)
#define RSYSQ_ETMACATR3() MRSQ(2, 1, c2, c6, 2)
#define RSYSQ_ETMACATR4() MRSQ(2, 1, c2, c8, 2)
#define RSYSQ_ETMACATR5() MRSQ(2, 1, c2, c10, 2)
#define RSYSQ_ETMACATR6() MRSQ(2, 1, c2, c12, 2)
#define RSYSQ_ETMACATR7() MRSQ(2, 1, c2, c14, 2)
#define RSYSQ_ETMACATR8() MRSQ(2, 1, c2, c0, 3)
#define RSYSQ_ETMACATR9() MRSQ(2, 1, c2, c2, 3)
#define RSYSQ_ETMACATR10() MRSQ(2, 1, c2, c4, 3)
#define RSYSQ_ETMACATR11() MRSQ(2, 1, c2, c6, 3)
#define RSYSQ_ETMACATR12() MRSQ(2, 1, c2, c8, 3)
#define RSYSQ_ETMACATR13() MRSQ(2, 1, c2, c10, 3)
#define RSYSQ_ETMACATR14() MRSQ(2, 1, c2, c12, 3)
#define RSYSQ_ETMACATR15() MRSQ(2, 1, c2, c14, 3)
#define RSYSQ_ETMCIDCVR0() MRSQ(2, 1, c3, c0, 0)
#define RSYSQ_ETMCIDCVR1() MRSQ(2, 1, c3, c2, 0)
#define RSYSQ_ETMCIDCVR2() MRSQ(2, 1, c3, c4, 0)
#define RSYSQ_ETMCIDCVR3() MRSQ(2, 1, c3, c6, 0)
#define RSYSQ_ETMCIDCVR4() MRSQ(2, 1, c3, c8, 0)
#define RSYSQ_ETMCIDCVR5() MRSQ(2, 1, c3, c10, 0)
#define RSYSQ_ETMCIDCVR6() MRSQ(2, 1, c3, c12, 0)
#define RSYSQ_ETMCIDCVR7() MRSQ(2, 1, c3, c14, 0)
#define RSYSQ_ETMACVR0() MRSQ(2, 1, c2, c0, 0)
#define RSYSQ_ETMACVR1() MRSQ(2, 1, c2, c2, 0)
#define RSYSQ_ETMACVR2() MRSQ(2, 1, c2, c4, 0)
#define RSYSQ_ETMACVR3() MRSQ(2, 1, c2, c6, 0)
#define RSYSQ_ETMACVR4() MRSQ(2, 1, c2, c8, 0)
#define RSYSQ_ETMACVR5() MRSQ(2, 1, c2, c10, 0)
#define RSYSQ_ETMACVR6() MRSQ(2, 1, c2, c12, 0)
#define RSYSQ_ETMACVR7() MRSQ(2, 1, c2, c14, 0)
#define RSYSQ_ETMACVR8() MRSQ(2, 1, c2, c0, 1)
#define RSYSQ_ETMACVR9() MRSQ(2, 1, c2, c2, 1)
#define RSYSQ_ETMACVR10() MRSQ(2, 1, c2, c4, 1)
#define RSYSQ_ETMACVR11() MRSQ(2, 1, c2, c6, 1)
#define RSYSQ_ETMACVR12() MRSQ(2, 1, c2, c8, 1)
#define RSYSQ_ETMACVR13() MRSQ(2, 1, c2, c10, 1)
#define RSYSQ_ETMACVR14() MRSQ(2, 1, c2, c12, 1)
#define RSYSQ_ETMACVR15() MRSQ(2, 1, c2, c14, 1)
#define RSYSQ_ETMVMIDCVR0() MRSQ(2, 1, c3, c0, 1)
#define RSYSQ_ETMVMIDCVR1() MRSQ(2, 1, c3, c2, 1)
#define RSYSQ_ETMVMIDCVR2() MRSQ(2, 1, c3, c4, 1)
#define RSYSQ_ETMVMIDCVR3() MRSQ(2, 1, c3, c6, 1)
#define RSYSQ_ETMVMIDCVR4() MRSQ(2, 1, c3, c8, 1)
#define RSYSQ_ETMVMIDCVR5() MRSQ(2, 1, c3, c10, 1)
#define RSYSQ_ETMVMIDCVR6() MRSQ(2, 1, c3, c12, 1)
#define RSYSQ_ETMVMIDCVR7() MRSQ(2, 1, c3, c14, 1)
#define RSYSQ_ETMDVCVR0() MRSQ(2, 1, c2, c0, 4)
#define RSYSQ_ETMDVCVR1() MRSQ(2, 1, c2, c4, 4)
#define RSYSQ_ETMDVCVR2() MRSQ(2, 1, c2, c8, 4)
#define RSYSQ_ETMDVCVR3() MRSQ(2, 1, c2, c12, 4)
#define RSYSQ_ETMDVCVR4() MRSQ(2, 1, c2, c0, 5)
#define RSYSQ_ETMDVCVR5() MRSQ(2, 1, c2, c4, 5)
#define RSYSQ_ETMDVCVR6() MRSQ(2, 1, c2, c8, 5)
#define RSYSQ_ETMDVCVR7() MRSQ(2, 1, c2, c12, 5)
#define RSYSQ_ETMDVCMR0() MRSQ(2, 1, c2, c0, 6)
#define RSYSQ_ETMDVCMR1() MRSQ(2, 1, c2, c4, 6)
#define RSYSQ_ETMDVCMR2() MRSQ(2, 1, c2, c8, 6)
#define RSYSQ_ETMDVCMR3() MRSQ(2, 1, c2, c12, 6)
#define RSYSQ_ETMDVCMR4() MRSQ(2, 1, c2, c0, 7)
#define RSYSQ_ETMDVCMR5() MRSQ(2, 1, c2, c4, 7)
#define RSYSQ_ETMDVCMR6() MRSQ(2, 1, c2, c8, 7)
#define RSYSQ_ETMDVCMR7() MRSQ(2, 1, c2, c12, 7)
/* 32 and 64 bit registers */
#define WSYS_ETMAUXCTLR(val) MSR(val, 2, 1, c0, c6, 0)
#define WSYS_ETMACATR0(val) MSR(val, 2, 1, c2, c0, 2)
#define WSYS_ETMACATR1(val) MSR(val, 2, 1, c2, c2, 2)
#define WSYS_ETMACATR2(val) MSR(val, 2, 1, c2, c4, 2)
#define WSYS_ETMACATR3(val) MSR(val, 2, 1, c2, c6, 2)
#define WSYS_ETMACATR4(val) MSR(val, 2, 1, c2, c8, 2)
#define WSYS_ETMACATR5(val) MSR(val, 2, 1, c2, c10, 2)
#define WSYS_ETMACATR6(val) MSR(val, 2, 1, c2, c12, 2)
#define WSYS_ETMACATR7(val) MSR(val, 2, 1, c2, c14, 2)
#define WSYS_ETMACATR8(val) MSR(val, 2, 1, c2, c0, 3)
#define WSYS_ETMACATR9(val) MSR(val, 2, 1, c2, c2, 3)
#define WSYS_ETMACATR10(val) MSR(val, 2, 1, c2, c4, 3)
#define WSYS_ETMACATR11(val) MSR(val, 2, 1, c2, c6, 3)
#define WSYS_ETMACATR12(val) MSR(val, 2, 1, c2, c8, 3)
#define WSYS_ETMACATR13(val) MSR(val, 2, 1, c2, c10, 3)
#define WSYS_ETMACATR14(val) MSR(val, 2, 1, c2, c12, 3)
#define WSYS_ETMACATR15(val) MSR(val, 2, 1, c2, c14, 3)
#define WSYS_ETMACVR0(val) MSR(val, 2, 1, c2, c0, 0)
#define WSYS_ETMACVR1(val) MSR(val, 2, 1, c2, c2, 0)
#define WSYS_ETMACVR2(val) MSR(val, 2, 1, c2, c4, 0)
#define WSYS_ETMACVR3(val) MSR(val, 2, 1, c2, c6, 0)
#define WSYS_ETMACVR4(val) MSR(val, 2, 1, c2, c8, 0)
#define WSYS_ETMACVR5(val) MSR(val, 2, 1, c2, c10, 0)
#define WSYS_ETMACVR6(val) MSR(val, 2, 1, c2, c12, 0)
#define WSYS_ETMACVR7(val) MSR(val, 2, 1, c2, c14, 0)
#define WSYS_ETMACVR8(val) MSR(val, 2, 1, c2, c0, 1)
#define WSYS_ETMACVR9(val) MSR(val, 2, 1, c2, c2, 1)
#define WSYS_ETMACVR10(val) MSR(val, 2, 1, c2, c4, 1)
#define WSYS_ETMACVR11(val) MSR(val, 2, 1, c2, c6, 1)
#define WSYS_ETMACVR12(val) MSR(val, 2, 1, c2, c8, 1)
#define WSYS_ETMACVR13(val) MSR(val, 2, 1, c2, c10, 1)
#define WSYS_ETMACVR14(val) MSR(val, 2, 1, c2, c12, 1)
#define WSYS_ETMACVR15(val) MSR(val, 2, 1, c2, c14, 1)
#define WSYS_ETMCCCTLR(val) MSR(val, 2, 1, c0, c14, 0)
#define WSYS_ETMCIDCCTLR0(val) MSR(val, 2, 1, c3, c0, 2)
#define WSYS_ETMCIDCVR0(val) MSR(val, 2, 1, c3, c0, 0)
#define WSYS_ETMCIDCVR1(val) MSR(val, 2, 1, c3, c2, 0)
#define WSYS_ETMCIDCVR2(val) MSR(val, 2, 1, c3, c4, 0)
#define WSYS_ETMCIDCVR3(val) MSR(val, 2, 1, c3, c6, 0)
#define WSYS_ETMCIDCVR4(val) MSR(val, 2, 1, c3, c8, 0)
#define WSYS_ETMCIDCVR5(val) MSR(val, 2, 1, c3, c10, 0)
#define WSYS_ETMCIDCVR6(val) MSR(val, 2, 1, c3, c12, 0)
#define WSYS_ETMCIDCVR7(val) MSR(val, 2, 1, c3, c14, 0)
#define WSYS_ETMCNTCTLR0(val) MSR(val, 2, 1, c0, c4, 5)
#define WSYS_ETMCNTCTLR1(val) MSR(val, 2, 1, c0, c5, 5)
#define WSYS_ETMCNTCTLR2(val) MSR(val, 2, 1, c0, c6, 5)
#define WSYS_ETMCNTCTLR3(val) MSR(val, 2, 1, c0, c7, 5)
#define WSYS_ETMCNTRLDVR0(val) MSR(val, 2, 1, c0, c0, 5)
#define WSYS_ETMCNTRLDVR1(val) MSR(val, 2, 1, c0, c1, 5)
#define WSYS_ETMCNTRLDVR2(val) MSR(val, 2, 1, c0, c2, 5)
#define WSYS_ETMCNTRLDVR3(val) MSR(val, 2, 1, c0, c3, 5)
#define WSYS_ETMCNTVR0(val) MSR(val, 2, 1, c0, c8, 5)
#define WSYS_ETMCNTVR1(val) MSR(val, 2, 1, c0, c9, 5)
#define WSYS_ETMCNTVR2(val) MSR(val, 2, 1, c0, c10, 5)
#define WSYS_ETMCNTVR3(val) MSR(val, 2, 1, c0, c11, 5)
#define WSYS_ETMCONFIGR(val) MSR(val, 2, 1, c0, c4, 0)
#define WSYS_ETMEVENTCTL0R(val) MSR(val, 2, 1, c0, c8, 0)
#define WSYS_ETMEVENTCTL1R(val) MSR(val, 2, 1, c0, c9, 0)
#define WSYS_ETMEXTINSELR(val) MSR(val, 2, 1, c0, c8, 4)
#define WSYS_ETMIMSPEC0(val) MSR(val, 2, 1, c0, c0, 7)
#define WSYS_ETMOSLAR(val) MSR(val, 2, 1, c1, c0, 4)
#define WSYS_ETMPRGCTLR(val) MSR(val, 2, 1, c0, c1, 0)
#define WSYS_ETMRSCTLR10(val) MSR(val, 2, 1, c1, c10, 0)
#define WSYS_ETMRSCTLR11(val) MSR(val, 2, 1, c1, c11, 0)
#define WSYS_ETMRSCTLR12(val) MSR(val, 2, 1, c1, c12, 0)
#define WSYS_ETMRSCTLR13(val) MSR(val, 2, 1, c1, c13, 0)
#define WSYS_ETMRSCTLR14(val) MSR(val, 2, 1, c1, c14, 0)
#define WSYS_ETMRSCTLR15(val) MSR(val, 2, 1, c1, c15, 0)
#define WSYS_ETMRSCTLR2(val) MSR(val, 2, 1, c1, c2, 0)
#define WSYS_ETMRSCTLR3(val) MSR(val, 2, 1, c1, c3, 0)
#define WSYS_ETMRSCTLR4(val) MSR(val, 2, 1, c1, c4, 0)
#define WSYS_ETMRSCTLR5(val) MSR(val, 2, 1, c1, c5, 0)
#define WSYS_ETMRSCTLR6(val) MSR(val, 2, 1, c1, c6, 0)
#define WSYS_ETMRSCTLR7(val) MSR(val, 2, 1, c1, c7, 0)
#define WSYS_ETMRSCTLR8(val) MSR(val, 2, 1, c1, c8, 0)
#define WSYS_ETMRSCTLR9(val) MSR(val, 2, 1, c1, c9, 0)
#define WSYS_ETMRSCTLR16(val) MSR(val, 2, 1, c1, c0, 1)
#define WSYS_ETMRSCTLR17(val) MSR(val, 2, 1, c1, c1, 1)
#define WSYS_ETMRSCTLR18(val) MSR(val, 2, 1, c1, c2, 1)
#define WSYS_ETMRSCTLR19(val) MSR(val, 2, 1, c1, c3, 1)
#define WSYS_ETMRSCTLR20(val) MSR(val, 2, 1, c1, c4, 1)
#define WSYS_ETMRSCTLR21(val) MSR(val, 2, 1, c1, c5, 1)
#define WSYS_ETMRSCTLR22(val) MSR(val, 2, 1, c1, c6, 1)
#define WSYS_ETMRSCTLR23(val) MSR(val, 2, 1, c1, c7, 1)
#define WSYS_ETMRSCTLR24(val) MSR(val, 2, 1, c1, c8, 1)
#define WSYS_ETMRSCTLR25(val) MSR(val, 2, 1, c1, c9, 1)
#define WSYS_ETMRSCTLR26(val) MSR(val, 2, 1, c1, c10, 1)
#define WSYS_ETMRSCTLR27(val) MSR(val, 2, 1, c1, c11, 1)
#define WSYS_ETMRSCTLR28(val) MSR(val, 2, 1, c1, c12, 1)
#define WSYS_ETMRSCTLR29(val) MSR(val, 2, 1, c1, c13, 1)
#define WSYS_ETMRSCTLR30(val) MSR(val, 2, 1, c1, c14, 1)
#define WSYS_ETMRSCTLR31(val) MSR(val, 2, 1, c1, c15, 1)
#define WSYS_ETMSEQEVR0(val) MSR(val, 2, 1, c0, c0, 4)
#define WSYS_ETMSEQEVR1(val) MSR(val, 2, 1, c0, c1, 4)
#define WSYS_ETMSEQEVR2(val) MSR(val, 2, 1, c0, c2, 4)
#define WSYS_ETMSEQRSTEVR(val) MSR(val, 2, 1, c0, c6, 4)
#define WSYS_ETMSEQSTR(val) MSR(val, 2, 1, c0, c7, 4)
#define WSYS_ETMSTALLCTLR(val) MSR(val, 2, 1, c0, c11, 0)
#define WSYS_ETMSYNCPR(val) MSR(val, 2, 1, c0, c13, 0)
#define WSYS_ETMTRACEIDR(val) MSR(val, 2, 1, c0, c0, 1)
#define WSYS_ETMTSCTLR(val) MSR(val, 2, 1, c0, c12, 0)
#define WSYS_ETMVICTLR(val) MSR(val, 2, 1, c0, c0, 2)
#define WSYS_ETMVIIECTLR(val) MSR(val, 2, 1, c0, c1, 2)
#define WSYS_ETMVISSCTLR(val) MSR(val, 2, 1, c0, c2, 2)
#define WSYS_ETMVMIDCVR0(val) MSR(val, 2, 1, c3, c0, 1)
#define WSYS_ETMVMIDCVR1(val) MSR(val, 2, 1, c3, c2, 1)
#define WSYS_ETMVMIDCVR2(val) MSR(val, 2, 1, c3, c4, 1)
#define WSYS_ETMVMIDCVR3(val) MSR(val, 2, 1, c3, c6, 1)
#define WSYS_ETMVMIDCVR4(val) MSR(val, 2, 1, c3, c8, 1)
#define WSYS_ETMVMIDCVR5(val) MSR(val, 2, 1, c3, c10, 1)
#define WSYS_ETMVMIDCVR6(val) MSR(val, 2, 1, c3, c12, 1)
#define WSYS_ETMVMIDCVR7(val) MSR(val, 2, 1, c3, c14, 1)
#define WSYS_ETMDVCVR0(val) MSR(val, 2, 1, c2, c0, 4)
#define WSYS_ETMDVCVR1(val) MSR(val, 2, 1, c2, c4, 4)
#define WSYS_ETMDVCVR2(val) MSR(val, 2, 1, c2, c8, 4)
#define WSYS_ETMDVCVR3(val) MSR(val, 2, 1, c2, c12, 4)
#define WSYS_ETMDVCVR4(val) MSR(val, 2, 1, c2, c0, 5)
#define WSYS_ETMDVCVR5(val) MSR(val, 2, 1, c2, c4, 5)
#define WSYS_ETMDVCVR6(val) MSR(val, 2, 1, c2, c8, 5)
#define WSYS_ETMDVCVR7(val) MSR(val, 2, 1, c2, c12, 5)
#define WSYS_ETMDVCMR0(val) MSR(val, 2, 1, c2, c0, 6)
#define WSYS_ETMDVCMR1(val) MSR(val, 2, 1, c2, c4, 6)
#define WSYS_ETMDVCMR2(val) MSR(val, 2, 1, c2, c8, 6)
#define WSYS_ETMDVCMR3(val) MSR(val, 2, 1, c2, c12, 6)
#define WSYS_ETMDVCMR4(val) MSR(val, 2, 1, c2, c0, 7)
#define WSYS_ETMDVCMR5(val) MSR(val, 2, 1, c2, c4, 7)
#define WSYS_ETMDVCMR6(val) MSR(val, 2, 1, c2, c8, 7)
#define WSYS_ETMDVCMR7(val) MSR(val, 2, 1, c2, c12, 7)
#define WSYS_ETMSSCCR0(val) MSR(val, 2, 1, c1, c0, 2)
#define WSYS_ETMSSCCR1(val) MSR(val, 2, 1, c1, c1, 2)
#define WSYS_ETMSSCCR2(val) MSR(val, 2, 1, c1, c2, 2)
#define WSYS_ETMSSCCR3(val) MSR(val, 2, 1, c1, c3, 2)
#define WSYS_ETMSSCCR4(val) MSR(val, 2, 1, c1, c4, 2)
#define WSYS_ETMSSCCR5(val) MSR(val, 2, 1, c1, c5, 2)
#define WSYS_ETMSSCCR6(val) MSR(val, 2, 1, c1, c6, 2)
#define WSYS_ETMSSCCR7(val) MSR(val, 2, 1, c1, c7, 2)
#define WSYS_ETMSSCSR0(val) MSR(val, 2, 1, c1, c8, 2)
#define WSYS_ETMSSCSR1(val) MSR(val, 2, 1, c1, c9, 2)
#define WSYS_ETMSSCSR2(val) MSR(val, 2, 1, c1, c10, 2)
#define WSYS_ETMSSCSR3(val) MSR(val, 2, 1, c1, c11, 2)
#define WSYS_ETMSSCSR4(val) MSR(val, 2, 1, c1, c12, 2)
#define WSYS_ETMSSCSR5(val) MSR(val, 2, 1, c1, c13, 2)
#define WSYS_ETMSSCSR6(val) MSR(val, 2, 1, c1, c14, 2)
#define WSYS_ETMSSCSR7(val) MSR(val, 2, 1, c1, c15, 2)
#define WSYS_ETMSSPCICR0(val) MSR(val, 2, 1, c1, c0, 3)
#define WSYS_ETMSSPCICR1(val) MSR(val, 2, 1, c1, c1, 3)
#define WSYS_ETMSSPCICR2(val) MSR(val, 2, 1, c1, c2, 3)
#define WSYS_ETMSSPCICR3(val) MSR(val, 2, 1, c1, c3, 3)
#define WSYS_ETMSSPCICR4(val) MSR(val, 2, 1, c1, c4, 3)
#define WSYS_ETMSSPCICR5(val) MSR(val, 2, 1, c1, c5, 3)
#define WSYS_ETMSSPCICR6(val) MSR(val, 2, 1, c1, c6, 3)
#define WSYS_ETMSSPCICR7(val) MSR(val, 2, 1, c1, c7, 3)
#endif

View File

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef __ASM_HH_HCALL_H
#define __ASM_HH_HCALL_H
#include <linux/types.h>
#include <linux/haven/hcall_common.h>
/**
* _hh_hcall: Performs an AArch64-specific call into hypervisor using Haven ABI
* @hcall_num: Hypercall function ID to invoke
* @args: Hypercall argument registers
* @resp: Pointer to location to store response
*/
static inline int _hh_hcall(const hh_hcall_fnid_t hcall_num,
const struct hh_hcall_args args,
struct hh_hcall_resp *resp)
{
uint64_t _x18;
register uint64_t _x0 asm("x0") = args.arg0;
register uint64_t _x1 asm("x1") = args.arg1;
register uint64_t _x2 asm("x2") = args.arg2;
register uint64_t _x3 asm("x3") = args.arg3;
register uint64_t _x4 asm("x4") = args.arg4;
register uint64_t _x5 asm("x5") = args.arg5;
register uint64_t _x6 asm("x6") = args.arg6;
register uint64_t _x7 asm("x7") = args.arg7;
asm volatile (
"str x18, [%[_x18]]\n"
"hvc %[num]\n"
"ldr x18, [%[_x18]]\n"
"str xzr, [%[_x18]]\n"
: "+r"(_x0), "+r"(_x1), "+r"(_x2), "+r"(_x3), "+r"(_x4),
"+r"(_x5), "+r"(_x6), "+r"(_x7)
: [num] "i" (hcall_num), [_x18] "r"(&_x18)
: "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",
"memory"
);
resp->resp0 = _x0;
resp->resp1 = _x1;
resp->resp2 = _x2;
resp->resp3 = _x3;
resp->resp4 = _x4;
resp->resp5 = _x5;
resp->resp6 = _x6;
resp->resp7 = _x7;
return _x0;
}
#endif

View File

@ -167,6 +167,7 @@ extern void iounmap(volatile void __iomem *addr);
extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
/*

View File

@ -16,8 +16,10 @@
struct mm_struct;
struct cpu_suspend_ctx;
extern void cpu_cache_off(void);
extern void cpu_do_idle(void);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr);
extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);

View File

@ -7,7 +7,11 @@
#ifdef CONFIG_SPARSEMEM
#define MAX_PHYSMEM_BITS CONFIG_ARM64_PA_BITS
#ifndef CONFIG_MEMORY_HOTPLUG
#define SECTION_SIZE_BITS 30
#else
#define SECTION_SIZE_BITS CONFIG_HOTPLUG_SIZE_BITS
#endif
#endif
#endif

View File

@ -32,8 +32,6 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct mm_struct;
extern void __show_regs(struct pt_regs *);
extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SYSTEM_MISC_H */

View File

@ -17,6 +17,7 @@
#ifndef _UAPI__ASM_SIGCONTEXT_H
#define _UAPI__ASM_SIGCONTEXT_H
#ifdef CONFIG_64BIT
#ifndef __ASSEMBLY__
#include <linux/types.h>
@ -248,5 +249,36 @@ struct sve_context {
#define SVE_SIG_CONTEXT_SIZE(vq) \
(SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
#else /* CONFIG_64BIT */
/*
* Signal context structure - contains all info to do with the state
* before the signal handler was invoked. Note: only add new entries
* to the end of the structure.
*/
struct sigcontext {
unsigned long trap_no;
unsigned long error_code;
unsigned long oldmask;
unsigned long arm_r0;
unsigned long arm_r1;
unsigned long arm_r2;
unsigned long arm_r3;
unsigned long arm_r4;
unsigned long arm_r5;
unsigned long arm_r6;
unsigned long arm_r7;
unsigned long arm_r8;
unsigned long arm_r9;
unsigned long arm_r10;
unsigned long arm_fp;
unsigned long arm_ip;
unsigned long arm_sp;
unsigned long arm_lr;
unsigned long arm_pc;
unsigned long arm_cpsr;
unsigned long fault_address;
};
#endif /* CONFIG_64BIT */
#endif /* _UAPI__ASM_SIGCONTEXT_H */

View File

@ -1171,7 +1171,7 @@ static bool cpu_has_broken_dbm(void)
/* List of CPUs which have broken DBM support. */
static const struct midr_range cpus[] = {
#ifdef CONFIG_ARM64_ERRATUM_1024718
MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 1, 0), // A55 r0p0 -r1p0
MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 2, 0), // A55 r0p0 -r2p0
#endif
{},
};

View File

@ -67,8 +67,6 @@ EXPORT_SYMBOL(__stack_chk_guard);
void (*pm_power_off)(void);
EXPORT_SYMBOL_GPL(pm_power_off);
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
static void __cpu_do_idle(void)
{
dsb(sy);
@ -198,10 +196,7 @@ void machine_restart(char *cmd)
efi_reboot(reboot_mode, NULL);
/* Now call the architecture specific reboot code. */
if (arm_pm_restart)
arm_pm_restart(reboot_mode, cmd);
else
do_kernel_restart(cmd);
do_kernel_restart(cmd);
/*
* Whoops - the architecture was unable to reboot.

View File

@ -976,3 +976,14 @@ void bpf_jit_free_exec(void *addr)
{
return vfree(addr);
}
#ifdef CONFIG_CFI_CLANG
bool arch_bpf_jit_check_func(const struct bpf_prog *prog)
{
const uintptr_t func = (const uintptr_t)prog->bpf_func;
/* bpf_func must be correctly aligned and within the BPF JIT region */
return (func >= BPF_JIT_REGION_START && func < BPF_JIT_REGION_END &&
IS_ALIGNED(func, sizeof(u32)));
}
#endif

View File

@ -645,6 +645,13 @@ static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive,
return -EINVAL;
}
page = gfn_to_page(kvm, gfn);
if (is_error_page(page)) {
srcu_read_unlock(&kvm->srcu, srcu_idx);
pr_err("Couldn't get queue page %llx!\n", kvm_eq.qaddr);
return -EINVAL;
}
qaddr = page_to_virt(page) + (kvm_eq.qaddr & ~PAGE_MASK);
srcu_read_unlock(&kvm->srcu, srcu_idx);

View File

@ -1,4 +1,3 @@
CONFIG_LOCALVERSION="-mainline"
# CONFIG_USELIB is not set
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
@ -49,9 +48,6 @@ CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
CONFIG_NR_CPUS=32
CONFIG_EFI=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_CPU_FREQ_TIMES=y
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
@ -259,6 +255,7 @@ CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_VIRTIO_CONSOLE=m
CONFIG_HW_RANDOM=y
CONFIG_HPET=y
# CONFIG_I2C_COMPAT is not set

View File

@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/init_task.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/desc.h>
#ifdef CONFIG_X86_32
#define DOUBLEFAULT_STACKSIZE (1024)
static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
static void doublefault_fn(void)
{
struct desc_ptr gdt_desc = {0, 0};
unsigned long gdt, tss;
native_store_gdt(&gdt_desc);
gdt = gdt_desc.address;
printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
if (ptr_ok(gdt)) {
gdt += GDT_ENTRY_TSS << 3;
tss = get_desc_base((struct desc_struct *)gdt);
printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
if (ptr_ok(tss)) {
struct x86_hw_tss *t = (struct x86_hw_tss *)tss;
printk(KERN_EMERG "eip = %08lx, esp = %08lx\n",
t->ip, t->sp);
printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
t->ax, t->bx, t->cx, t->dx);
printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
t->si, t->di);
}
}
for (;;)
cpu_relax();
}
struct x86_hw_tss doublefault_tss __cacheline_aligned = {
.sp0 = STACK_START,
.ss0 = __KERNEL_DS,
.ldt = 0,
.io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
.ip = (unsigned long) doublefault_fn,
/* 0x2 bit is always set */
.flags = X86_EFLAGS_SF | 0x2,
.sp = STACK_START,
.es = __USER_DS,
.cs = __KERNEL_CS,
.ss = __KERNEL_DS,
.ds = __USER_DS,
.fs = __KERNEL_PERCPU,
#ifndef CONFIG_X86_32_LAZY_GS
.gs = __KERNEL_STACK_CANARY,
#endif
.__cr3 = __pa_nodebug(swapper_pg_dir),
};
/* dummy for do_double_fault() call */
void df_debug(struct pt_regs *regs, long error_code) {}
#else /* !CONFIG_X86_32 */
void df_debug(struct pt_regs *regs, long error_code)
{
pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
show_regs(regs);
panic("Machine halted.");
}
#endif

View File

@ -1337,6 +1337,8 @@ static u64 kvm_get_arch_capabilities(void)
else if (!boot_cpu_has_bug(X86_BUG_TAA))
data |= ARCH_CAP_TAA_NO;
/* KVM does not emulate MSR_IA32_TSX_CTRL. */
data &= ~ARCH_CAP_TSX_CTRL_MSR;
return data;
}

View File

@ -1,4 +1,3 @@
. ${ROOT_DIR}/common/build.config.common
. ${ROOT_DIR}/common/build.config.aarch64
. ${ROOT_DIR}/common/build.config.gki

View File

@ -133,6 +133,17 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
},
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
},
{
/*
* Medion Akoya E2215T, notification of the LID device only
* happens on close, not on open and _LID always returns closed.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
DMI_MATCH(DMI_PRODUCT_NAME, "E2215T MD60198"),
},
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
},
{}
};

View File

@ -654,7 +654,7 @@ static int binderfs_fill_super(struct super_block *sb, void *data, int silent)
int ret;
struct binderfs_info *info;
struct inode *inode = NULL;
struct binderfs_device device_info = { 0 };
struct binderfs_device device_info = { {0} };
const char *name;
size_t len;

View File

@ -20,6 +20,7 @@
#include <linux/percpu.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/sched.h>
DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
DEFINE_PER_CPU(unsigned long, max_cpu_freq);
@ -219,6 +220,7 @@ init_cpu_capacity_callback(struct notifier_block *nb,
if (cpumask_empty(cpus_to_visit)) {
topology_normalize_cpu_scale();
walt_update_cluster_topology();
schedule_work(&update_topology_flags_work);
free_raw_capacity();
pr_debug("cpu_capacity: parsing done\n");
@ -481,6 +483,26 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
return core_mask;
}
#ifdef CONFIG_SCHED_WALT
void update_possible_siblings_masks(unsigned int cpuid)
{
struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
int cpu;
if (cpuid_topo->package_id == -1)
return;
for_each_possible_cpu(cpu) {
cpu_topo = &cpu_topology[cpu];
if (cpuid_topo->package_id != cpu_topo->package_id)
continue;
cpumask_set_cpu(cpuid, &cpu_topo->core_possible_sibling);
cpumask_set_cpu(cpu, &cpuid_topo->core_possible_sibling);
}
}
#endif
void update_siblings_masks(unsigned int cpuid)
{
struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
@ -560,6 +582,9 @@ __weak int __init parse_acpi_topology(void)
#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
void __init init_cpu_topology(void)
{
#ifdef CONFIG_SCHED_WALT
int cpu;
#endif
reset_cpu_topology();
/*
@ -570,5 +595,11 @@ void __init init_cpu_topology(void)
reset_cpu_topology();
else if (of_have_populated_dt() && parse_dt_topology())
reset_cpu_topology();
#ifdef CONFIG_SCHED_WALT
else {
for_each_possible_cpu(cpu)
update_possible_siblings_masks(cpu);
}
#endif
}
#endif

View File

@ -1156,6 +1156,11 @@ int lock_device_hotplug_sysfs(void)
return restart_syscall();
}
void lock_device_hotplug_assert(void)
{
lockdep_assert_held(&device_hotplug_lock);
}
#ifdef CONFIG_BLOCK
static inline int device_is_not_partition(struct device *dev)
{

View File

@ -183,9 +183,94 @@ static struct attribute_group crash_note_cpu_attr_group = {
};
#endif
#ifdef CONFIG_HOTPLUG_CPU
static ssize_t isolate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct cpu *cpu = container_of(dev, struct cpu, dev);
ssize_t rc;
int cpuid = cpu->dev.id;
unsigned int isolated = cpu_isolated(cpuid);
rc = scnprintf(buf, PAGE_SIZE-2, "%d\n", isolated);
return rc;
}
static DEVICE_ATTR_RO(isolate);
static struct attribute *cpu_isolated_attrs[] = {
&dev_attr_isolate.attr,
NULL
};
static struct attribute_group cpu_isolated_attr_group = {
.attrs = cpu_isolated_attrs,
};
#endif
#ifdef CONFIG_SCHED_WALT
static ssize_t sched_load_boost_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
ssize_t rc;
int boost;
struct cpu *cpu = container_of(dev, struct cpu, dev);
int cpuid = cpu->dev.id;
boost = per_cpu(sched_load_boost, cpuid);
rc = scnprintf(buf, PAGE_SIZE-2, "%d\n", boost);
return rc;
}
static ssize_t __ref sched_load_boost_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int err;
int boost;
struct cpu *cpu = container_of(dev, struct cpu, dev);
int cpuid = cpu->dev.id;
err = kstrtoint(strstrip((char *)buf), 0, &boost);
if (err)
return err;
/*
* -100 is low enough to cancel out CPU's load and make it near zro.
* 1000 is close to the maximum value that cpu_util_freq_{walt,pelt}
* can take without overflow.
*/
if (boost < -100 || boost > 1000)
return -EINVAL;
per_cpu(sched_load_boost, cpuid) = boost;
return count;
}
static DEVICE_ATTR_RW(sched_load_boost);
static struct attribute *sched_cpu_attrs[] = {
&dev_attr_sched_load_boost.attr,
NULL
};
static struct attribute_group sched_cpu_attr_group = {
.attrs = sched_cpu_attrs,
};
#endif
static const struct attribute_group *common_cpu_attr_groups[] = {
#ifdef CONFIG_KEXEC
&crash_note_cpu_attr_group,
#endif
#ifdef CONFIG_HOTPLUG_CPU
&cpu_isolated_attr_group,
#endif
#ifdef CONFIG_SCHED_WALT
&sched_cpu_attr_group,
#endif
NULL
};
@ -193,6 +278,12 @@ static const struct attribute_group *common_cpu_attr_groups[] = {
static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
#ifdef CONFIG_KEXEC
&crash_note_cpu_attr_group,
#endif
#ifdef CONFIG_HOTPLUG_CPU
&cpu_isolated_attr_group,
#endif
#ifdef CONFIG_SCHED_WALT
&sched_cpu_attr_group,
#endif
NULL
};
@ -223,6 +314,7 @@ static struct cpu_attr cpu_attrs[] = {
_CPU_ATTR(online, &__cpu_online_mask),
_CPU_ATTR(possible, &__cpu_possible_mask),
_CPU_ATTR(present, &__cpu_present_mask),
_CPU_ATTR(core_ctl_isolated, &__cpu_isolated_mask),
};
/*
@ -472,6 +564,7 @@ static struct attribute *cpu_root_attrs[] = {
&cpu_attrs[0].attr.attr,
&cpu_attrs[1].attr.attr,
&cpu_attrs[2].attr.attr,
&cpu_attrs[3].attr.attr,
&dev_attr_kernel_max.attr,
&dev_attr_offline.attr,
&dev_attr_isolated.attr,

View File

@ -99,6 +99,12 @@ extern int pm_async_enabled;
/* drivers/base/power/main.c */
extern struct list_head dpm_list; /* The active device list */
#ifdef CONFIG_QCOM_SHOW_RESUME_IRQ
extern int msm_show_resume_irq_mask;
#else
#define msm_show_resume_irq_mask 0
#endif
static inline struct device *to_device(struct list_head *entry)
{
return container_of(entry, struct device, power.entry);

View File

@ -17,6 +17,9 @@
#include <linux/pm_wakeirq.h>
#include <linux/types.h>
#include <trace/events/power.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/irqdesc.h>
#include "power.h"
@ -977,7 +980,21 @@ void pm_wakeup_clear(bool reset)
void pm_system_irq_wakeup(unsigned int irq_number)
{
struct irq_desc *desc;
const char *name = "null";
if (pm_wakeup_irq == 0) {
if (msm_show_resume_irq_mask) {
desc = irq_to_desc(irq_number);
if (desc == NULL)
name = "stray irq";
else if (desc->action && desc->action->name)
name = desc->action->name;
pr_warn("%s: %d triggered %s\n", __func__,
irq_number, name);
}
pm_wakeup_irq = irq_number;
pm_system_wakeup();
}

View File

@ -53,3 +53,20 @@ config REGMAP_SCCB
config REGMAP_I3C
tristate
depends on I3C
config REGMAP_QTI_DEBUG
bool "Regmap QTI debug feature support"
depends on REGMAP && DEBUG_FS && QGKI
help
Say yes to enable QTI debug features. This provides a runtime debugfs
interface to read and write a subset of regmap registers. This
interface is more performant and easier to use than the traditional
method which dumps all registers defined in a given regmap.
config REGMAP_ALLOW_WRITE_DEBUGFS
depends on REGMAP && DEBUG_FS
bool "Allow REGMAP debugfs write"
help
Say 'y' here to allow the regmap debugfs write. Regmap debugfs write
could be risky when accessing some essential hardwares, so it is not
recommended to enable this option on any production device.

View File

@ -84,6 +84,11 @@ struct regmap {
struct list_head debugfs_off_cache;
struct mutex cache_lock;
#ifdef CONFIG_REGMAP_QTI_DEBUG
unsigned int dump_address;
unsigned int dump_count;
#endif
#endif
unsigned int max_register;

View File

@ -288,8 +288,7 @@ static ssize_t regmap_map_read_file(struct file *file, char __user *user_buf,
count, ppos);
}
#undef REGMAP_ALLOW_WRITE_DEBUGFS
#ifdef REGMAP_ALLOW_WRITE_DEBUGFS
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
/*
* This can be dangerous especially when we have clients such as
* PMICs, therefore don't provide any real compile time configuration option
@ -339,6 +338,72 @@ static const struct file_operations regmap_map_fops = {
.llseek = default_llseek,
};
#ifdef CONFIG_REGMAP_QTI_DEBUG
static ssize_t regmap_data_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct regmap *map = file->private_data;
int new_count;
regmap_calc_tot_len(map, NULL, 0);
new_count = map->dump_count * map->debugfs_tot_len;
if (new_count > count)
new_count = count;
if (*ppos == 0)
*ppos = map->dump_address * map->debugfs_tot_len;
else if (*ppos >= map->dump_address * map->debugfs_tot_len
+ map->dump_count * map->debugfs_tot_len)
return 0;
else if (*ppos < map->dump_address * map->debugfs_tot_len)
return 0;
return regmap_read_debugfs(map, 0, map->max_register, user_buf,
new_count, ppos);
}
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
static ssize_t regmap_data_write_file(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
char *start = buf;
unsigned long value;
struct regmap *map = file->private_data;
int ret;
buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
buf[buf_size] = 0;
while (*start == ' ')
start++;
if (kstrtoul(start, 16, &value))
return -EINVAL;
/* Userspace has been fiddling around behind the kernel's back */
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
ret = regmap_write(map, map->dump_address, value);
if (ret < 0)
return ret;
return buf_size;
}
#else
#define regmap_data_write_file NULL
#endif
static const struct file_operations regmap_data_fops = {
.open = simple_open,
.read = regmap_data_read_file,
.write = regmap_data_write_file,
.llseek = default_llseek,
};
#endif
static ssize_t regmap_range_read_file(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@ -598,7 +663,7 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
if (map->max_register || regmap_readable(map, 0)) {
umode_t registers_mode;
#if defined(REGMAP_ALLOW_WRITE_DEBUGFS)
#ifdef CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS
registers_mode = 0600;
#else
registers_mode = 0400;
@ -608,6 +673,16 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
map, &regmap_map_fops);
debugfs_create_file("access", 0400, map->debugfs,
map, &regmap_access_fops);
#ifdef CONFIG_REGMAP_QTI_DEBUG
debugfs_create_x32("address", 0600, map->debugfs,
&map->dump_address);
map->dump_count = 1;
debugfs_create_u32("count", 0600, map->debugfs,
&map->dump_count);
debugfs_create_file("data", registers_mode, map->debugfs,
map, &regmap_data_fops);
#endif
}
if (map->cache_type) {

View File

@ -1362,13 +1362,14 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec,
__GFP_KSWAPD_RECLAIM |
__GFP_NOWARN |
__GFP_HIGHMEM |
__GFP_MOVABLE);
__GFP_MOVABLE |
__GFP_CMA);
if (!handle) {
zcomp_stream_put(zram->comp);
atomic64_inc(&zram->stats.writestall);
handle = zs_malloc(zram->mem_pool, comp_len,
GFP_NOIO | __GFP_HIGHMEM |
__GFP_MOVABLE);
__GFP_MOVABLE | __GFP_CMA);
if (handle)
goto compress_again;
return -ENOMEM;

View File

@ -425,4 +425,30 @@ config BT_HCIRSI
Say Y here to compile support for HCI over Redpine into the
kernel or say M to compile as a module.
config MSM_BT_POWER
tristate "MSM Bluetooth Power Control"
depends on ARCH_QCOM
help
MSM Bluetooth Power control driver.
This provides a parameter to switch on/off power from PMIC
to Bluetooth device. This will control LDOs/Clock/GPIOs to
control Bluetooth Chipset based on power on/off sequence.
Say Y here to compile support for Bluetooth Power driver
into the kernel or say M to compile as a module.
config BTFM_SLIM
tristate "MSM Bluetooth/FM Slimbus Device"
depends on MSM_BT_POWER
select SLIMBUS
help
This enables BT/FM slimbus driver to get multiple audio channel.
This will make use of slimbus platform driver and slimbus
codec driver to communicate with slimbus machine driver and LPSS which
is Slimbus master.Slimbus slave initialization and configuration
will be done through this driver.
Say Y here to compile support for Bluetooth slimbus driver
into the kernel or say M to compile as a module.
endmenu

View File

@ -30,6 +30,12 @@ obj-$(CONFIG_BT_HCIUART_NOKIA) += hci_nokia.o
obj-$(CONFIG_BT_HCIRSI) += btrsi.o
obj-$(CONFIG_MSM_BT_POWER) += btpower.o
bt_fm_slim-objs := btfm_slim.o btfm_slim_codec.o btfm_slim_slave.o
obj-$(CONFIG_BTFM_SLIM) += bt_fm_slim.o
btmrvl-y := btmrvl_main.o
btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o

View File

@ -0,0 +1,616 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/debugfs.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <linux/btpower.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "btfm_slim.h"
#include "btfm_slim_slave.h"
int btfm_slim_write(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *src, uint8_t pgd)
{
int ret, i;
struct slim_ele_access msg;
int slim_write_tries = SLIM_SLAVE_RW_MAX_TRIES;
BTFMSLIM_DBG("Write to %s", pgd?"PGD":"IFD");
msg.start_offset = SLIM_SLAVE_REG_OFFSET + reg;
msg.num_bytes = bytes;
msg.comp = NULL;
for ( ; slim_write_tries != 0; slim_write_tries--) {
mutex_lock(&btfmslim->xfer_lock);
ret = slim_change_val_element(pgd ? btfmslim->slim_pgd :
&btfmslim->slim_ifd, &msg, src, bytes);
mutex_unlock(&btfmslim->xfer_lock);
if (ret == 0)
break;
usleep_range(5000, 5100);
}
if (ret) {
BTFMSLIM_ERR("failed (%d)", ret);
return ret;
}
for (i = 0; i < bytes; i++)
BTFMSLIM_DBG("Write 0x%02x to reg 0x%x", ((uint8_t *)src)[i],
reg + i);
return 0;
}
int btfm_slim_write_pgd(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *src)
{
return btfm_slim_write(btfmslim, reg, bytes, src, PGD);
}
int btfm_slim_write_inf(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *src)
{
return btfm_slim_write(btfmslim, reg, bytes, src, IFD);
}
int btfm_slim_read(struct btfmslim *btfmslim, unsigned short reg,
int bytes, void *dest, uint8_t pgd)
{
int ret, i;
struct slim_ele_access msg;
int slim_read_tries = SLIM_SLAVE_RW_MAX_TRIES;
BTFMSLIM_DBG("Read from %s", pgd?"PGD":"IFD");
msg.start_offset = SLIM_SLAVE_REG_OFFSET + reg;
msg.num_bytes = bytes;
msg.comp = NULL;
for ( ; slim_read_tries != 0; slim_read_tries--) {
mutex_lock(&btfmslim->xfer_lock);
ret = slim_request_val_element(pgd ? btfmslim->slim_pgd :
&btfmslim->slim_ifd, &msg, dest, bytes);
mutex_unlock(&btfmslim->xfer_lock);
if (ret == 0)
break;
usleep_range(5000, 5100);
}
if (ret)
BTFMSLIM_ERR("failed (%d)", ret);
for (i = 0; i < bytes; i++)
BTFMSLIM_DBG("Read 0x%02x from reg 0x%x", ((uint8_t *)dest)[i],
reg + i);
return 0;
}
int btfm_slim_read_pgd(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *dest)
{
return btfm_slim_read(btfmslim, reg, bytes, dest, PGD);
}
int btfm_slim_read_inf(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *dest)
{
return btfm_slim_read(btfmslim, reg, bytes, dest, IFD);
}
int btfm_slim_enable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
uint8_t rxport, uint32_t rates, uint8_t grp, uint8_t nchan)
{
int ret, i;
struct slim_ch prop;
struct btfmslim_ch *chan = ch;
uint16_t ch_h[2];
if (!btfmslim || !ch)
return -EINVAL;
BTFMSLIM_DBG("port: %d ch: %d", ch->port, ch->ch);
/* Define the channel with below parameters */
prop.prot = ((rates == 44100) || (rates == 88200)) ?
SLIM_PUSH : SLIM_AUTO_ISO;
prop.baser = ((rates == 44100) || (rates == 88200)) ?
SLIM_RATE_11025HZ : SLIM_RATE_4000HZ;
prop.dataf = ((rates == 48000) || (rates == 44100) ||
(rates == 88200) || (rates == 96000)) ?
SLIM_CH_DATAF_NOT_DEFINED : SLIM_CH_DATAF_LPCM_AUDIO;
/* for feedback channel, PCM bit should not be set */
if (btfm_feedback_ch_setting) {
BTFMSLIM_DBG("port open for feedback ch, not setting PCM bit");
prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
/* reset so that next port open sets the data format properly */
btfm_feedback_ch_setting = 0;
}
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.ratem = ((rates == 44100) || (rates == 88200)) ?
(rates/11025) : (rates/4000);
prop.sampleszbits = 16;
ch_h[0] = ch->ch_hdl;
ch_h[1] = (grp) ? (ch+1)->ch_hdl : 0;
BTFMSLIM_INFO("channel define - prot:%d, dataf:%d, auxf:%d",
prop.prot, prop.dataf, prop.auxf);
BTFMSLIM_INFO("channel define - rates:%d, baser:%d, ratem:%d",
rates, prop.baser, prop.ratem);
ret = slim_define_ch(btfmslim->slim_pgd, &prop, ch_h, nchan, grp,
&ch->grph);
if (ret < 0) {
BTFMSLIM_ERR("slim_define_ch failed ret[%d]", ret);
goto error;
}
for (i = 0; i < nchan; i++, ch++) {
/* Enable port through registration setting */
if (btfmslim->vendor_port_en) {
ret = btfmslim->vendor_port_en(btfmslim, ch->port,
rxport, 1);
if (ret < 0) {
BTFMSLIM_ERR("vendor_port_en failed ret[%d]",
ret);
goto error;
}
}
if (rxport) {
BTFMSLIM_INFO("slim_connect_sink(port: %d, ch: %d)",
ch->port, ch->ch);
/* Connect Port with channel given by Machine driver*/
ret = slim_connect_sink(btfmslim->slim_pgd,
&ch->port_hdl, 1, ch->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_connect_sink failed ret[%d]",
ret);
goto remove_channel;
}
} else {
BTFMSLIM_INFO("slim_connect_src(port: %d, ch: %d)",
ch->port, ch->ch);
/* Connect Port with channel given by Machine driver*/
ret = slim_connect_src(btfmslim->slim_pgd, ch->port_hdl,
ch->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_connect_src failed ret[%d]",
ret);
goto remove_channel;
}
}
}
/* Activate the channel immediately */
BTFMSLIM_INFO(
"port: %d, ch: %d, grp: %d, ch->grph: 0x%x, ch_hdl: 0x%x",
chan->port, chan->ch, grp, chan->grph, chan->ch_hdl);
ret = slim_control_ch(btfmslim->slim_pgd, (grp ? chan->grph :
chan->ch_hdl), SLIM_CH_ACTIVATE, true);
if (ret < 0) {
BTFMSLIM_ERR("slim_control_ch failed ret[%d]", ret);
goto remove_channel;
}
error:
return ret;
remove_channel:
/* Remove the channel immediately*/
ret = slim_control_ch(btfmslim->slim_pgd, (grp ? ch->grph : ch->ch_hdl),
SLIM_CH_REMOVE, true);
if (ret < 0)
BTFMSLIM_ERR("slim_control_ch failed ret[%d]", ret);
return ret;
}
int btfm_slim_disable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
uint8_t rxport, uint8_t grp, uint8_t nchan)
{
int ret, i;
if (!btfmslim || !ch)
return -EINVAL;
BTFMSLIM_INFO("port:%d, grp: %d, ch->grph:0x%x, ch->ch_hdl:0x%x ",
ch->port, grp, ch->grph, ch->ch_hdl);
/* For 44.1/88.2 Khz A2DP Rx, disconnect the port first */
if (rxport &&
(btfmslim->sample_rate == 44100 ||
btfmslim->sample_rate == 88200)) {
BTFMSLIM_DBG("disconnecting the ports, removing the channel");
ret = slim_disconnect_ports(btfmslim->slim_pgd,
&ch->port_hdl, 1);
if (ret < 0) {
BTFMSLIM_ERR("slim_disconnect_ports failed ret[%d]",
ret);
}
}
/* Remove the channel immediately*/
ret = slim_control_ch(btfmslim->slim_pgd, (grp ? ch->grph : ch->ch_hdl),
SLIM_CH_REMOVE, true);
if (ret < 0) {
BTFMSLIM_ERR("slim_control_ch failed ret[%d]", ret);
if (btfmslim->sample_rate != 44100 &&
btfmslim->sample_rate != 88200) {
ret = slim_disconnect_ports(btfmslim->slim_pgd,
&ch->port_hdl, 1);
if (ret < 0) {
BTFMSLIM_ERR("disconnect_ports failed ret[%d]",
ret);
goto error;
}
}
}
/* Disable port through registration setting */
for (i = 0; i < nchan; i++, ch++) {
if (btfmslim->vendor_port_en) {
ret = btfmslim->vendor_port_en(btfmslim, ch->port,
rxport, 0);
if (ret < 0) {
BTFMSLIM_ERR("vendor_port_en failed ret[%d]",
ret);
break;
}
}
}
error:
return ret;
}
static int btfm_slim_get_logical_addr(struct slim_device *slim)
{
int ret = 0;
const unsigned long timeout = jiffies +
msecs_to_jiffies(SLIM_SLAVE_PRESENT_TIMEOUT);
do {
ret = slim_get_logical_addr(slim, slim->e_addr,
ARRAY_SIZE(slim->e_addr), &slim->laddr);
if (!ret) {
BTFMSLIM_DBG("Assigned l-addr: 0x%x", slim->laddr);
break;
}
/* Give SLIMBUS time to report present and be ready. */
usleep_range(1000, 1100);
BTFMSLIM_DBG("retyring get logical addr");
} while (time_before(jiffies, timeout));
return ret;
}
static int btfm_slim_alloc_port(struct btfmslim *btfmslim)
{
int ret = -EINVAL, i;
int chipset_ver;
struct btfmslim_ch *rx_chs;
struct btfmslim_ch *tx_chs;
if (!btfmslim)
return ret;
chipset_ver = btpower_get_chipset_version();
BTFMSLIM_INFO("chipset soc version:%x", chipset_ver);
rx_chs = btfmslim->rx_chs;
tx_chs = btfmslim->tx_chs;
if ((chipset_ver >= QCA_CHEROKEE_SOC_ID_0310) &&
(chipset_ver <= QCA_CHEROKEE_SOC_ID_0320_UMC)) {
for (i = 0; (tx_chs->port != BTFM_SLIM_PGD_PORT_LAST) &&
(i < BTFM_SLIM_NUM_CODEC_DAIS); i++, tx_chs++) {
if (tx_chs->port == SLAVE_SB_PGD_PORT_TX1_FM)
tx_chs->port = CHRKVER3_SB_PGD_PORT_TX1_FM;
else if (tx_chs->port == SLAVE_SB_PGD_PORT_TX2_FM)
tx_chs->port = CHRKVER3_SB_PGD_PORT_TX2_FM;
BTFMSLIM_INFO("Tx port:%d", tx_chs->port);
}
tx_chs = btfmslim->tx_chs;
}
if (!rx_chs || !tx_chs)
return ret;
BTFMSLIM_DBG("Rx: id\tname\tport\thdl\tch\tch_hdl");
for (i = 0 ; (rx_chs->port != BTFM_SLIM_PGD_PORT_LAST) &&
(i < BTFM_SLIM_NUM_CODEC_DAIS); i++, rx_chs++) {
/* Get Rx port handler from slimbus driver based
* on port number
*/
ret = slim_get_slaveport(btfmslim->slim_pgd->laddr,
rx_chs->port, &rx_chs->port_hdl, SLIM_SINK);
if (ret < 0) {
BTFMSLIM_ERR("slave port failure port#%d - ret[%d]",
rx_chs->port, SLIM_SINK);
return ret;
}
BTFMSLIM_DBG(" %d\t%s\t%d\t%x\t%d\t%x", rx_chs->id,
rx_chs->name, rx_chs->port, rx_chs->port_hdl,
rx_chs->ch, rx_chs->ch_hdl);
}
BTFMSLIM_DBG("Tx: id\tname\tport\thdl\tch\tch_hdl");
for (i = 0; (tx_chs->port != BTFM_SLIM_PGD_PORT_LAST) &&
(i < BTFM_SLIM_NUM_CODEC_DAIS); i++, tx_chs++) {
/* Get Tx port handler from slimbus driver based
* on port number
*/
ret = slim_get_slaveport(btfmslim->slim_pgd->laddr,
tx_chs->port, &tx_chs->port_hdl, SLIM_SRC);
if (ret < 0) {
BTFMSLIM_ERR("slave port failure port#%d - ret[%d]",
tx_chs->port, SLIM_SRC);
return ret;
}
BTFMSLIM_DBG(" %d\t%s\t%d\t%x\t%d\t%x", tx_chs->id,
tx_chs->name, tx_chs->port, tx_chs->port_hdl,
tx_chs->ch, tx_chs->ch_hdl);
}
return ret;
}
int btfm_slim_hw_init(struct btfmslim *btfmslim)
{
int ret;
BTFMSLIM_DBG("");
if (!btfmslim)
return -EINVAL;
if (btfmslim->enabled) {
BTFMSLIM_DBG("Already enabled");
return 0;
}
mutex_lock(&btfmslim->io_lock);
/* Assign Logical Address for PGD (Ported Generic Device)
* enumeration address
*/
ret = btfm_slim_get_logical_addr(btfmslim->slim_pgd);
if (ret) {
BTFMSLIM_ERR("failed to get slimbus %s logical address: %d",
btfmslim->slim_pgd->name, ret);
goto error;
}
/* Assign Logical Address for Ported Generic Device
* enumeration address
*/
ret = btfm_slim_get_logical_addr(&btfmslim->slim_ifd);
if (ret) {
BTFMSLIM_ERR("failed to get slimbus %s logical address: %d",
btfmslim->slim_ifd.name, ret);
goto error;
}
/* Allocate ports with logical address to get port handler from
* slimbus driver
*/
ret = btfm_slim_alloc_port(btfmslim);
if (ret)
goto error;
/* Start vendor specific initialization and get port information */
if (btfmslim->vendor_init)
ret = btfmslim->vendor_init(btfmslim);
/* Only when all registers read/write successfully, it set to
* enabled status
*/
btfmslim->enabled = 1;
error:
mutex_unlock(&btfmslim->io_lock);
return ret;
}
int btfm_slim_hw_deinit(struct btfmslim *btfmslim)
{
int ret = 0;
if (!btfmslim)
return -EINVAL;
if (!btfmslim->enabled) {
BTFMSLIM_DBG("Already disabled");
return 0;
}
mutex_lock(&btfmslim->io_lock);
btfmslim->enabled = 0;
mutex_unlock(&btfmslim->io_lock);
return ret;
}
static int btfm_slim_get_dt_info(struct btfmslim *btfmslim)
{
int ret = 0;
struct slim_device *slim = btfmslim->slim_pgd;
struct slim_device *slim_ifd = &btfmslim->slim_ifd;
struct property *prop;
if (!slim || !slim_ifd)
return -EINVAL;
if (slim->dev.of_node) {
BTFMSLIM_DBG("Platform data from device tree (%s)",
slim->name);
ret = of_property_read_string(slim->dev.of_node,
"qcom,btfm-slim-ifd", &slim_ifd->name);
if (ret) {
BTFMSLIM_ERR("Looking up %s property in node %s failed",
"qcom,btfm-slim-ifd",
slim->dev.of_node->full_name);
return -ENODEV;
}
BTFMSLIM_DBG("qcom,btfm-slim-ifd (%s)", slim_ifd->name);
prop = of_find_property(slim->dev.of_node,
"qcom,btfm-slim-ifd-elemental-addr", NULL);
if (!prop) {
BTFMSLIM_ERR("Looking up %s property in node %s failed",
"qcom,btfm-slim-ifd-elemental-addr",
slim->dev.of_node->full_name);
return -ENODEV;
} else if (prop->length != 6) {
BTFMSLIM_ERR(
"invalid codec slim ifd addr. addr length= %d",
prop->length);
return -ENODEV;
}
memcpy(slim_ifd->e_addr, prop->value, 6);
BTFMSLIM_DBG(
"PGD Enum Addr: %.02x:%.02x:%.02x:%.02x:%.02x: %.02x",
slim->e_addr[0], slim->e_addr[1], slim->e_addr[2],
slim->e_addr[3], slim->e_addr[4], slim->e_addr[5]);
BTFMSLIM_DBG(
"IFD Enum Addr: %.02x:%.02x:%.02x:%.02x:%.02x: %.02x",
slim_ifd->e_addr[0], slim_ifd->e_addr[1],
slim_ifd->e_addr[2], slim_ifd->e_addr[3],
slim_ifd->e_addr[4], slim_ifd->e_addr[5]);
} else {
BTFMSLIM_ERR("Platform data is not valid");
}
return ret;
}
static int btfm_slim_probe(struct slim_device *slim)
{
int ret = 0;
struct btfmslim *btfm_slim;
BTFMSLIM_DBG("");
if (!slim->ctrl)
return -EINVAL;
/* Allocation btfmslim data pointer */
btfm_slim = kzalloc(sizeof(struct btfmslim), GFP_KERNEL);
if (btfm_slim == NULL) {
BTFMSLIM_ERR("error, allocation failed");
return -ENOMEM;
}
/* BTFM Slimbus driver control data configuration */
btfm_slim->slim_pgd = slim;
/* Assign vendor specific function */
btfm_slim->rx_chs = SLIM_SLAVE_RXPORT;
btfm_slim->tx_chs = SLIM_SLAVE_TXPORT;
btfm_slim->vendor_init = SLIM_SLAVE_INIT;
btfm_slim->vendor_port_en = SLIM_SLAVE_PORT_EN;
/* Created Mutex for slimbus data transfer */
mutex_init(&btfm_slim->io_lock);
mutex_init(&btfm_slim->xfer_lock);
/* Get Device tree node for Interface Device enumeration address */
ret = btfm_slim_get_dt_info(btfm_slim);
if (ret)
goto dealloc;
/* Add Interface Device for slimbus driver */
ret = slim_add_device(btfm_slim->slim_pgd->ctrl, &btfm_slim->slim_ifd);
if (ret) {
BTFMSLIM_ERR("error, adding SLIMBUS device failed");
goto dealloc;
}
/* Platform driver data allocation */
slim->dev.platform_data = btfm_slim;
/* Driver specific data allocation */
btfm_slim->dev = &slim->dev;
ret = btfm_slim_register_codec(&slim->dev);
if (ret) {
BTFMSLIM_ERR("error, registering slimbus codec failed");
goto free;
}
ret = btpower_register_slimdev(&slim->dev);
if (ret < 0) {
btfm_slim_unregister_codec(&slim->dev);
goto free;
}
return ret;
free:
slim_remove_device(&btfm_slim->slim_ifd);
dealloc:
mutex_destroy(&btfm_slim->io_lock);
mutex_destroy(&btfm_slim->xfer_lock);
kfree(btfm_slim);
return ret;
}
static int btfm_slim_remove(struct slim_device *slim)
{
struct btfmslim *btfm_slim = slim->dev.platform_data;
BTFMSLIM_DBG("");
mutex_destroy(&btfm_slim->io_lock);
mutex_destroy(&btfm_slim->xfer_lock);
snd_soc_unregister_component(&slim->dev);
BTFMSLIM_DBG("slim_remove_device() - btfm_slim->slim_ifd");
slim_remove_device(&btfm_slim->slim_ifd);
kfree(btfm_slim);
BTFMSLIM_DBG("slim_remove_device() - btfm_slim->slim_pgd");
slim_remove_device(slim);
return 0;
}
static const struct slim_device_id btfm_slim_id[] = {
{SLIM_SLAVE_COMPATIBLE_STR, 0},
{}
};
static struct slim_driver btfm_slim_driver = {
.driver = {
.name = "btfmslim-driver",
.owner = THIS_MODULE,
},
.probe = btfm_slim_probe,
.remove = btfm_slim_remove,
.id_table = btfm_slim_id
};
static int __init btfm_slim_init(void)
{
int ret;
BTFMSLIM_DBG("");
ret = slim_driver_register(&btfm_slim_driver);
if (ret)
BTFMSLIM_ERR("Failed to register slimbus driver: %d", ret);
return ret;
}
static void __exit btfm_slim_exit(void)
{
BTFMSLIM_DBG("");
slim_driver_unregister(&btfm_slim_driver);
}
module_init(btfm_slim_init);
module_exit(btfm_slim_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("BTFM Slimbus Slave driver");

View File

@ -0,0 +1,169 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#ifndef BTFM_SLIM_H
#define BTFM_SLIM_H
#include <linux/slimbus/slimbus.h>
#define BTFMSLIM_DBG(fmt, arg...) pr_debug("%s: " fmt "\n", __func__, ## arg)
#define BTFMSLIM_INFO(fmt, arg...) pr_info("%s: " fmt "\n", __func__, ## arg)
#define BTFMSLIM_ERR(fmt, arg...) pr_err("%s: " fmt "\n", __func__, ## arg)
/* Vendor specific defines
* This should redefines in slimbus slave specific header
*/
#define SLIM_SLAVE_COMPATIBLE_STR "btfmslim_slave"
#define SLIM_SLAVE_REG_OFFSET 0x0000
#define SLIM_SLAVE_RXPORT NULL
#define SLIM_SLAVE_TXPORT NULL
#define SLIM_SLAVE_INIT NULL
#define SLIM_SLAVE_PORT_EN NULL
/* Misc defines */
#define SLIM_SLAVE_RW_MAX_TRIES 3
#define SLIM_SLAVE_PRESENT_TIMEOUT 100
#define PGD 1
#define IFD 0
/* Codec driver defines */
enum {
BTFM_FM_SLIM_TX = 0,
BTFM_BT_SCO_SLIM_TX,
BTFM_BT_SCO_A2DP_SLIM_RX,
BTFM_BT_SPLIT_A2DP_SLIM_RX,
BTFM_SLIM_NUM_CODEC_DAIS
};
/* Slimbus Port defines - This should be redefined in specific device file */
#define BTFM_SLIM_PGD_PORT_LAST 0xFF
struct btfmslim_ch {
int id;
char *name;
uint32_t port_hdl; /* slimbus port handler */
uint16_t port; /* slimbus port number */
uint8_t ch; /* slimbus channel number */
uint16_t ch_hdl; /* slimbus channel handler */
uint16_t grph; /* slimbus group channel handler */
};
struct btfmslim {
struct device *dev;
struct slim_device *slim_pgd;
struct slim_device slim_ifd;
struct mutex io_lock;
struct mutex xfer_lock;
uint8_t enabled;
uint32_t num_rx_port;
uint32_t num_tx_port;
uint32_t sample_rate;
struct btfmslim_ch *rx_chs;
struct btfmslim_ch *tx_chs;
int (*vendor_init)(struct btfmslim *btfmslim);
int (*vendor_port_en)(struct btfmslim *btfmslim, uint8_t port_num,
uint8_t rxport, uint8_t enable);
};
extern int btfm_feedback_ch_setting;
/**
* btfm_slim_hw_init: Initialize slimbus slave device
* Returns:
* 0: Success
* else: Fail
*/
int btfm_slim_hw_init(struct btfmslim *btfmslim);
/**
* btfm_slim_hw_deinit: Deinitialize slimbus slave device
* Returns:
* 0: Success
* else: Fail
*/
int btfm_slim_hw_deinit(struct btfmslim *btfmslim);
/**
* btfm_slim_write: write value to pgd or ifd device
* @btfmslim: slimbus slave device data pointer.
* @reg: slimbus slave register address
* @bytes: length of data
* @src: data pointer to write
* @pgd: selection for device: either PGD or IFD
* Returns:
* -EINVAL
* -ETIMEDOUT
* -ENOMEM
*/
int btfm_slim_write(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *src, uint8_t pgd);
/**
* btfm_slim_read: read value from pgd or ifd device
* @btfmslim: slimbus slave device data pointer.
* @reg: slimbus slave register address
* @bytes: length of data
* @dest: data pointer to read
* @pgd: selection for device: either PGD or IFD
* Returns:
* -EINVAL
* -ETIMEDOUT
* -ENOMEM
*/
int btfm_slim_read(struct btfmslim *btfmslim,
uint16_t reg, int bytes, void *dest, uint8_t pgd);
/**
* btfm_slim_enable_ch: enable channel for slimbus slave port
* @btfmslim: slimbus slave device data pointer.
* @ch: slimbus slave channel pointer
* @rxport: rxport or txport
* Returns:
* -EINVAL
* -ETIMEDOUT
* -ENOMEM
*/
int btfm_slim_enable_ch(struct btfmslim *btfmslim,
struct btfmslim_ch *ch, uint8_t rxport, uint32_t rates,
uint8_t grp, uint8_t nchan);
/**
* btfm_slim_disable_ch: disable channel for slimbus slave port
* @btfmslim: slimbus slave device data pointer.
* @ch: slimbus slave channel pointer
* @rxport: rxport or txport
* Returns:
* -EINVAL
* -ETIMEDOUT
* -ENOMEM
*/
int btfm_slim_disable_ch(struct btfmslim *btfmslim,
struct btfmslim_ch *ch, uint8_t rxport, uint8_t grp, uint8_t nchan);
/**
* btfm_slim_register_codec: Register codec driver in slimbus device node
* @dev: device node
* Returns:
* -ENOMEM
* 0
*/
int btfm_slim_register_codec(struct device *dev);
/**
* btfm_slim_unregister_codec: Unregister codec driver in slimbus device node
* @dev: device node
* Returns:
* VOID
*/
void btfm_slim_unregister_codec(struct device *dev);
#endif /* BTFM_SLIM_H */

View File

@ -0,0 +1,459 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/debugfs.h>
#include <linux/slimbus/slimbus.h>
#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "btfm_slim.h"
static int bt_soc_enable_status;
int btfm_feedback_ch_setting;
static int btfm_slim_codec_write(struct snd_soc_component *codec,
unsigned int reg, unsigned int value)
{
return 0;
}
static unsigned int btfm_slim_codec_read(struct snd_soc_component *codec,
unsigned int reg)
{
return 0;
}
static int bt_soc_status_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = bt_soc_enable_status;
return 1;
}
static int bt_soc_status_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
return 1;
}
static int btfm_get_feedback_ch_setting(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = btfm_feedback_ch_setting;
return 1;
}
static int btfm_put_feedback_ch_setting(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
btfm_feedback_ch_setting = ucontrol->value.integer.value[0];
return 1;
}
static const struct snd_kcontrol_new status_controls[] = {
SOC_SINGLE_EXT("BT SOC status", 0, 0, 1, 0,
bt_soc_status_get,
bt_soc_status_put),
SOC_SINGLE_EXT("BT set feedback channel", 0, 0, 1, 0,
btfm_get_feedback_ch_setting,
btfm_put_feedback_ch_setting)
};
static int btfm_slim_codec_probe(struct snd_soc_component *codec)
{
snd_soc_add_component_controls(codec, status_controls,
ARRAY_SIZE(status_controls));
return 0;
}
static void btfm_slim_codec_remove(struct snd_soc_component *codec)
{
}
static int btfm_slim_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int ret;
struct btfmslim *btfmslim = dai->dev->platform_data;
BTFMSLIM_DBG("substream = %s stream = %d dai->name = %s",
substream->name, substream->stream, dai->name);
ret = btfm_slim_hw_init(btfmslim);
return ret;
}
static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int i;
struct btfmslim *btfmslim = dai->dev->platform_data;
struct btfmslim_ch *ch;
uint8_t rxport, grp = false, nchan = 1;
BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
dai->id, dai->rate);
switch (dai->id) {
case BTFM_FM_SLIM_TX:
grp = true; nchan = 2;
ch = btfmslim->tx_chs;
rxport = 0;
break;
case BTFM_BT_SCO_SLIM_TX:
ch = btfmslim->tx_chs;
rxport = 0;
break;
case BTFM_BT_SCO_A2DP_SLIM_RX:
case BTFM_BT_SPLIT_A2DP_SLIM_RX:
ch = btfmslim->rx_chs;
rxport = 1;
break;
case BTFM_SLIM_NUM_CODEC_DAIS:
default:
BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
return;
}
/* Search for dai->id matched port handler */
for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != dai->id); ch++, i++)
;
if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
(ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
BTFMSLIM_ERR("ch is invalid!!");
return;
}
btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
btfm_slim_hw_deinit(btfmslim);
}
static int btfm_slim_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
BTFMSLIM_DBG("dai->name = %s DAI-ID %x rate %d num_ch %d",
dai->name, dai->id, params_rate(params),
params_channels(params));
return 0;
}
static int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int i, ret = -EINVAL;
struct btfmslim *btfmslim = dai->dev->platform_data;
struct btfmslim_ch *ch;
uint8_t rxport, grp = false, nchan = 1;
bt_soc_enable_status = 0;
BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
dai->id, dai->rate);
/* save sample rate */
btfmslim->sample_rate = dai->rate;
switch (dai->id) {
case BTFM_FM_SLIM_TX:
grp = true; nchan = 2;
ch = btfmslim->tx_chs;
rxport = 0;
break;
case BTFM_BT_SCO_SLIM_TX:
ch = btfmslim->tx_chs;
rxport = 0;
break;
case BTFM_BT_SCO_A2DP_SLIM_RX:
case BTFM_BT_SPLIT_A2DP_SLIM_RX:
ch = btfmslim->rx_chs;
rxport = 1;
break;
case BTFM_SLIM_NUM_CODEC_DAIS:
default:
BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
return ret;
}
/* Search for dai->id matched port handler */
for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != dai->id); ch++, i++)
;
if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
(ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
BTFMSLIM_ERR("ch is invalid!!");
return ret;
}
ret = btfm_slim_enable_ch(btfmslim, ch, rxport, dai->rate, grp, nchan);
/* save the enable channel status */
if (ret == 0)
bt_soc_enable_status = 1;
return ret;
}
/* This function will be called once during boot up */
static int btfm_slim_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
{
int ret = -EINVAL, i;
struct btfmslim *btfmslim = dai->dev->platform_data;
struct btfmslim_ch *rx_chs;
struct btfmslim_ch *tx_chs;
BTFMSLIM_DBG("");
if (!btfmslim)
return ret;
rx_chs = btfmslim->rx_chs;
tx_chs = btfmslim->tx_chs;
if (!rx_chs || !tx_chs)
return ret;
BTFMSLIM_DBG("Rx: id\tname\tport\thdl\tch\tch_hdl");
for (i = 0; (rx_chs->port != BTFM_SLIM_PGD_PORT_LAST) && (i < rx_num);
i++, rx_chs++) {
/* Set Rx Channel number from machine driver and
* get channel handler from slimbus driver
*/
rx_chs->ch = *(uint8_t *)(rx_slot + i);
ret = slim_query_ch(btfmslim->slim_pgd, rx_chs->ch,
&rx_chs->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_query_ch failure ch#%d - ret[%d]",
rx_chs->ch, ret);
goto error;
}
BTFMSLIM_DBG(" %d\t%s\t%d\t%x\t%d\t%x", rx_chs->id,
rx_chs->name, rx_chs->port, rx_chs->port_hdl,
rx_chs->ch, rx_chs->ch_hdl);
}
BTFMSLIM_DBG("Tx: id\tname\tport\thdl\tch\tch_hdl");
for (i = 0; (tx_chs->port != BTFM_SLIM_PGD_PORT_LAST) && (i < tx_num);
i++, tx_chs++) {
/* Set Tx Channel number from machine driver and
* get channel handler from slimbus driver
*/
tx_chs->ch = *(uint8_t *)(tx_slot + i);
ret = slim_query_ch(btfmslim->slim_pgd, tx_chs->ch,
&tx_chs->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_query_ch failure ch#%d - ret[%d]",
tx_chs->ch, ret);
goto error;
}
BTFMSLIM_DBG(" %d\t%s\t%d\t%x\t%d\t%x", tx_chs->id,
tx_chs->name, tx_chs->port, tx_chs->port_hdl,
tx_chs->ch, tx_chs->ch_hdl);
}
error:
return ret;
}
static int btfm_slim_dai_get_channel_map(struct snd_soc_dai *dai,
unsigned int *tx_num, unsigned int *tx_slot,
unsigned int *rx_num, unsigned int *rx_slot)
{
int i, ret = -EINVAL, *slot = NULL, j = 0, num = 1;
struct btfmslim *btfmslim = dai->dev->platform_data;
struct btfmslim_ch *ch = NULL;
if (!btfmslim)
return ret;
switch (dai->id) {
case BTFM_FM_SLIM_TX:
num = 2;
case BTFM_BT_SCO_SLIM_TX:
if (!tx_slot || !tx_num) {
BTFMSLIM_ERR("Invalid tx_slot %p or tx_num %p",
tx_slot, tx_num);
return -EINVAL;
}
ch = btfmslim->tx_chs;
if (!ch)
return -EINVAL;
slot = tx_slot;
*rx_slot = 0;
*tx_num = num;
*rx_num = 0;
break;
case BTFM_BT_SCO_A2DP_SLIM_RX:
case BTFM_BT_SPLIT_A2DP_SLIM_RX:
if (!rx_slot || !rx_num) {
BTFMSLIM_ERR("Invalid rx_slot %p or rx_num %p",
rx_slot, rx_num);
return -EINVAL;
}
ch = btfmslim->rx_chs;
if (!ch)
return -EINVAL;
slot = rx_slot;
*tx_slot = 0;
*tx_num = 0;
*rx_num = num;
break;
default:
BTFMSLIM_ERR("Unsupported DAI %d", dai->id);
return -EINVAL;
}
do {
if (!ch)
return -EINVAL;
for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) && (ch->id !=
BTFM_SLIM_NUM_CODEC_DAIS) && (ch->id != dai->id);
ch++, i++)
;
if (ch->id == BTFM_SLIM_NUM_CODEC_DAIS ||
i == BTFM_SLIM_NUM_CODEC_DAIS) {
BTFMSLIM_ERR(
"No channel has been allocated for dai (%d)",
dai->id);
return -EINVAL;
}
if (!slot)
return -EINVAL;
*(slot + j) = ch->ch;
BTFMSLIM_DBG("id:%d, port:%d, ch:%d, slot: %d", ch->id,
ch->port, ch->ch, *(slot + j));
/* In case it has mulitiple channels */
if (++j < num)
ch++;
} while (j < num);
return 0;
}
static struct snd_soc_dai_ops btfmslim_dai_ops = {
.startup = btfm_slim_dai_startup,
.shutdown = btfm_slim_dai_shutdown,
.hw_params = btfm_slim_dai_hw_params,
.prepare = btfm_slim_dai_prepare,
.set_channel_map = btfm_slim_dai_set_channel_map,
.get_channel_map = btfm_slim_dai_get_channel_map,
};
static struct snd_soc_dai_driver btfmslim_dai[] = {
{ /* FM Audio data multiple channel : FM -> qdsp */
.name = "btfm_fm_slim_tx",
.id = BTFM_FM_SLIM_TX,
.capture = {
.stream_name = "FM TX Capture",
.rates = SNDRV_PCM_RATE_48000, /* 48 KHz */
.formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
.channels_max = 2,
},
.ops = &btfmslim_dai_ops,
},
{ /* Bluetooth SCO voice uplink: bt -> modem */
.name = "btfm_bt_sco_slim_tx",
.id = BTFM_BT_SCO_SLIM_TX,
.capture = {
.stream_name = "SCO TX Capture",
/* 8 KHz or 16 KHz */
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000
| SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000
| SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */
.rate_max = 96000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 1,
},
.ops = &btfmslim_dai_ops,
},
{ /* Bluetooth SCO voice downlink: modem -> bt or A2DP Playback */
.name = "btfm_bt_sco_a2dp_slim_rx",
.id = BTFM_BT_SCO_A2DP_SLIM_RX,
.playback = {
.stream_name = "SCO A2DP RX Playback",
/* 8/16/44.1/48/88.2/96 Khz */
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000
| SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000
| SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */
.rate_max = 96000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 1,
},
.ops = &btfmslim_dai_ops,
},
{ /* Bluetooth Split A2DP data: qdsp -> bt */
.name = "btfm_bt_split_a2dp_slim_rx",
.id = BTFM_BT_SPLIT_A2DP_SLIM_RX,
.playback = {
.stream_name = "SPLIT A2DP Playback",
.rates = SNDRV_PCM_RATE_48000, /* 48 KHz */
.formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */
.rate_max = 48000,
.rate_min = 48000,
.channels_min = 1,
.channels_max = 1,
},
.ops = &btfmslim_dai_ops,
},
};
static const struct snd_soc_component_driver btfmslim_codec = {
.probe = btfm_slim_codec_probe,
.remove = btfm_slim_codec_remove,
.read = btfm_slim_codec_read,
.write = btfm_slim_codec_write,
};
int btfm_slim_register_codec(struct device *dev)
{
int ret = 0;
BTFMSLIM_DBG("");
/* Register Codec driver */
ret = snd_soc_register_component(dev, &btfmslim_codec,
btfmslim_dai, ARRAY_SIZE(btfmslim_dai));
if (ret)
BTFMSLIM_ERR("failed to register codec (%d)", ret);
return ret;
}
void btfm_slim_unregister_codec(struct device *dev)
{
BTFMSLIM_DBG("");
/* Unregister Codec driver */
snd_soc_unregister_component(dev);
}
MODULE_DESCRIPTION("BTFM Slimbus Codec driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,189 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/slimbus/slimbus.h>
#include "btfm_slim.h"
#include "btfm_slim_slave.h"
/* SLAVE (WCN3990/QCA6390) Port assignment */
struct btfmslim_ch slave_rxport[] = {
{.id = BTFM_BT_SCO_A2DP_SLIM_RX, .name = "SCO_A2P_Rx",
.port = SLAVE_SB_PGD_PORT_RX_SCO},
{.id = BTFM_BT_SPLIT_A2DP_SLIM_RX, .name = "A2P_Rx",
.port = SLAVE_SB_PGD_PORT_RX_A2P},
{.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
.port = BTFM_SLIM_PGD_PORT_LAST},
};
struct btfmslim_ch slave_txport[] = {
{.id = BTFM_BT_SCO_SLIM_TX, .name = "SCO_Tx",
.port = SLAVE_SB_PGD_PORT_TX_SCO},
{.id = BTFM_FM_SLIM_TX, .name = "FM_Tx1",
.port = SLAVE_SB_PGD_PORT_TX1_FM},
{.id = BTFM_FM_SLIM_TX, .name = "FM_Tx2",
.port = SLAVE_SB_PGD_PORT_TX2_FM},
{.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
.port = BTFM_SLIM_PGD_PORT_LAST},
};
/* Function description */
int btfm_slim_slave_hw_init(struct btfmslim *btfmslim)
{
int ret = 0;
uint8_t reg_val;
uint16_t reg;
BTFMSLIM_DBG("");
if (!btfmslim)
return -EINVAL;
/* Get SB_SLAVE_HW_REV_MSB value*/
reg = SLAVE_SB_SLAVE_HW_REV_MSB;
ret = btfm_slim_read(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
goto error;
}
BTFMSLIM_DBG("Major Rev: 0x%x, Minor Rev: 0x%x",
(reg_val & 0xF0) >> 4, (reg_val & 0x0F));
/* Get SB_SLAVE_HW_REV_LSB value*/
reg = SLAVE_SB_SLAVE_HW_REV_LSB;
ret = btfm_slim_read(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
goto error;
}
BTFMSLIM_DBG("Step Rev: 0x%x", reg_val);
error:
return ret;
}
static inline int is_fm_port(uint8_t port_num)
{
if (port_num == SLAVE_SB_PGD_PORT_TX1_FM ||
port_num == CHRKVER3_SB_PGD_PORT_TX1_FM ||
port_num == CHRKVER3_SB_PGD_PORT_TX2_FM ||
port_num == SLAVE_SB_PGD_PORT_TX2_FM)
return 1;
else
return 0;
}
int btfm_slim_slave_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
uint8_t rxport, uint8_t enable)
{
int ret = 0;
uint8_t reg_val = 0, en;
uint8_t rxport_num = 0;
uint16_t reg;
BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
if (rxport) {
BTFMSLIM_DBG("sample rate is %d", btfmslim->sample_rate);
if (enable &&
btfmslim->sample_rate != 44100 &&
btfmslim->sample_rate != 88200) {
BTFMSLIM_DBG("setting multichannel bit");
/* For SCO Rx, A2DP Rx other than 44.1 and 88.2Khz */
if (port_num < 24) {
rxport_num = port_num - 16;
reg_val = 0x01 << rxport_num;
reg = SLAVE_SB_PGD_RX_PORTn_MULTI_CHNL_0(
rxport_num);
} else {
rxport_num = port_num - 24;
reg_val = 0x01 << rxport_num;
reg = SLAVE_SB_PGD_RX_PORTn_MULTI_CHNL_1(
rxport_num);
}
BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
ret, reg);
goto error;
}
}
/* Port enable */
reg = SLAVE_SB_PGD_PORT_RX_CFGN(port_num - 0x10);
goto enable_disable_rxport;
}
if (!enable)
goto enable_disable_txport;
/* txport */
/* Multiple Channel Setting */
if (is_fm_port(port_num)) {
if (port_num == CHRKVER3_SB_PGD_PORT_TX1_FM)
reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX1_FM);
else if (port_num == CHRKVER3_SB_PGD_PORT_TX2_FM)
reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX2_FM);
else
reg_val = (0x1 << SLAVE_SB_PGD_PORT_TX1_FM) |
(0x1 << SLAVE_SB_PGD_PORT_TX2_FM);
reg = SLAVE_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
BTFMSLIM_INFO("writing reg_val (%d) to reg(%x)", reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
goto error;
}
} else if (port_num == SLAVE_SB_PGD_PORT_TX_SCO) {
/* SCO Tx */
reg_val = 0x1 << SLAVE_SB_PGD_PORT_TX_SCO;
reg = SLAVE_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
ret, reg);
goto error;
}
}
/* Enable Tx port hw auto recovery for underrun or overrun error */
reg_val = (SLAVE_ENABLE_OVERRUN_AUTO_RECOVERY |
SLAVE_ENABLE_UNDERRUN_AUTO_RECOVERY);
reg = SLAVE_SB_PGD_PORT_TX_OR_UR_CFGN(port_num);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
goto error;
}
enable_disable_txport:
/* Port enable */
reg = SLAVE_SB_PGD_PORT_TX_CFGN(port_num);
enable_disable_rxport:
if (enable)
en = SLAVE_SB_PGD_PORT_ENABLE;
else
en = SLAVE_SB_PGD_PORT_DISABLE;
if (is_fm_port(port_num))
reg_val = en | SLAVE_SB_PGD_PORT_WM_L8;
else if (port_num == SLAVE_SB_PGD_PORT_TX_SCO)
reg_val = enable ? en | SLAVE_SB_PGD_PORT_WM_L1 : en;
else
reg_val = enable ? en | SLAVE_SB_PGD_PORT_WM_LB : en;
if (enable && port_num == SLAVE_SB_PGD_PORT_TX_SCO)
BTFMSLIM_INFO("programming SCO Tx with reg_val %d to reg 0x%x",
reg_val, reg);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret)
BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
error:
return ret;
}

View File

@ -0,0 +1,161 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
#ifndef BTFM_SLIM_SLAVE_H
#define BTFM_SLIM_SLAVE_H
#include "btfm_slim.h"
/* Registers Address */
#define SLAVE_SB_COMP_TEST 0x00000000
#define SLAVE_SB_SLAVE_HW_REV_MSB 0x00000001
#define SLAVE_SB_SLAVE_HW_REV_LSB 0x00000002
#define SLAVE_SB_DEBUG_FEATURES 0x00000005
#define SLAVE_SB_INTF_INT_EN 0x00000010
#define SLAVE_SB_INTF_INT_STATUS 0x00000011
#define SLAVE_SB_INTF_INT_CLR 0x00000012
#define SLAVE_SB_FRM_CFG 0x00000013
#define SLAVE_SB_FRM_STATUS 0x00000014
#define SLAVE_SB_FRM_INT_EN 0x00000015
#define SLAVE_SB_FRM_INT_STATUS 0x00000016
#define SLAVE_SB_FRM_INT_CLR 0x00000017
#define SLAVE_SB_FRM_WAKEUP 0x00000018
#define SLAVE_SB_FRM_CLKCTL_DONE 0x00000019
#define SLAVE_SB_FRM_IE_STATUS 0x0000001A
#define SLAVE_SB_FRM_VE_STATUS 0x0000001B
#define SLAVE_SB_PGD_TX_CFG_STATUS 0x00000020
#define SLAVE_SB_PGD_RX_CFG_STATUS 0x00000021
#define SLAVE_SB_PGD_DEV_INT_EN 0x00000022
#define SLAVE_SB_PGD_DEV_INT_STATUS 0x00000023
#define SLAVE_SB_PGD_DEV_INT_CLR 0x00000024
#define SLAVE_SB_PGD_PORT_INT_EN_RX_0 0x00000030
#define SLAVE_SB_PGD_PORT_INT_EN_RX_1 0x00000031
#define SLAVE_SB_PGD_PORT_INT_EN_TX_0 0x00000032
#define SLAVE_SB_PGD_PORT_INT_EN_TX_1 0x00000033
#define SLAVE_SB_PGD_PORT_INT_STATUS_RX_0 0x00000034
#define SLAVE_SB_PGD_PORT_INT_STATUS_RX_1 0x00000035
#define SLAVE_SB_PGD_PORT_INT_STATUS_TX_0 0x00000036
#define SLAVE_SB_PGD_PORT_INT_STATUS_TX_1 0x00000037
#define SLAVE_SB_PGD_PORT_INT_CLR_RX_0 0x00000038
#define SLAVE_SB_PGD_PORT_INT_CLR_RX_1 0x00000039
#define SLAVE_SB_PGD_PORT_INT_CLR_TX_0 0x0000003A
#define SLAVE_SB_PGD_PORT_INT_CLR_TX_1 0x0000003B
#define SLAVE_SB_PGD_PORT_RX_CFGN(n) (0x00000040 + n)
#define SLAVE_SB_PGD_PORT_TX_CFGN(n) (0x00000050 + n)
#define SLAVE_SB_PGD_PORT_INT_RX_SOURCEN(n) (0x00000060 + n)
#define SLAVE_SB_PGD_PORT_INT_TX_SOURCEN(n) (0x00000070 + n)
#define SLAVE_SB_PGD_PORT_RX_STATUSN(n) (0x00000080 + n)
#define SLAVE_SB_PGD_PORT_TX_STATUSN(n) (0x00000090 + n)
#define SLAVE_SB_PGD_TX_PORTn_MULTI_CHNL_0(n) (0x00000100 + 0x4*n)
#define SLAVE_SB_PGD_TX_PORTn_MULTI_CHNL_1(n) (0x00000101 + 0x4*n)
#define SLAVE_SB_PGD_RX_PORTn_MULTI_CHNL_0(n) (0x00000180 + 0x4*n)
#define SLAVE_SB_PGD_RX_PORTn_MULTI_CHNL_1(n) (0x00000181 + 0x4*n)
#define SLAVE_SB_PGD_PORT_TX_OR_UR_CFGN(n) (0x000001F0 + n)
/* Register Bit Setting */
#define SLAVE_ENABLE_OVERRUN_AUTO_RECOVERY (0x1 << 1)
#define SLAVE_ENABLE_UNDERRUN_AUTO_RECOVERY (0x1 << 0)
#define SLAVE_SB_PGD_PORT_ENABLE (0x1 << 0)
#define SLAVE_SB_PGD_PORT_DISABLE (0x0 << 0)
#define SLAVE_SB_PGD_PORT_WM_L1 (0x1 << 1)
#define SLAVE_SB_PGD_PORT_WM_L2 (0x2 << 1)
#define SLAVE_SB_PGD_PORT_WM_L3 (0x3 << 1)
#define SLAVE_SB_PGD_PORT_WM_L8 (0x8 << 1)
#define SLAVE_SB_PGD_PORT_WM_LB (0xB << 1)
#define SLAVE_SB_PGD_PORT_RX_NUM 16
#define SLAVE_SB_PGD_PORT_TX_NUM 16
/* PGD Port Map */
#define SLAVE_SB_PGD_PORT_TX_SCO 0
#define SLAVE_SB_PGD_PORT_TX1_FM 1
#define SLAVE_SB_PGD_PORT_TX2_FM 2
#define CHRKVER3_SB_PGD_PORT_TX1_FM 4
#define CHRKVER3_SB_PGD_PORT_TX2_FM 5
#define SLAVE_SB_PGD_PORT_RX_SCO 16
#define SLAVE_SB_PGD_PORT_RX_A2P 17
enum {
QCA_CHEROKEE_SOC_ID_0200 = 0x40010200,
QCA_CHEROKEE_SOC_ID_0201 = 0x40010201,
QCA_CHEROKEE_SOC_ID_0210 = 0x40010214,
QCA_CHEROKEE_SOC_ID_0211 = 0x40010224,
QCA_CHEROKEE_SOC_ID_0310 = 0x40010310,
QCA_CHEROKEE_SOC_ID_0320 = 0x40010320,
QCA_CHEROKEE_SOC_ID_0320_UMC = 0x40014320,
};
enum {
QCA_APACHE_SOC_ID_0100 = 0x40020120,
QCA_APACHE_SOC_ID_0110 = 0x40020130,
QCA_APACHE_SOC_ID_0120 = 0x40020140,
QCA_APACHE_SOC_ID_0121 = 0x40020150,
};
enum {
QCA_COMANCHE_SOC_ID_0101 = 0x40070101,
QCA_COMANCHE_SOC_ID_0110 = 0x40070110,
QCA_COMANCHE_SOC_ID_0120 = 0x40070120,
};
enum {
QCA_HASTINGS_SOC_ID_0200 = 0x400A0200,
};
/* Function Prototype */
/*
* btfm_slim_slave_hw_init: Initialize slave specific slimbus slave device
* @btfmslim: slimbus slave device data pointer.
* Returns:
* 0: Success
* else: Fail
*/
int btfm_slim_slave_hw_init(struct btfmslim *btfmslim);
/*
* btfm_slim_slave_enable_rxport: Enable slave Rx port by given port number
* @btfmslim: slimbus slave device data pointer.
* @portNum: slimbus slave port number to enable
* @rxport: rxport or txport
* @enable: enable port or disable port
* Returns:
* 0: Success
* else: Fail
*/
int btfm_slim_slave_enable_port(struct btfmslim *btfmslim, uint8_t portNum,
uint8_t rxport, uint8_t enable);
/* Specific defines for slave slimbus device */
#define SLAVE_SLIM_REG_OFFSET 0x0800
#ifdef SLIM_SLAVE_REG_OFFSET
#undef SLIM_SLAVE_REG_OFFSET
#define SLIM_SLAVE_REG_OFFSET SLAVE_SLIM_REG_OFFSET
#endif
/* Assign vendor specific function */
extern struct btfmslim_ch slave_txport[];
extern struct btfmslim_ch slave_rxport[];
#ifdef SLIM_SLAVE_RXPORT
#undef SLIM_SLAVE_RXPORT
#define SLIM_SLAVE_RXPORT (&slave_rxport[0])
#endif
#ifdef SLIM_SLAVE_TXPORT
#undef SLIM_SLAVE_TXPORT
#define SLIM_SLAVE_TXPORT (&slave_txport[0])
#endif
#ifdef SLIM_SLAVE_INIT
#undef SLIM_SLAVE_INIT
#define SLIM_SLAVE_INIT btfm_slim_slave_hw_init
#endif
#ifdef SLIM_SLAVE_PORT_EN
#undef SLIM_SLAVE_PORT_EN
#define SLIM_SLAVE_PORT_EN btfm_slim_slave_enable_port
#endif
#endif

772
drivers/bluetooth/btpower.c Normal file
View File

@ -0,0 +1,772 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
/*
* Bluetooth Power Switch Module
* controls power to external Bluetooth device
* with interface to power management device
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#include <linux/btpower.h>
#if defined CONFIG_BT_SLIM_QCA6390 || \
defined CONFIG_BT_SLIM_QCA6490 || \
defined CONFIG_BTFM_SLIM_WCN3990
#include "btfm_slim.h"
#endif
#include <linux/fs.h>
static const struct of_device_id bt_power_match_table[] = {
{ .compatible = "qcom,qca6174" },
{ .compatible = "qcom,wcn3990" },
{ .compatible = "qcom,qca6390" },
{ .compatible = "qcom,qca6490" },
{},
};
static struct bt_power_vreg_data bt_power_vreg_info[] = {
{NULL, "qcom,bt-vdd-aon", 950000, 950000, 0, false, true},
{NULL, "qcom,bt-vdd-dig", 950000, 952000, 0, false, true},
{NULL, "qcom,bt-vdd-rfa1", 1900000, 1900000, 0, false, true},
{NULL, "qcom,bt-vdd-rfa2", 1900000, 1900000, 0, false, true},
{NULL, "qcom,bt-vdd-asd", 0, 0, 0, false, false},
};
#define BT_VREG_INFO_SIZE ARRAY_SIZE(bt_power_vreg_info)
static int bt_power_vreg_get(struct platform_device *pdev);
static int bt_power_vreg_set(enum bt_power_modes mode);
static void bt_power_vreg_put(void);
static struct bluetooth_power_platform_data *bt_power_pdata;
static struct platform_device *btpdev;
static bool previous;
static int pwr_state;
static struct class *bt_class;
static int bt_major;
static int soc_id;
static int bt_vreg_enable(struct bt_power_vreg_data *vreg)
{
int rc = 0;
pr_debug("%s: vreg_en for : %s\n", __func__, vreg->name);
if (!vreg->is_enabled) {
if ((vreg->min_vol != 0) && (vreg->max_vol != 0)) {
rc = regulator_set_voltage(vreg->reg,
vreg->min_vol,
vreg->max_vol);
if (rc < 0) {
pr_err("%s: regulator_set_voltage(%s) failed rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
}
if (vreg->load_curr >= 0) {
rc = regulator_set_load(vreg->reg,
vreg->load_curr);
if (rc < 0) {
pr_err("%s: regulator_set_load(%s) failed rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
}
rc = regulator_enable(vreg->reg);
if (rc < 0) {
pr_err("regulator_enable(%s) failed. rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
vreg->is_enabled = true;
}
out:
return rc;
}
static int bt_vreg_enable_retention(struct bt_power_vreg_data *vreg)
{
int rc = 0;
if (!vreg)
return rc;
pr_debug("%s: enable_retention for : %s\n", __func__, vreg->name);
if ((vreg->is_enabled) && (vreg->is_retention_supp)) {
if ((vreg->min_vol != 0) && (vreg->max_vol != 0)) {
/* Set the min voltage to 0 */
rc = regulator_set_voltage(vreg->reg, 0, vreg->max_vol);
if (rc < 0) {
pr_err("%s: regulator_set_voltage(%s) failed rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
}
if (vreg->load_curr >= 0) {
rc = regulator_set_load(vreg->reg, 0);
if (rc < 0) {
pr_err("%s: regulator_set_load(%s) failed rc=%d\n",
__func__, vreg->name, rc);
}
}
}
out:
return rc;
}
static int bt_vreg_disable(struct bt_power_vreg_data *vreg)
{
int rc = 0;
if (!vreg)
return rc;
pr_debug("vreg_disable for : %s\n", __func__, vreg->name);
if (vreg->is_enabled) {
rc = regulator_disable(vreg->reg);
if (rc < 0) {
pr_err("%s, regulator_disable(%s) failed. rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
vreg->is_enabled = false;
if ((vreg->min_vol != 0) && (vreg->max_vol != 0)) {
/* Set the min voltage to 0 */
rc = regulator_set_voltage(vreg->reg, 0,
vreg->max_vol);
if (rc < 0) {
pr_err("%s: regulator_set_voltage(%s) failed rc=%d\n",
__func__, vreg->name, rc);
goto out;
}
}
if (vreg->load_curr >= 0) {
rc = regulator_set_load(vreg->reg, 0);
if (rc < 0) {
pr_err("%s: regulator_set_load(%s) failed rc=%d\n",
__func__, vreg->name, rc);
}
}
}
out:
return rc;
}
static int bt_clk_enable(struct bt_power_clk_data *clk)
{
int rc = 0;
pr_debug("%s: %s\n", __func__, clk->name);
/* Get the clock handle for vreg */
if (!clk->clk || clk->is_enabled) {
pr_err("%s: error - node: %p, clk->is_enabled:%d\n",
__func__, clk->clk, clk->is_enabled);
return -EINVAL;
}
rc = clk_prepare_enable(clk->clk);
if (rc) {
pr_err("%s: failed to enable %s, rc(%d)\n",
__func__, clk->name, rc);
return rc;
}
clk->is_enabled = true;
return rc;
}
static int bt_clk_disable(struct bt_power_clk_data *clk)
{
int rc = 0;
pr_debug("%s: %s\n", __func__, clk->name);
/* Get the clock handle for vreg */
if (!clk->clk || !clk->is_enabled) {
pr_err("%s: error - node: %p, clk->is_enabled:%d\n",
__func__, clk->clk, clk->is_enabled);
return -EINVAL;
}
clk_disable_unprepare(clk->clk);
clk->is_enabled = false;
return rc;
}
static int bt_configure_gpios(int on)
{
int rc = 0;
int bt_reset_gpio = bt_power_pdata->bt_gpio_sys_rst;
pr_debug("%s: bt_gpio= %d on: %d\n", __func__, bt_reset_gpio, on);
if (on) {
rc = gpio_request(bt_reset_gpio, "bt_sys_rst_n");
if (rc) {
pr_err("%s: unable to request gpio %d (%d)\n",
__func__, bt_reset_gpio, rc);
return rc;
}
rc = gpio_direction_output(bt_reset_gpio, 0);
if (rc) {
pr_err("%s: Unable to set direction\n", __func__);
return rc;
}
msleep(50);
rc = gpio_direction_output(bt_reset_gpio, 1);
if (rc) {
pr_err("%s: Unable to set direction\n", __func__);
return rc;
}
msleep(50);
} else {
gpio_set_value(bt_reset_gpio, 0);
msleep(100);
}
return rc;
}
static int bluetooth_power(int on)
{
int rc = 0;
pr_debug("%s: on: %d\n", __func__, on);
if (on == 1) {
rc = bt_power_vreg_set(BT_POWER_ENABLE);
if (rc < 0) {
pr_err("%s: bt_power regulators config failed\n",
__func__);
goto regulator_fail;
}
/* Parse dt_info and check if a target requires clock voting.
* Enable BT clock when BT is on and disable it when BT is off
*/
if (bt_power_pdata->bt_chip_clk) {
rc = bt_clk_enable(bt_power_pdata->bt_chip_clk);
if (rc < 0) {
pr_err("%s: bt_power gpio config failed\n",
__func__);
goto clk_fail;
}
}
if (bt_power_pdata->bt_gpio_sys_rst > 0) {
rc = bt_configure_gpios(on);
if (rc < 0) {
pr_err("%s: bt_power gpio config failed\n",
__func__);
goto gpio_fail;
}
}
} else if (on == 0) {
// Power Off
if (bt_power_pdata->bt_gpio_sys_rst > 0)
bt_configure_gpios(on);
gpio_fail:
if (bt_power_pdata->bt_gpio_sys_rst > 0)
gpio_free(bt_power_pdata->bt_gpio_sys_rst);
if (bt_power_pdata->bt_chip_clk)
bt_clk_disable(bt_power_pdata->bt_chip_clk);
clk_fail:
regulator_fail:
bt_power_vreg_set(BT_POWER_DISABLE);
} else if (on == 2) {
/* Retention mode */
bt_power_vreg_set(BT_POWER_RETENTION);
} else {
pr_err("%s: Invalid power mode: %d\n", __func__, on);
rc = -1;
}
return rc;
}
static int bluetooth_toggle_radio(void *data, bool blocked)
{
int ret = 0;
int (*power_control)(int enable);
power_control =
((struct bluetooth_power_platform_data *)data)->bt_power_setup;
if (previous != blocked)
ret = (*power_control)(!blocked);
if (!ret)
previous = blocked;
return ret;
}
static const struct rfkill_ops bluetooth_power_rfkill_ops = {
.set_block = bluetooth_toggle_radio,
};
static ssize_t extldo_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
return scnprintf(buf, 6, "false\n");
}
static DEVICE_ATTR_RO(extldo);
static int bluetooth_power_rfkill_probe(struct platform_device *pdev)
{
struct rfkill *rfkill;
int ret;
rfkill = rfkill_alloc("bt_power", &pdev->dev, RFKILL_TYPE_BLUETOOTH,
&bluetooth_power_rfkill_ops,
pdev->dev.platform_data);
if (!rfkill) {
dev_err(&pdev->dev, "rfkill allocate failed\n");
return -ENOMEM;
}
/* add file into rfkill0 to handle LDO27 */
ret = device_create_file(&pdev->dev, &dev_attr_extldo);
if (ret < 0)
pr_err("%s: device create file error\n", __func__);
/* force Bluetooth off during init to allow for user control */
rfkill_init_sw_state(rfkill, 1);
previous = true;
ret = rfkill_register(rfkill);
if (ret) {
dev_err(&pdev->dev, "rfkill register failed=%d\n", ret);
rfkill_destroy(rfkill);
return ret;
}
platform_set_drvdata(pdev, rfkill);
return 0;
}
static void bluetooth_power_rfkill_remove(struct platform_device *pdev)
{
struct rfkill *rfkill;
pr_debug("%s\n", __func__);
rfkill = platform_get_drvdata(pdev);
if (rfkill)
rfkill_unregister(rfkill);
rfkill_destroy(rfkill);
platform_set_drvdata(pdev, NULL);
}
#define MAX_PROP_SIZE 32
static int bt_dt_parse_vreg_info(struct device *dev,
struct bt_power_vreg_data **vreg_data, const char *vreg_name)
{
int len;
const __be32 *prop;
char prop_name[MAX_PROP_SIZE];
struct bt_power_vreg_data *vreg = *vreg_data;
struct device_node *np = dev->of_node;
pr_debug("%s: vreg dev tree parse for %s\n", __func__, vreg_name);
snprintf(prop_name, sizeof(prop_name), "%s-supply", vreg_name);
if (of_parse_phandle(np, prop_name, 0)) {
snprintf(prop_name, sizeof(prop_name), "%s-config", vreg->name);
prop = of_get_property(dev->of_node, prop_name, &len);
if (!prop || len != (4 * sizeof(__be32))) {
pr_debug("%s: Property %s %s, use default\n",
__func__, prop_name,
prop ? "invalid format" : "doesn't exist");
} else {
vreg->min_vol = be32_to_cpup(&prop[0]);
vreg->max_vol = be32_to_cpup(&prop[1]);
vreg->load_curr = be32_to_cpup(&prop[2]);
vreg->is_retention_supp = be32_to_cpup(&prop[4]);
}
pr_debug("%s: Got regulator: %s, min_vol: %u, max_vol: %u, load_curr: %u,is_retention_supp: %u\n",
__func__, vreg->name, vreg->min_vol, vreg->max_vol,
vreg->load_curr, vreg->is_retention_supp);
} else
pr_info("%s: %s is not provided in device tree\n",
__func__, vreg_name);
return 0;
}
static int bt_dt_parse_clk_info(struct device *dev,
struct bt_power_clk_data **clk_data)
{
int ret = -EINVAL;
struct bt_power_clk_data *clk = NULL;
struct device_node *np = dev->of_node;
pr_debug("%s\n", __func__);
*clk_data = NULL;
if (of_parse_phandle(np, "clocks", 0)) {
clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
if (!clk) {
ret = -ENOMEM;
goto err;
}
/* Allocated 20 bytes size buffer for clock name string */
clk->name = devm_kzalloc(dev, 20, GFP_KERNEL);
/* Parse clock name from node */
ret = of_property_read_string_index(np, "clock-names", 0,
&(clk->name));
if (ret < 0) {
pr_err("%s: reading \"clock-names\" failed\n",
__func__);
return ret;
}
clk->clk = devm_clk_get(dev, clk->name);
if (IS_ERR(clk->clk)) {
ret = PTR_ERR(clk->clk);
pr_err("%s: failed to get %s, ret (%d)\n",
__func__, clk->name, ret);
clk->clk = NULL;
return ret;
}
*clk_data = clk;
} else {
pr_err("%s: clocks is not provided in device tree\n", __func__);
}
err:
return ret;
}
static int bt_power_vreg_get(struct platform_device *pdev)
{
struct bt_power_vreg_data *vreg_info;
int i = 0, ret = 0;
bt_power_pdata->vreg_info =
devm_kzalloc(&(pdev->dev),
sizeof(bt_power_vreg_info),
GFP_KERNEL);
if (!bt_power_pdata->vreg_info) {
ret = -ENOMEM;
goto out;
}
memcpy(bt_power_pdata->vreg_info, bt_power_vreg_info,
sizeof(bt_power_vreg_info));
for (; i < BT_VREG_INFO_SIZE; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
ret = bt_dt_parse_vreg_info(&(pdev->dev), &vreg_info,
vreg_info->name);
}
out:
return ret;
}
static int bt_power_vreg_set(enum bt_power_modes mode)
{
int i = 0, ret = 0;
struct bt_power_vreg_data *vreg_info = NULL;
struct device *dev = &btpdev->dev;
if (mode == BT_POWER_ENABLE) {
for (; i < BT_VREG_INFO_SIZE; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
/* set vreg handle if not already set */
if (!(vreg_info->reg)) {
vreg_info->reg = regulator_get(dev,
vreg_info->name);
if (IS_ERR(vreg_info->reg)) {
ret = PTR_ERR(vreg_info->reg);
vreg_info->reg = NULL;
pr_err("%s: regulator_get(%s) failed. rc=%d\n",
__func__, vreg_info->name, ret);
goto out;
}
}
ret = bt_vreg_enable(vreg_info);
if (ret < 0)
goto out;
}
} else if (mode == BT_POWER_DISABLE) {
for (; i < BT_VREG_INFO_SIZE; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
ret = bt_vreg_disable(vreg_info);
}
} else if (mode == BT_POWER_RETENTION) {
for (; i < BT_VREG_INFO_SIZE; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
ret = bt_vreg_enable_retention(vreg_info);
}
} else {
pr_err("%s: Invalid power mode: %d\n", __func__, mode);
ret = -1;
}
out:
return ret;
}
static void bt_power_vreg_put(void)
{
int i = 0;
struct bt_power_vreg_data *vreg_info = NULL;
for (; i < BT_VREG_INFO_SIZE; i++) {
vreg_info = &bt_power_pdata->vreg_info[i];
if (vreg_info->reg)
regulator_put(vreg_info->reg);
}
}
static int bt_power_populate_dt_pinfo(struct platform_device *pdev)
{
int rc;
pr_debug("%s\n", __func__);
if (!bt_power_pdata)
return -ENOMEM;
if (pdev->dev.of_node) {
bt_power_vreg_get(pdev);
bt_power_pdata->bt_gpio_sys_rst =
of_get_named_gpio(pdev->dev.of_node,
"qcom,bt-reset-gpio", 0);
if (bt_power_pdata->bt_gpio_sys_rst < 0)
pr_err("%s: bt-reset-gpio not provided in device tree\n",
__func__);
rc = bt_dt_parse_clk_info(&pdev->dev,
&bt_power_pdata->bt_chip_clk);
if (rc < 0)
pr_err("%s: clock not provided in device tree\n",
__func__);
}
bt_power_pdata->bt_power_setup = bluetooth_power;
return 0;
}
static int bt_power_probe(struct platform_device *pdev)
{
int ret = 0;
pr_debug("%s\n", __func__);
bt_power_pdata = kzalloc(sizeof(*bt_power_pdata), GFP_KERNEL);
if (!bt_power_pdata)
return -ENOMEM;
if (pdev->dev.of_node) {
ret = bt_power_populate_dt_pinfo(pdev);
if (ret < 0) {
pr_err("%s, Failed to populate device tree info\n",
__func__);
goto free_pdata;
}
pdev->dev.platform_data = bt_power_pdata;
} else if (pdev->dev.platform_data) {
/* Optional data set to default if not provided */
if (!((struct bluetooth_power_platform_data *)
(pdev->dev.platform_data))->bt_power_setup)
((struct bluetooth_power_platform_data *)
(pdev->dev.platform_data))->bt_power_setup =
bluetooth_power;
memcpy(bt_power_pdata, pdev->dev.platform_data,
sizeof(struct bluetooth_power_platform_data));
pwr_state = 0;
} else {
pr_err("%s: Failed to get platform data\n", __func__);
goto free_pdata;
}
if (bluetooth_power_rfkill_probe(pdev) < 0)
goto free_pdata;
btpdev = pdev;
return 0;
free_pdata:
kfree(bt_power_pdata);
return ret;
}
static int bt_power_remove(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "%s\n", __func__);
bluetooth_power_rfkill_remove(pdev);
bt_power_vreg_put();
kfree(bt_power_pdata);
return 0;
}
int btpower_register_slimdev(struct device *dev)
{
pr_debug("%s\n", __func__);
if (!bt_power_pdata || (dev == NULL)) {
pr_err("%s: Failed to allocate memory\n", __func__);
return -EINVAL;
}
bt_power_pdata->slim_dev = dev;
return 0;
}
EXPORT_SYMBOL(btpower_register_slimdev);
int btpower_get_chipset_version(void)
{
pr_debug("%s\n", __func__);
return soc_id;
}
EXPORT_SYMBOL(btpower_get_chipset_version);
static long bt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret = 0, pwr_cntrl = 0;
int chipset_version = 0;
switch (cmd) {
case BT_CMD_SLIM_TEST:
#if (defined CONFIG_BT_SLIM_QCA6390 || \
defined CONFIG_BT_SLIM_QCA6490 || \
defined CONFIG_BTFM_SLIM_WCN3990)
if (!bt_power_pdata->slim_dev) {
pr_err("%s: slim_dev is null\n", __func__);
return -EINVAL;
}
ret = btfm_slim_hw_init(
bt_power_pdata->slim_dev->platform_data
);
#endif
break;
case BT_CMD_PWR_CTRL:
pwr_cntrl = (int)arg;
pr_err("%s: BT_CMD_PWR_CTRL pwr_cntrl: %d\n",
__func__, pwr_cntrl);
if (pwr_state != pwr_cntrl) {
ret = bluetooth_power(pwr_cntrl);
if (!ret)
pwr_state = pwr_cntrl;
} else {
pr_err("%s: BT chip state is already: %d no change\n",
__func__, pwr_state);
ret = 0;
}
break;
case BT_CMD_CHIPSET_VERS:
chipset_version = (int)arg;
pr_err("%s: BT_CMD_CHIP_VERS soc_version:%x\n", __func__,
chipset_version);
if (chipset_version) {
soc_id = chipset_version;
} else {
pr_err("%s: got invalid soc version\n");
soc_id = 0;
}
break;
default:
return -ENOIOCTLCMD;
}
return ret;
}
static struct platform_driver bt_power_driver = {
.probe = bt_power_probe,
.remove = bt_power_remove,
.driver = {
.name = "bt_power",
.of_match_table = bt_power_match_table,
},
};
static const struct file_operations bt_dev_fops = {
.unlocked_ioctl = bt_ioctl,
.compat_ioctl = bt_ioctl,
};
static int __init bluetooth_power_init(void)
{
int ret = 0;
ret = platform_driver_register(&bt_power_driver);
if (ret) {
pr_err("%s: platform_driver_register error: %d\n",
__func__, ret);
goto driver_err;
}
bt_major = register_chrdev(0, "bt", &bt_dev_fops);
if (bt_major < 0) {
pr_err("%s: failed to allocate char dev\n", __func__);
ret = -1;
goto chrdev_err;
}
bt_class = class_create(THIS_MODULE, "bt-dev");
if (IS_ERR(bt_class)) {
pr_err("%s: coudn't create class\n", __func__);
ret = -1;
goto class_err;
}
if (device_create(bt_class, NULL, MKDEV(bt_major, 0),
NULL, "btpower") == NULL) {
pr_err("%s: failed to allocate char dev\n", __func__);
goto device_err;
}
return 0;
device_err:
class_destroy(bt_class);
class_err:
unregister_chrdev(bt_major, "bt");
chrdev_err:
platform_driver_unregister(&bt_power_driver);
driver_err:
return ret;
}
static void __exit bluetooth_power_exit(void)
{
platform_driver_unregister(&bt_power_driver);
}
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MSM Bluetooth power control driver");
module_init(bluetooth_power_init);
module_exit(bluetooth_power_exit);

View File

@ -200,6 +200,25 @@ config DA8XX_MSTPRI
configuration. Allows to adjust the priorities of all master
peripherals.
config MHI_BUS
tristate "Modem Host Interface"
help
MHI Host Interface is a communication protocol to be used by the host
to control and communcate with modem over a high speed peripheral bus.
Enabling this module will allow host to communicate with external
devices that support MHI protocol.
config MHI_DEBUG
bool "MHI debug support"
depends on MHI_BUS
help
Say yes here to enable debugging support in the MHI transport
and individual MHI client drivers. This option will impact
throughput as individual MHI packets and state transitions
will be logged.
source "drivers/bus/fsl-mc/Kconfig"
source "drivers/bus/mhi/controllers/Kconfig"
source "drivers/bus/mhi/devices/Kconfig"
endmenu

View File

@ -34,3 +34,4 @@ obj-$(CONFIG_UNIPHIER_SYSTEM_BUS) += uniphier-system-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
obj-$(CONFIG_MHI_BUS) += mhi/

9
drivers/bus/mhi/Makefile Normal file
View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the MHI stack
#
# core layer
obj-y += core/
obj-y += controllers/
obj-y += devices/

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "MHI controllers"
config MHI_QCOM
tristate "MHI QCOM"
depends on MHI_BUS
help
If you say yes to this option, MHI bus support for QCOM modem chipsets
will be enabled. QCOM PCIe based modems uses MHI as the communication
protocol. MHI control driver is the bus master for such modems. As the
bus master driver, it oversees power management operations such as
suspend, resume, powering on and off the device.
endmenu

View File

@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MHI_QCOM) += mhi_qcom_drv.o
mhi_qcom_drv-y := mhi_qcom.o mhi_arch_qcom.o

View File

@ -0,0 +1,750 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/
#include <asm/dma-iommu.h>
#include <linux/async.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/esoc_client.h>
#include <linux/interconnect.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/msm_pcie.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/mhi.h>
#include "mhi_qcom.h"
struct arch_info {
struct mhi_dev *mhi_dev;
struct esoc_desc *esoc_client;
struct esoc_client_hook esoc_ops;
struct icc_path *icc_path;
u32 *icc_peak_bw;
u32 icc_peak_bw_len;
struct msm_pcie_register_event pcie_reg_event;
struct pci_saved_state *pcie_state;
async_cookie_t cookie;
void *boot_ipc_log;
void *tsync_ipc_log;
struct mhi_device *boot_dev;
bool drv_connected;
struct notifier_block pm_notifier;
struct completion pm_completion;
};
/* ipc log markings */
#define DLOG "Dev->Host: "
#define HLOG "Host: "
#define MHI_TSYNC_LOG_PAGES (10)
#ifdef CONFIG_MHI_DEBUG
#define MHI_IPC_LOG_PAGES (100)
enum MHI_DEBUG_LEVEL mhi_ipc_log_lvl = MHI_MSG_LVL_VERBOSE;
#else
#define MHI_IPC_LOG_PAGES (10)
enum MHI_DEBUG_LEVEL mhi_ipc_log_lvl = MHI_MSG_LVL_ERROR;
#endif
static int mhi_arch_pm_notifier(struct notifier_block *nb,
unsigned long event, void *unused)
{
struct arch_info *arch_info =
container_of(nb, struct arch_info, pm_notifier);
switch (event) {
case PM_SUSPEND_PREPARE:
reinit_completion(&arch_info->pm_completion);
break;
case PM_POST_SUSPEND:
complete_all(&arch_info->pm_completion);
break;
}
return NOTIFY_DONE;
}
void mhi_arch_timesync_log(struct mhi_controller *mhi_cntrl, u64 remote_time)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
if (remote_time != U64_MAX)
ipc_log_string(arch_info->tsync_ipc_log, "%6u.%06lu 0x%llx",
REMOTE_TICKS_TO_SEC(remote_time),
REMOTE_TIME_REMAINDER_US(remote_time),
remote_time);
}
static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
MHI_LOG("Setting bus request to index %d\n", index);
if (index >= arch_info->icc_peak_bw_len)
return -EINVAL;
if (arch_info->icc_path)
return icc_set_bw(arch_info->icc_path, 0,
arch_info->icc_peak_bw[index]);
/* default return success */
return 0;
}
static void mhi_arch_pci_link_state_cb(struct msm_pcie_notify *notify)
{
struct mhi_controller *mhi_cntrl = notify->data;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
struct arch_info *arch_info = mhi_dev->arch_info;
switch (notify->event) {
case MSM_PCIE_EVENT_WAKEUP:
MHI_LOG("Received MSM_PCIE_EVENT_WAKE signal\n");
/* bring link out of d3cold */
if (mhi_dev->powered_on) {
pm_runtime_get(&pci_dev->dev);
pm_runtime_put_noidle(&pci_dev->dev);
}
break;
case MSM_PCIE_EVENT_L1SS_TIMEOUT:
MHI_VERB("Received MSM_PCIE_EVENT_L1SS_TIMEOUT signal\n");
pm_runtime_mark_last_busy(&pci_dev->dev);
pm_request_autosuspend(&pci_dev->dev);
break;
case MSM_PCIE_EVENT_DRV_CONNECT:
/* drv is connected we can suspend now */
MHI_LOG("Received MSM_PCIE_EVENT_DRV_CONNECT signal\n");
arch_info->drv_connected = true;
mutex_lock(&mhi_cntrl->pm_mutex);
/* if we're in amss attempt a suspend */
if (mhi_dev->powered_on && mhi_cntrl->ee == MHI_EE_AMSS) {
pm_runtime_allow(&pci_dev->dev);
pm_runtime_mark_last_busy(&pci_dev->dev);
pm_request_autosuspend(&pci_dev->dev);
}
mutex_unlock(&mhi_cntrl->pm_mutex);
break;
case MSM_PCIE_EVENT_DRV_DISCONNECT:
MHI_LOG("Received MSM_PCIE_EVENT_DRV_DISCONNECT signal\n");
/*
* if link suspended bring it out of suspend and disable runtime
* suspend
*/
arch_info->drv_connected = false;
pm_runtime_forbid(&pci_dev->dev);
break;
default:
MHI_ERR("Unhandled event 0x%x\n", notify->event);
}
}
static int mhi_arch_esoc_ops_power_on(void *priv, unsigned int flags)
{
struct mhi_controller *mhi_cntrl = priv;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
int ret;
mutex_lock(&mhi_cntrl->pm_mutex);
if (mhi_dev->powered_on) {
MHI_LOG("MHI still in active state\n");
mutex_unlock(&mhi_cntrl->pm_mutex);
return 0;
}
MHI_LOG("Enter\n");
/* reset rpm state */
pm_runtime_set_active(&pci_dev->dev);
pm_runtime_enable(&pci_dev->dev);
mutex_unlock(&mhi_cntrl->pm_mutex);
pm_runtime_forbid(&pci_dev->dev);
ret = pm_runtime_get_sync(&pci_dev->dev);
if (ret < 0) {
MHI_ERR("Error with rpm resume, ret:%d\n", ret);
return ret;
}
/* re-start the link & recover default cfg states */
ret = msm_pcie_pm_control(MSM_PCIE_RESUME, pci_dev->bus->number,
pci_dev, NULL, 0);
if (ret) {
MHI_ERR("Failed to resume pcie bus ret %d\n", ret);
return ret;
}
mhi_dev->mdm_state = (flags & ESOC_HOOK_MDM_CRASH);
return mhi_pci_probe(pci_dev, NULL);
}
static void mhi_arch_link_off(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
MHI_LOG("Entered\n");
pci_set_power_state(pci_dev, PCI_D3hot);
/* release the resources */
msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev, NULL, 0);
mhi_arch_set_bus_request(mhi_cntrl, 0);
MHI_LOG("Exited\n");
}
static void mhi_arch_esoc_ops_power_off(void *priv, unsigned int flags)
{
struct mhi_controller *mhi_cntrl = priv;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
bool mdm_state = (flags & ESOC_HOOK_MDM_CRASH);
MHI_LOG("Enter: mdm_crashed:%d\n", mdm_state);
/*
* Abort system suspend if system is preparing to go to suspend
* by grabbing wake source.
* If system is suspended, wait for pm notifier callback to notify
* that resume has occurred with PM_POST_SUSPEND event.
*/
pm_stay_awake(&mhi_cntrl->mhi_dev->dev);
wait_for_completion(&arch_info->pm_completion);
/* if link is in drv suspend, wake it up */
pm_runtime_get_sync(&pci_dev->dev);
mutex_lock(&mhi_cntrl->pm_mutex);
if (!mhi_dev->powered_on) {
MHI_LOG("Not in active state\n");
mutex_unlock(&mhi_cntrl->pm_mutex);
pm_runtime_put_noidle(&pci_dev->dev);
return;
}
mhi_dev->powered_on = false;
mutex_unlock(&mhi_cntrl->pm_mutex);
pm_runtime_put_noidle(&pci_dev->dev);
MHI_LOG("Triggering shutdown process\n");
mhi_power_down(mhi_cntrl, !mdm_state);
/* turn the link off */
mhi_deinit_pci_dev(mhi_cntrl);
mhi_arch_link_off(mhi_cntrl);
/* wait for boot monitor to exit */
async_synchronize_cookie(arch_info->cookie + 1);
mhi_arch_pcie_deinit(mhi_cntrl);
mhi_cntrl->dev = NULL;
pm_relax(&mhi_cntrl->mhi_dev->dev);
}
static void mhi_arch_esoc_ops_mdm_error(void *priv)
{
struct mhi_controller *mhi_cntrl = priv;
MHI_LOG("Enter: mdm asserted\n");
/* transition MHI state into error state */
mhi_control_error(mhi_cntrl);
MHI_LOG("Exit\n");
}
static void mhi_bl_dl_cb(struct mhi_device *mhi_device,
struct mhi_result *mhi_result)
{
struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
char *buf = mhi_result->buf_addr;
/* force a null at last character */
buf[mhi_result->bytes_xferd - 1] = 0;
ipc_log_string(arch_info->boot_ipc_log, "%s %s", DLOG, buf);
}
static void mhi_bl_dummy_cb(struct mhi_device *mhi_dev,
struct mhi_result *mhi_result)
{
}
static void mhi_bl_remove(struct mhi_device *mhi_device)
{
struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
arch_info->boot_dev = NULL;
ipc_log_string(arch_info->boot_ipc_log,
HLOG "Received Remove notif.\n");
}
static void mhi_boot_monitor(void *data, async_cookie_t cookie)
{
struct mhi_controller *mhi_cntrl = data;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct mhi_device *boot_dev;
/* 15 sec timeout for booting device */
const u32 timeout = msecs_to_jiffies(15000);
/* wait for device to enter boot stage */
wait_event_timeout(mhi_cntrl->state_event, mhi_cntrl->ee == MHI_EE_AMSS
|| mhi_cntrl->ee == MHI_EE_DISABLE_TRANSITION
|| mhi_cntrl->power_down,
timeout);
ipc_log_string(arch_info->boot_ipc_log, HLOG "Device current ee = %s\n",
TO_MHI_EXEC_STR(mhi_cntrl->ee));
/* if we successfully booted to amss disable boot log channel */
if (mhi_cntrl->ee == MHI_EE_AMSS) {
boot_dev = arch_info->boot_dev;
if (boot_dev)
mhi_unprepare_from_transfer(boot_dev);
if (!mhi_dev->drv_supported || arch_info->drv_connected)
pm_runtime_allow(&mhi_dev->pci_dev->dev);
}
}
int mhi_arch_power_up(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
/* start a boot monitor if not in crashed state */
if (!mhi_dev->mdm_state)
arch_info->cookie = async_schedule(mhi_boot_monitor, mhi_cntrl);
return 0;
}
static int mhi_arch_pcie_scale_bw(struct mhi_controller *mhi_cntrl,
struct pci_dev *pci_dev,
struct mhi_link_info *link_info)
{
int ret;
mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data);
ret = msm_pcie_set_link_bandwidth(pci_dev, link_info->target_link_speed,
link_info->target_link_width);
mhi_cntrl->lpm_enable(mhi_cntrl, mhi_cntrl->priv_data);
if (ret)
return ret;
/* do a bus scale vote based on gen speeds */
mhi_arch_set_bus_request(mhi_cntrl, link_info->target_link_speed);
MHI_VERB("bw changed to speed:0x%x width:0x%x\n",
link_info->target_link_speed, link_info->target_link_width);
return 0;
}
static int mhi_arch_bw_scale(struct mhi_controller *mhi_cntrl,
struct mhi_link_info *link_info)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
return mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, link_info);
}
static int mhi_bl_probe(struct mhi_device *mhi_device,
const struct mhi_device_id *id)
{
char node_name[32];
struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
snprintf(node_name, sizeof(node_name), "mhi_bl_%04x_%02u.%02u.%02u",
mhi_device->dev_id, mhi_device->domain, mhi_device->bus,
mhi_device->slot);
arch_info->boot_dev = mhi_device;
arch_info->boot_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES,
node_name, 0);
ipc_log_string(arch_info->boot_ipc_log, HLOG
"Entered SBL, Session ID:0x%x\n", mhi_cntrl->session_id);
return 0;
}
static const struct mhi_device_id mhi_bl_match_table[] = {
{ .chan = "BL" },
{},
};
static struct mhi_driver mhi_bl_driver = {
.id_table = mhi_bl_match_table,
.remove = mhi_bl_remove,
.probe = mhi_bl_probe,
.ul_xfer_cb = mhi_bl_dummy_cb,
.dl_xfer_cb = mhi_bl_dl_cb,
.driver = {
.name = "MHI_BL",
.owner = THIS_MODULE,
},
};
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct mhi_link_info *cur_link_info;
char node[32];
int ret;
int size = 0;
u16 linkstat;
if (!arch_info) {
struct msm_pcie_register_event *reg_event;
struct pci_dev *root_port;
struct device_node *root_ofnode;
arch_info = devm_kzalloc(&mhi_dev->pci_dev->dev,
sizeof(*arch_info), GFP_KERNEL);
if (!arch_info)
return -ENOMEM;
mhi_dev->arch_info = arch_info;
arch_info->mhi_dev = mhi_dev;
snprintf(node, sizeof(node), "mhi_%04x_%02u.%02u.%02u",
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
mhi_cntrl->slot);
mhi_cntrl->log_buf = ipc_log_context_create(MHI_IPC_LOG_PAGES,
node, 0);
mhi_cntrl->log_lvl = mhi_ipc_log_lvl;
snprintf(node, sizeof(node), "mhi_tsync_%04x_%02u.%02u.%02u",
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
mhi_cntrl->slot);
arch_info->tsync_ipc_log = ipc_log_context_create(
MHI_TSYNC_LOG_PAGES, node, 0);
if (arch_info->tsync_ipc_log)
mhi_cntrl->tsync_log = mhi_arch_timesync_log;
/* check if root-complex support DRV */
root_port = pci_find_pcie_root_port(mhi_dev->pci_dev);
root_ofnode = root_port->dev.of_node;
if (root_ofnode->parent)
mhi_dev->drv_supported =
of_property_read_bool(root_ofnode->parent,
"qcom,drv-supported");
/* get icc path from PCIe platform device */
arch_info->icc_path = of_icc_get(root_port->dev.parent->parent,
"ep_icc_path");
if (IS_ERR_OR_NULL(arch_info->icc_path)) {
ret = arch_info->icc_path ?
PTR_ERR(arch_info->icc_path) : -EINVAL;
return ret;
}
of_get_property(pdev->dev.of_node, "icc_peak_bw", &size);
if (!size)
return -EINVAL;
arch_info->icc_peak_bw_len = size / sizeof(u32);
arch_info->icc_peak_bw = devm_kcalloc(&mhi_dev->pci_dev->dev,
arch_info->icc_peak_bw_len,
sizeof(u32), GFP_KERNEL);
if (!arch_info->icc_peak_bw)
return -ENOMEM;
ret = of_property_read_u32_array(mhi_dev->pci_dev->dev.of_node,
"icc-peak-bw", arch_info->icc_peak_len);
if (ret)
return -EINVAL;
/* register with pcie rc for WAKE# events */
reg_event = &arch_info->pcie_reg_event;
reg_event->events =
MSM_PCIE_EVENT_WAKEUP | MSM_PCIE_EVENT_L1SS_TIMEOUT;
/* if drv supported register for drv connection events */
if (mhi_dev->drv_supported)
reg_event->events |= MSM_PCIE_EVENT_DRV_CONNECT |
MSM_PCIE_EVENT_DRV_DISCONNECT;
reg_event->user = mhi_dev->pci_dev;
reg_event->callback = mhi_arch_pci_link_state_cb;
reg_event->notify.data = mhi_cntrl;
ret = msm_pcie_register_event(reg_event);
if (ret)
MHI_LOG("Failed to reg. for link up notification\n");
init_completion(&arch_info->pm_completion);
/* register PM notifier to get post resume events */
arch_info->pm_notifier.notifier_call = mhi_arch_pm_notifier;
register_pm_notifier(&arch_info->pm_notifier);
/*
* Mark as completed at initial boot-up to allow ESOC power on
* callback to proceed if system has not gone to suspend
*/
complete_all(&arch_info->pm_completion);
arch_info->esoc_client = devm_register_esoc_client(
&mhi_dev->pci_dev->dev, "mdm");
if (IS_ERR_OR_NULL(arch_info->esoc_client)) {
MHI_ERR("Failed to register esoc client\n");
} else {
/* register for power on/off hooks */
struct esoc_client_hook *esoc_ops =
&arch_info->esoc_ops;
esoc_ops->priv = mhi_cntrl;
esoc_ops->prio = ESOC_MHI_HOOK;
esoc_ops->esoc_link_power_on =
mhi_arch_esoc_ops_power_on;
esoc_ops->esoc_link_power_off =
mhi_arch_esoc_ops_power_off;
esoc_ops->esoc_link_mdm_crash =
mhi_arch_esoc_ops_mdm_error;
ret = esoc_register_client_hook(arch_info->esoc_client,
esoc_ops);
if (ret)
MHI_ERR("Failed to register esoc ops\n");
}
/*
* MHI host driver has full autonomy to manage power state.
* Disable all automatic power collapse features
*/
msm_pcie_pm_control(MSM_PCIE_DISABLE_PC, mhi_cntrl->bus,
mhi_dev->pci_dev, NULL, 0);
mhi_dev->pci_dev->no_d3hot = true;
mhi_cntrl->bw_scale = mhi_arch_bw_scale;
mhi_driver_register(&mhi_bl_driver);
}
/* store the current bw info */
ret = pcie_capability_read_word(mhi_dev->pci_dev,
PCI_EXP_LNKSTA, &linkstat);
if (ret)
return ret;
cur_link_info = &mhi_cntrl->mhi_link_info;
cur_link_info->target_link_speed = linkstat & PCI_EXP_LNKSTA_CLS;
cur_link_info->target_link_width = (linkstat & PCI_EXP_LNKSTA_NLW) >>
PCI_EXP_LNKSTA_NLW_SHIFT;
return mhi_arch_set_bus_request(mhi_cntrl,
cur_link_info->target_link_speed);
}
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl)
{
mhi_arch_set_bus_request(mhi_cntrl, 0);
}
static int mhi_arch_drv_suspend(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
struct mhi_link_info link_info, *cur_link_info;
bool bw_switched = false;
int ret;
cur_link_info = &mhi_cntrl->mhi_link_info;
/* if link is not in gen 1 we need to switch to gen 1 */
if (cur_link_info->target_link_speed != PCI_EXP_LNKSTA_CLS_2_5GB) {
link_info.target_link_speed = PCI_EXP_LNKSTA_CLS_2_5GB;
link_info.target_link_width = cur_link_info->target_link_width;
ret = mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, &link_info);
if (ret) {
MHI_ERR("Failed to switch Gen1 speed\n");
return -EBUSY;
}
bw_switched = true;
}
/* do a drv hand off */
ret = msm_pcie_pm_control(MSM_PCIE_DRV_SUSPEND, mhi_cntrl->bus,
pci_dev, NULL, 0);
/*
* we failed to suspend and scaled down pcie bw.. need to scale up again
*/
if (ret && bw_switched) {
mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, cur_link_info);
return ret;
}
return ret;
}
int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
int ret = 0;
MHI_LOG("Entered\n");
/* disable inactivity timer */
msm_pcie_l1ss_timeout_disable(pci_dev);
switch (mhi_dev->suspend_mode) {
case MHI_DEFAULT_SUSPEND:
pci_clear_master(pci_dev);
ret = pci_save_state(mhi_dev->pci_dev);
if (ret) {
MHI_ERR("Failed with pci_save_state, ret:%d\n", ret);
goto exit_suspend;
}
arch_info->pcie_state = pci_store_saved_state(pci_dev);
pci_disable_device(pci_dev);
pci_set_power_state(pci_dev, PCI_D3hot);
/* release the resources */
msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev,
NULL, 0);
mhi_arch_set_bus_request(mhi_cntrl, 0);
break;
case MHI_FAST_LINK_OFF:
ret = mhi_arch_drv_suspend(mhi_cntrl);
break;
case MHI_ACTIVE_STATE:
case MHI_FAST_LINK_ON:/* keeping link on do nothing */
break;
}
exit_suspend:
if (ret)
msm_pcie_l1ss_timeout_enable(pci_dev);
MHI_LOG("Exited with ret:%d\n", ret);
return ret;
}
static int __mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct arch_info *arch_info = mhi_dev->arch_info;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
struct mhi_link_info *cur_info = &mhi_cntrl->mhi_link_info;
int ret;
MHI_LOG("Entered\n");
/* request bus scale voting based on higher gen speed */
ret = mhi_arch_set_bus_request(mhi_cntrl,
cur_info->target_link_speed);
if (ret)
MHI_LOG("Could not set bus frequency, ret:%d\n", ret);
ret = msm_pcie_pm_control(MSM_PCIE_RESUME, mhi_cntrl->bus, pci_dev,
NULL, 0);
if (ret) {
MHI_ERR("Link training failed, ret:%d\n", ret);
return ret;
}
ret = pci_set_power_state(pci_dev, PCI_D0);
if (ret) {
MHI_ERR("Failed to set PCI_D0 state, ret:%d\n", ret);
return ret;
}
ret = pci_enable_device(pci_dev);
if (ret) {
MHI_ERR("Failed to enable device, ret:%d\n", ret);
return ret;
}
ret = pci_load_and_free_saved_state(pci_dev, &arch_info->pcie_state);
if (ret)
MHI_LOG("Failed to load saved cfg state\n");
pci_restore_state(pci_dev);
pci_set_master(pci_dev);
return 0;
}
int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
struct mhi_link_info *cur_info = &mhi_cntrl->mhi_link_info;
int ret = 0;
MHI_LOG("Entered\n");
switch (mhi_dev->suspend_mode) {
case MHI_DEFAULT_SUSPEND:
ret = __mhi_arch_link_resume(mhi_cntrl);
break;
case MHI_FAST_LINK_OFF:
ret = msm_pcie_pm_control(MSM_PCIE_RESUME, mhi_cntrl->bus,
pci_dev, NULL, 0);
if (ret ||
cur_info->target_link_speed == PCI_EXP_LNKSTA_CLS_2_5GB)
break;
/*
* BW request from device isn't for gen 1 link speed, we can
* only print an error here.
*/
if (mhi_arch_pcie_scale_bw(mhi_cntrl, pci_dev, cur_info))
MHI_ERR(
"Failed to honor bw request: speed:0x%x width:0x%x\n",
cur_info->target_link_speed,
cur_info->target_link_width);
break;
case MHI_ACTIVE_STATE:
case MHI_FAST_LINK_ON:
break;
}
if (ret) {
MHI_ERR("Link training failed, ret:%d\n", ret);
return ret;
}
msm_pcie_l1ss_timeout_enable(pci_dev);
MHI_LOG("Exited\n");
return 0;
}

View File

@ -0,0 +1,941 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/
#include <asm/arch_timer.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/mhi.h>
#include "mhi_qcom.h"
struct firmware_info {
unsigned int dev_id;
const char *fw_image;
const char *edl_image;
};
static const struct firmware_info firmware_table[] = {
{.dev_id = 0x306, .fw_image = "sdx55m/sbl1.mbn"},
{.dev_id = 0x305, .fw_image = "sdx50m/sbl1.mbn"},
{.dev_id = 0x304, .fw_image = "sbl.mbn", .edl_image = "edl.mbn"},
/* default, set to debug.mbn */
{.fw_image = "debug.mbn"},
};
static int debug_mode;
int mhi_debugfs_trigger_m0(void *data, u64 val)
{
struct mhi_controller *mhi_cntrl = data;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
MHI_LOG("Trigger M3 Exit\n");
pm_runtime_get(&mhi_dev->pci_dev->dev);
pm_runtime_put(&mhi_dev->pci_dev->dev);
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m0_fops, NULL,
mhi_debugfs_trigger_m0, "%llu\n");
int mhi_debugfs_trigger_m3(void *data, u64 val)
{
struct mhi_controller *mhi_cntrl = data;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
MHI_LOG("Trigger M3 Entry\n");
pm_runtime_mark_last_busy(&mhi_dev->pci_dev->dev);
pm_request_autosuspend(&mhi_dev->pci_dev->dev);
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m3_fops, NULL,
mhi_debugfs_trigger_m3, "%llu\n");
void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
pm_runtime_mark_last_busy(&pci_dev->dev);
pm_runtime_dont_use_autosuspend(&pci_dev->dev);
pm_runtime_disable(&pci_dev->dev);
/* reset counter for lpm state changes */
mhi_dev->lpm_disable_depth = 0;
pci_free_irq_vectors(pci_dev);
kfree(mhi_cntrl->irq);
mhi_cntrl->irq = NULL;
iounmap(mhi_cntrl->regs);
mhi_cntrl->regs = NULL;
pci_clear_master(pci_dev);
pci_release_region(pci_dev, mhi_dev->resn);
pci_disable_device(pci_dev);
}
static int mhi_init_pci_dev(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
struct pci_dev *pci_dev = mhi_dev->pci_dev;
int ret;
resource_size_t len;
int i;
mhi_dev->resn = MHI_PCI_BAR_NUM;
ret = pci_assign_resource(pci_dev, mhi_dev->resn);
if (ret) {
MHI_ERR("Error assign pci resources, ret:%d\n", ret);
return ret;
}
ret = pci_enable_device(pci_dev);
if (ret) {
MHI_ERR("Error enabling device, ret:%d\n", ret);
goto error_enable_device;
}
ret = pci_request_region(pci_dev, mhi_dev->resn, "mhi");
if (ret) {
MHI_ERR("Error pci_request_region, ret:%d\n", ret);
goto error_request_region;
}
pci_set_master(pci_dev);
mhi_cntrl->base_addr = pci_resource_start(pci_dev, mhi_dev->resn);
len = pci_resource_len(pci_dev, mhi_dev->resn);
mhi_cntrl->regs = ioremap(mhi_cntrl->base_addr, len);
if (!mhi_cntrl->regs) {
MHI_ERR("Error ioremap region\n");
goto error_ioremap;
}
ret = pci_alloc_irq_vectors(pci_dev, mhi_cntrl->msi_required,
mhi_cntrl->msi_required, PCI_IRQ_MSI);
if (IS_ERR_VALUE((ulong)ret) || ret < mhi_cntrl->msi_required) {
MHI_ERR("Failed to enable MSI, ret:%d\n", ret);
goto error_req_msi;
}
mhi_cntrl->msi_allocated = ret;
mhi_cntrl->irq = kmalloc_array(mhi_cntrl->msi_allocated,
sizeof(*mhi_cntrl->irq), GFP_KERNEL);
if (!mhi_cntrl->irq) {
ret = -ENOMEM;
goto error_alloc_msi_vec;
}
for (i = 0; i < mhi_cntrl->msi_allocated; i++) {
mhi_cntrl->irq[i] = pci_irq_vector(pci_dev, i);
if (mhi_cntrl->irq[i] < 0) {
ret = mhi_cntrl->irq[i];
goto error_get_irq_vec;
}
}
dev_set_drvdata(&pci_dev->dev, mhi_cntrl);
/* configure runtime pm */
pm_runtime_set_autosuspend_delay(&pci_dev->dev, MHI_RPM_SUSPEND_TMR_MS);
pm_runtime_use_autosuspend(&pci_dev->dev);
pm_suspend_ignore_children(&pci_dev->dev, true);
/*
* pci framework will increment usage count (twice) before
* calling local device driver probe function.
* 1st pci.c pci_pm_init() calls pm_runtime_forbid
* 2nd pci-driver.c local_pci_probe calls pm_runtime_get_sync
* Framework expect pci device driver to call
* pm_runtime_put_noidle to decrement usage count after
* successful probe and and call pm_runtime_allow to enable
* runtime suspend.
*/
pm_runtime_mark_last_busy(&pci_dev->dev);
pm_runtime_put_noidle(&pci_dev->dev);
return 0;
error_get_irq_vec:
kfree(mhi_cntrl->irq);
mhi_cntrl->irq = NULL;
error_alloc_msi_vec:
pci_free_irq_vectors(pci_dev);
error_req_msi:
iounmap(mhi_cntrl->regs);
error_ioremap:
pci_clear_master(pci_dev);
error_request_region:
pci_disable_device(pci_dev);
error_enable_device:
pci_release_region(pci_dev, mhi_dev->resn);
return ret;
}
static int mhi_runtime_suspend(struct device *dev)
{
int ret = 0;
struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev);
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
MHI_LOG("Enter\n");
mutex_lock(&mhi_cntrl->pm_mutex);
if (!mhi_dev->powered_on) {
MHI_LOG("Not fully powered, return success\n");
mutex_unlock(&mhi_cntrl->pm_mutex);
return 0;
}
/* if drv is supported we will always go into drv */
if (mhi_dev->drv_supported) {
ret = mhi_pm_fast_suspend(mhi_cntrl, true);
mhi_dev->suspend_mode = MHI_FAST_LINK_OFF;
} else {
ret = mhi_pm_suspend(mhi_cntrl);
mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND;
/* regular suspend failed, probably a client has a vote */
if (ret == -EBUSY) {
ret = mhi_pm_fast_suspend(mhi_cntrl, false);
mhi_dev->suspend_mode = MHI_FAST_LINK_ON;
}
}
if (ret) {
MHI_LOG("Abort due to ret:%d\n", ret);
mhi_dev->suspend_mode = MHI_ACTIVE_STATE;
goto exit_runtime_suspend;
}
ret = mhi_arch_link_suspend(mhi_cntrl);
/* failed suspending link abort mhi suspend */
if (ret) {
MHI_LOG("Failed to suspend link, abort suspend\n");
if (mhi_dev->suspend_mode == MHI_DEFAULT_SUSPEND)
mhi_pm_resume(mhi_cntrl);
else
mhi_pm_fast_resume(mhi_cntrl,
mhi_dev->suspend_mode == MHI_FAST_LINK_OFF);
mhi_dev->suspend_mode = MHI_ACTIVE_STATE;
}
exit_runtime_suspend:
mutex_unlock(&mhi_cntrl->pm_mutex);
MHI_LOG("Exited with ret:%d\n", ret);
return (ret < 0) ? -EBUSY : 0;
}
static int mhi_runtime_idle(struct device *dev)
{
struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev);
MHI_LOG("Entered returning -EBUSY\n");
/*
* RPM framework during runtime resume always calls
* rpm_idle to see if device ready to suspend.
* If dev.power usage_count count is 0, rpm fw will call
* rpm_idle cb to see if device is ready to suspend.
* if cb return 0, or cb not defined the framework will
* assume device driver is ready to suspend;
* therefore, fw will schedule runtime suspend.
* In MHI power management, MHI host shall go to
* runtime suspend only after entering MHI State M2, even if
* usage count is 0. Return -EBUSY to disable automatic suspend.
*/
return -EBUSY;
}
static int mhi_runtime_resume(struct device *dev)
{
int ret = 0;
struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev);
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
MHI_LOG("Enter\n");
mutex_lock(&mhi_cntrl->pm_mutex);
if (!mhi_dev->powered_on) {
MHI_LOG("Not fully powered, return success\n");
mutex_unlock(&mhi_cntrl->pm_mutex);
return 0;
}
/* turn on link */
ret = mhi_arch_link_resume(mhi_cntrl);
if (ret)
goto rpm_resume_exit;
/* transition to M0 state */
if (mhi_dev->suspend_mode == MHI_DEFAULT_SUSPEND)
ret = mhi_pm_resume(mhi_cntrl);
else
ret = mhi_pm_fast_resume(mhi_cntrl,
mhi_dev->suspend_mode == MHI_FAST_LINK_OFF);
mhi_dev->suspend_mode = MHI_ACTIVE_STATE;
rpm_resume_exit:
mutex_unlock(&mhi_cntrl->pm_mutex);
MHI_LOG("Exited with :%d\n", ret);
return (ret < 0) ? -EBUSY : 0;
}
static int mhi_system_resume(struct device *dev)
{
return mhi_runtime_resume(dev);
}
int mhi_system_suspend(struct device *dev)
{
struct mhi_controller *mhi_cntrl = dev_get_drvdata(dev);
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
int ret;
MHI_LOG("Entered\n");
mutex_lock(&mhi_cntrl->pm_mutex);
if (!mhi_dev->powered_on) {
MHI_LOG("Not fully powered, return success\n");
mutex_unlock(&mhi_cntrl->pm_mutex);
return 0;
}
/*
* pci framework always makes a dummy vote to rpm
* framework to resume before calling system suspend
* hence usage count is minimum one
*/
if (atomic_read(&dev->power.usage_count) > 1) {
/*
* clients have requested to keep link on, try
* fast suspend. No need to notify clients since
* we will not be turning off the pcie link
*/
ret = mhi_pm_fast_suspend(mhi_cntrl, false);
mhi_dev->suspend_mode = MHI_FAST_LINK_ON;
} else {
/* if drv enable always do fast suspend */
if (mhi_dev->drv_supported) {
ret = mhi_pm_fast_suspend(mhi_cntrl, true);
mhi_dev->suspend_mode = MHI_FAST_LINK_OFF;
} else {
/* try normal suspend */
mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND;
ret = mhi_pm_suspend(mhi_cntrl);
/*
* normal suspend failed because we're busy, try
* fast suspend before aborting system suspend.
* this could happens if client has disabled
* device lpm but no active vote for PCIe from
* apps processor
*/
if (ret == -EBUSY) {
ret = mhi_pm_fast_suspend(mhi_cntrl, true);
mhi_dev->suspend_mode = MHI_FAST_LINK_ON;
}
}
}
if (ret) {
MHI_LOG("Abort due to ret:%d\n", ret);
mhi_dev->suspend_mode = MHI_ACTIVE_STATE;
goto exit_system_suspend;
}
ret = mhi_arch_link_suspend(mhi_cntrl);
/* failed suspending link abort mhi suspend */
if (ret) {
MHI_LOG("Failed to suspend link, abort suspend\n");
if (mhi_dev->suspend_mode == MHI_DEFAULT_SUSPEND)
mhi_pm_resume(mhi_cntrl);
else
mhi_pm_fast_resume(mhi_cntrl,
mhi_dev->suspend_mode == MHI_FAST_LINK_OFF);
mhi_dev->suspend_mode = MHI_ACTIVE_STATE;
}
exit_system_suspend:
mutex_unlock(&mhi_cntrl->pm_mutex);
MHI_LOG("Exit with ret:%d\n", ret);
return ret;
}
static int mhi_force_suspend(struct mhi_controller *mhi_cntrl)
{
int ret = -EIO;
const u32 delayms = 100;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms, delayms);
MHI_LOG("Entered\n");
mutex_lock(&mhi_cntrl->pm_mutex);
for (; itr; itr--) {
/*
* This function get called soon as device entered mission mode
* so most of the channels are still in disabled state. However,
* sbl channels are active and clients could be trying to close
* channels while we trying to suspend the link. So, we need to
* re-try if MHI is busy
*/
ret = mhi_pm_suspend(mhi_cntrl);
if (!ret || ret != -EBUSY)
break;
MHI_LOG("MHI busy, sleeping and retry\n");
msleep(delayms);
}
if (ret)
goto exit_force_suspend;
mhi_dev->suspend_mode = MHI_DEFAULT_SUSPEND;
ret = mhi_arch_link_suspend(mhi_cntrl);
exit_force_suspend:
MHI_LOG("Force suspend ret with %d\n", ret);
mutex_unlock(&mhi_cntrl->pm_mutex);
return ret;
}
/* checks if link is down */
static int mhi_link_status(struct mhi_controller *mhi_cntrl, void *priv)
{
struct mhi_dev *mhi_dev = priv;
u16 dev_id;
int ret;
/* try reading device id, if dev id don't match, link is down */
ret = pci_read_config_word(mhi_dev->pci_dev, PCI_DEVICE_ID, &dev_id);
return (ret || dev_id != mhi_cntrl->dev_id) ? -EIO : 0;
}
/* disable PCIe L1 */
static int mhi_lpm_disable(struct mhi_controller *mhi_cntrl, void *priv)
{
struct mhi_dev *mhi_dev = priv;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL;
u8 val;
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&mhi_dev->lpm_lock, flags);
/* L1 is already disabled */
if (mhi_dev->lpm_disable_depth) {
mhi_dev->lpm_disable_depth++;
goto lpm_disable_exit;
}
ret = pci_read_config_byte(pci_dev, lnkctl, &val);
if (ret) {
MHI_ERR("Error reading LNKCTL, ret:%d\n", ret);
goto lpm_disable_exit;
}
/* L1 is not supported, do not increment lpm_disable_depth */
if (unlikely(!(val & PCI_EXP_LNKCTL_ASPM_L1)))
goto lpm_disable_exit;
val &= ~PCI_EXP_LNKCTL_ASPM_L1;
ret = pci_write_config_byte(pci_dev, lnkctl, val);
if (ret) {
MHI_ERR("Error writing LNKCTL to disable LPM, ret:%d\n", ret);
goto lpm_disable_exit;
}
mhi_dev->lpm_disable_depth++;
lpm_disable_exit:
spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags);
return ret;
}
/* enable PCIe L1 */
static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv)
{
struct mhi_dev *mhi_dev = priv;
struct pci_dev *pci_dev = mhi_dev->pci_dev;
int lnkctl = pci_dev->pcie_cap + PCI_EXP_LNKCTL;
u8 val;
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&mhi_dev->lpm_lock, flags);
/*
* Exit if L1 is not supported or is already disabled or
* decrementing lpm_disable_depth still keeps it above 0
*/
if (!mhi_dev->lpm_disable_depth)
goto lpm_enable_exit;
if (mhi_dev->lpm_disable_depth > 1) {
mhi_dev->lpm_disable_depth--;
goto lpm_enable_exit;
}
ret = pci_read_config_byte(pci_dev, lnkctl, &val);
if (ret) {
MHI_ERR("Error reading LNKCTL, ret:%d\n", ret);
goto lpm_enable_exit;
}
val |= PCI_EXP_LNKCTL_ASPM_L1;
ret = pci_write_config_byte(pci_dev, lnkctl, val);
if (ret) {
MHI_ERR("Error writing LNKCTL to enable LPM, ret:%d\n", ret);
goto lpm_enable_exit;
}
mhi_dev->lpm_disable_depth = 0;
lpm_enable_exit:
spin_unlock_irqrestore(&mhi_dev->lpm_lock, flags);
return ret;
}
void mhi_qcom_store_hwinfo(struct mhi_controller *mhi_cntrl)
{
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
int i;
mhi_dev->serial_num = readl_relaxed(mhi_cntrl->bhi +
MHI_BHI_SERIAL_NUM_OFFS);
for (i = 0; i < ARRAY_SIZE(mhi_dev->oem_pk_hash); i++)
mhi_dev->oem_pk_hash[i] = readl_relaxed(mhi_cntrl->bhi +
MHI_BHI_OEMPKHASH(i));
}
static int mhi_qcom_power_up(struct mhi_controller *mhi_cntrl)
{
enum mhi_dev_state dev_state = mhi_get_mhi_state(mhi_cntrl);
const u32 delayus = 10;
int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms * 1000, delayus);
int ret;
/*
* It's possible device did not go thru a cold reset before
* power up and still in error state. If device in error state,
* we need to trigger a soft reset before continue with power
* up
*/
if (dev_state == MHI_STATE_SYS_ERR) {
mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);
while (itr--) {
dev_state = mhi_get_mhi_state(mhi_cntrl);
if (dev_state != MHI_STATE_SYS_ERR)
break;
usleep_range(delayus, delayus << 1);
}
/* device still in error state, abort power up */
if (dev_state == MHI_STATE_SYS_ERR)
return -EIO;
}
/* when coming out of SSR, initial states are not valid */
mhi_cntrl->ee = 0;
mhi_cntrl->power_down = false;
ret = mhi_arch_power_up(mhi_cntrl);
if (ret)
return ret;
ret = mhi_async_power_up(mhi_cntrl);
/* Update modem serial Info */
if (!ret)
mhi_qcom_store_hwinfo(mhi_cntrl);
/* power up create the dentry */
if (mhi_cntrl->dentry) {
debugfs_create_file("m0", 0444, mhi_cntrl->dentry, mhi_cntrl,
&debugfs_trigger_m0_fops);
debugfs_create_file("m3", 0444, mhi_cntrl->dentry, mhi_cntrl,
&debugfs_trigger_m3_fops);
}
return ret;
}
static int mhi_runtime_get(struct mhi_controller *mhi_cntrl, void *priv)
{
struct mhi_dev *mhi_dev = priv;
struct device *dev = &mhi_dev->pci_dev->dev;
return pm_runtime_get(dev);
}
static void mhi_runtime_put(struct mhi_controller *mhi_cntrl, void *priv)
{
struct mhi_dev *mhi_dev = priv;
struct device *dev = &mhi_dev->pci_dev->dev;
pm_runtime_put_noidle(dev);
}
static void mhi_status_cb(struct mhi_controller *mhi_cntrl,
void *priv,
enum MHI_CB reason)
{
struct mhi_dev *mhi_dev = priv;
struct device *dev = &mhi_dev->pci_dev->dev;
int ret;
switch (reason) {
case MHI_CB_IDLE:
MHI_LOG("Schedule runtime suspend\n");
pm_runtime_mark_last_busy(dev);
pm_request_autosuspend(dev);
break;
case MHI_CB_EE_MISSION_MODE:
/*
* we need to force a suspend so device can switch to
* mission mode pcie phy settings.
*/
pm_runtime_get(dev);
ret = mhi_force_suspend(mhi_cntrl);
if (!ret)
mhi_runtime_resume(dev);
pm_runtime_put(dev);
break;
default:
MHI_ERR("Unhandled cb:0x%x\n", reason);
}
}
/* capture host SoC XO time in ticks */
static u64 mhi_time_get(struct mhi_controller *mhi_cntrl, void *priv)
{
return arch_counter_get_cntvct();
}
static ssize_t timeout_ms_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct mhi_device *mhi_dev = to_mhi_device(dev);
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
/* buffer provided by sysfs has a minimum size of PAGE_SIZE */
return snprintf(buf, PAGE_SIZE, "%u\n", mhi_cntrl->timeout_ms);
}
static ssize_t timeout_ms_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
struct mhi_device *mhi_dev = to_mhi_device(dev);
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
u32 timeout_ms;
if (kstrtou32(buf, 0, &timeout_ms) < 0)
return -EINVAL;
mhi_cntrl->timeout_ms = timeout_ms;
return count;
}
static DEVICE_ATTR_RW(timeout_ms);
static ssize_t power_up_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
int ret;
struct mhi_device *mhi_dev = to_mhi_device(dev);
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
ret = mhi_qcom_power_up(mhi_cntrl);
if (ret)
return ret;
return count;
}
static DEVICE_ATTR_WO(power_up);
static ssize_t serial_info_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct mhi_device *mhi_device = to_mhi_device(dev);
struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
int n;
n = scnprintf(buf, PAGE_SIZE, "Serial Number:%u\n",
mhi_dev->serial_num);
return n;
}
static DEVICE_ATTR_RO(serial_info);
static ssize_t oempkhash_info_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct mhi_device *mhi_device = to_mhi_device(dev);
struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
int i, n = 0;
for (i = 0; i < ARRAY_SIZE(mhi_dev->oem_pk_hash); i++)
n += scnprintf(buf + n, PAGE_SIZE - n, "OEMPKHASH[%d]:%u\n",
i, mhi_dev->oem_pk_hash[i]);
return n;
}
static DEVICE_ATTR_RO(oempkhash_info);
static struct attribute *mhi_qcom_attrs[] = {
&dev_attr_timeout_ms.attr,
&dev_attr_power_up.attr,
&dev_attr_serial_info.attr,
&dev_attr_oempkhash_info.attr,
NULL
};
static const struct attribute_group mhi_qcom_group = {
.attrs = mhi_qcom_attrs,
};
static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev)
{
struct mhi_controller *mhi_cntrl;
struct mhi_dev *mhi_dev;
struct device_node *of_node = pci_dev->dev.of_node;
const struct firmware_info *firmware_info;
bool use_s1;
u32 addr_win[2];
const char *iommu_dma_type;
int ret, i;
if (!of_node)
return ERR_PTR(-ENODEV);
mhi_cntrl = mhi_alloc_controller(sizeof(*mhi_dev));
if (!mhi_cntrl)
return ERR_PTR(-ENOMEM);
mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
mhi_cntrl->domain = pci_domain_nr(pci_dev->bus);
mhi_cntrl->dev_id = pci_dev->device;
mhi_cntrl->bus = pci_dev->bus->number;
mhi_cntrl->slot = PCI_SLOT(pci_dev->devfn);
mhi_cntrl->of_node = of_node;
mhi_cntrl->iova_start = memblock_start_of_DRAM();
mhi_cntrl->iova_stop = memblock_end_of_DRAM();
of_node = of_parse_phandle(mhi_cntrl->of_node, "qcom,iommu-group", 0);
if (of_node) {
use_s1 = true;
/*
* s1 translation can be in bypass or fastmap mode
* if "qcom,iommu-dma" property is missing, we assume s1 is
* enabled and in default (no fastmap/atomic) mode
*/
ret = of_property_read_string(of_node, "qcom,iommu-dma",
&iommu_dma_type);
if (!ret && !strcmp("bypass", iommu_dma_type))
use_s1 = false;
/*
* if s1 translation enabled pull iova addr from dt using
* iommu-dma-addr-pool property specified addresses
*/
if (use_s1) {
ret = of_property_read_u32_array(of_node,
"qcom,iommu-dma-addr-pool",
addr_win, 2);
if (ret) {
of_node_put(of_node);
return ERR_PTR(-EINVAL);
}
/*
* If S1 is enabled, set MHI_CTRL start address to 0
* so we can use low level mapping api to map buffers
* outside of smmu domain
*/
mhi_cntrl->iova_start = 0;
mhi_cntrl->iova_stop = addr_win[0] + addr_win[1];
}
of_node_put(of_node);
}
mhi_dev->pci_dev = pci_dev;
spin_lock_init(&mhi_dev->lpm_lock);
/* setup power management apis */
mhi_cntrl->status_cb = mhi_status_cb;
mhi_cntrl->runtime_get = mhi_runtime_get;
mhi_cntrl->runtime_put = mhi_runtime_put;
mhi_cntrl->link_status = mhi_link_status;
mhi_cntrl->lpm_disable = mhi_lpm_disable;
mhi_cntrl->lpm_enable = mhi_lpm_enable;
mhi_cntrl->time_get = mhi_time_get;
mhi_cntrl->remote_timer_freq = 19200000;
ret = of_register_mhi_controller(mhi_cntrl);
if (ret)
goto error_register;
for (i = 0; i < ARRAY_SIZE(firmware_table); i++) {
firmware_info = firmware_table + i;
/* debug mode always use default */
if (!debug_mode && mhi_cntrl->dev_id == firmware_info->dev_id)
break;
}
mhi_cntrl->fw_image = firmware_info->fw_image;
mhi_cntrl->edl_image = firmware_info->edl_image;
if (sysfs_create_group(&mhi_cntrl->mhi_dev->dev.kobj, &mhi_qcom_group))
MHI_ERR("Error while creating the sysfs group\n");
return mhi_cntrl;
error_register:
mhi_free_controller(mhi_cntrl);
return ERR_PTR(-EINVAL);
}
int mhi_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *device_id)
{
struct mhi_controller *mhi_cntrl;
u32 domain = pci_domain_nr(pci_dev->bus);
u32 bus = pci_dev->bus->number;
u32 dev_id = pci_dev->device;
u32 slot = PCI_SLOT(pci_dev->devfn);
struct mhi_dev *mhi_dev;
int ret;
/* see if we already registered */
mhi_cntrl = mhi_bdf_to_controller(domain, bus, slot, dev_id);
if (!mhi_cntrl)
mhi_cntrl = mhi_register_controller(pci_dev);
if (IS_ERR(mhi_cntrl))
return PTR_ERR(mhi_cntrl);
mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
mhi_dev->powered_on = true;
ret = mhi_arch_pcie_init(mhi_cntrl);
if (ret)
return ret;
mhi_cntrl->dev = &mhi_dev->pci_dev->dev;
ret = dma_set_mask_and_coherent(mhi_cntrl->dev, DMA_BIT_MASK(64));
if (ret)
goto error_pci_probe;
ret = mhi_init_pci_dev(mhi_cntrl);
if (ret)
goto error_pci_probe;
/* start power up sequence */
if (!debug_mode) {
ret = mhi_qcom_power_up(mhi_cntrl);
if (ret)
goto error_power_up;
}
pm_runtime_mark_last_busy(&pci_dev->dev);
MHI_LOG("Return successful\n");
return 0;
error_power_up:
mhi_deinit_pci_dev(mhi_cntrl);
error_pci_probe:
mhi_arch_pcie_deinit(mhi_cntrl);
return ret;
}
static const struct dev_pm_ops pm_ops = {
SET_RUNTIME_PM_OPS(mhi_runtime_suspend,
mhi_runtime_resume,
mhi_runtime_idle)
SET_SYSTEM_SLEEP_PM_OPS(mhi_system_suspend, mhi_system_resume)
};
static struct pci_device_id mhi_pcie_device_id[] = {
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0300)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0301)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0302)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0303)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0304)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0305)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, 0x0306)},
{PCI_DEVICE(MHI_PCIE_VENDOR_ID, MHI_PCIE_DEBUG_ID)},
{0},
};
static struct pci_driver mhi_pcie_driver = {
.name = "mhi",
.id_table = mhi_pcie_device_id,
.probe = mhi_pci_probe,
.driver = {
.pm = &pm_ops
}
};
module_pci_driver(mhi_pcie_driver);
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("MHI_CORE");
MODULE_DESCRIPTION("MHI Host Driver");

View File

@ -0,0 +1,105 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/
#ifndef _MHI_QCOM_
#define _MHI_QCOM_
/* iova cfg bitmask */
#define MHI_SMMU_ATTACH BIT(0)
#define MHI_SMMU_S1_BYPASS BIT(1)
#define MHI_SMMU_FAST BIT(2)
#define MHI_SMMU_ATOMIC BIT(3)
#define MHI_SMMU_FORCE_COHERENT BIT(4)
#define MHI_PCIE_VENDOR_ID (0x17cb)
#define MHI_PCIE_DEBUG_ID (0xffff)
#define MHI_BHI_SERIAL_NUM_OFFS (0x40)
#define MHI_BHI_OEMPKHASH(n) (0x64 + (0x4 * (n)))
#define MHI_BHI_OEMPKHASH_SEG (16)
/* runtime suspend timer */
#define MHI_RPM_SUSPEND_TMR_MS (250)
#define MHI_PCI_BAR_NUM (0)
/* timesync time calculations */
#define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \
div_u64(mhi_cntrl->remote_timer_freq, 10000ULL)))
#define REMOTE_TICKS_TO_SEC(x) (div_u64((x), \
mhi_cntrl->remote_timer_freq))
#define REMOTE_TIME_REMAINDER_US(x) (REMOTE_TICKS_TO_US((x)) % \
(REMOTE_TICKS_TO_SEC((x)) * 1000000ULL))
extern const char * const mhi_ee_str[MHI_EE_MAX];
#define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee])
enum mhi_suspend_mode {
MHI_ACTIVE_STATE,
MHI_DEFAULT_SUSPEND,
MHI_FAST_LINK_OFF,
MHI_FAST_LINK_ON,
};
#define MHI_IS_SUSPENDED(mode) (mode)
struct mhi_dev {
struct pci_dev *pci_dev;
bool drv_supported;
int resn;
void *arch_info;
bool powered_on;
bool mdm_state;
dma_addr_t iova_start;
dma_addr_t iova_stop;
enum mhi_suspend_mode suspend_mode;
/* hardware info */
u32 serial_num;
u32 oem_pk_hash[MHI_BHI_OEMPKHASH_SEG];
unsigned int lpm_disable_depth;
/* lock to toggle low power modes */
spinlock_t lpm_lock;
};
void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl);
int mhi_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *device_id);
#ifdef CONFIG_ARCH_QCOM
int mhi_arch_power_up(struct mhi_controller *mhi_cntrl);
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl);
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl);
int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl);
int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl);
#else
static inline int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl)
{
return 0;
}
static inline void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl)
{
}
static inline int mhi_arch_link_suspend(struct mhi_controller *mhi_cntrl)
{
return 0;
}
static inline int mhi_arch_link_resume(struct mhi_controller *mhi_cntrl)
{
return 0;
}
static inline int mhi_arch_power_up(struct mhi_controller *mhi_cntrl)
{
return 0;
}
#endif
#endif /* _MHI_QCOM_ */

View File

@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MHI_BUS) += mhi_bus.o
mhi_bus-y := mhi_init.o mhi_main.o mhi_pm.o mhi_boot.o mhi_dtr.o

View File

@ -0,0 +1,668 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mhi.h>
#include "mhi_internal.h"
static void mhi_process_sfr(struct mhi_controller *mhi_cntrl,
struct file_info *info)
{
struct mhi_buf *mhi_buf = mhi_cntrl->rddm_image->mhi_buf;
u8 *sfr_buf, *file_offset = info->file_offset;
u32 file_size = info->file_size;
u32 rem_seg_len = info->rem_seg_len;
u32 seg_idx = info->seg_idx;
sfr_buf = kzalloc(file_size + 1, GFP_KERNEL);
if (!sfr_buf)
return;
while (file_size) {
/* file offset starting from seg base */
if (!rem_seg_len) {
file_offset = mhi_buf[seg_idx].buf;
if (file_size > mhi_buf[seg_idx].len)
rem_seg_len = mhi_buf[seg_idx].len;
else
rem_seg_len = file_size;
}
if (file_size <= rem_seg_len) {
memcpy(sfr_buf, file_offset, file_size);
break;
}
memcpy(sfr_buf, file_offset, rem_seg_len);
sfr_buf += rem_seg_len;
file_size -= rem_seg_len;
rem_seg_len = 0;
seg_idx++;
if (seg_idx == mhi_cntrl->rddm_image->entries) {
MHI_ERR("invalid size for SFR file\n");
goto err;
}
}
sfr_buf[info->file_size] = '\0';
/* force sfr string to log in kernel msg */
MHI_ERR("%s\n", sfr_buf);
err:
kfree(sfr_buf);
}
static int mhi_find_next_file_offset(struct mhi_controller *mhi_cntrl,
struct file_info *info, struct rddm_table_info *table_info)
{
struct mhi_buf *mhi_buf = mhi_cntrl->rddm_image->mhi_buf;
if (info->rem_seg_len >= table_info->size) {
info->file_offset += table_info->size;
info->rem_seg_len -= table_info->size;
return 0;
}
info->file_size = table_info->size - info->rem_seg_len;
info->rem_seg_len = 0;
/* iterate over segments until eof is reached */
while (info->file_size) {
info->seg_idx++;
if (info->seg_idx == mhi_cntrl->rddm_image->entries) {
MHI_ERR("invalid size for file %s\n",
table_info->file_name);
return -EINVAL;
}
if (info->file_size > mhi_buf[info->seg_idx].len) {
info->file_size -= mhi_buf[info->seg_idx].len;
} else {
info->file_offset = mhi_buf[info->seg_idx].buf +
info->file_size;
info->rem_seg_len = mhi_buf[info->seg_idx].len -
info->file_size;
info->file_size = 0;
}
}
return 0;
}
void mhi_dump_sfr(struct mhi_controller *mhi_cntrl)
{
struct mhi_buf *mhi_buf = mhi_cntrl->rddm_image->mhi_buf;
struct rddm_header *rddm_header =
(struct rddm_header *)mhi_buf->buf;
struct rddm_table_info *table_info;
struct file_info info;
u32 table_size, n;
memset(&info, 0, sizeof(info));
if (rddm_header->header_size > sizeof(*rddm_header) ||
rddm_header->header_size < 8) {
MHI_ERR("invalid reported header size %u\n",
rddm_header->header_size);
return;
}
table_size = (rddm_header->header_size - 8) / sizeof(*table_info);
if (!table_size) {
MHI_ERR("invalid rddm table size %u\n", table_size);
return;
}
info.file_offset = (u8 *)rddm_header + rddm_header->header_size;
info.rem_seg_len = mhi_buf[0].len - rddm_header->header_size;
for (n = 0; n < table_size; n++) {
table_info = &rddm_header->table_info[n];
if (!strcmp(table_info->file_name, "Q6-SFR.bin")) {
info.file_size = table_info->size;
mhi_process_sfr(mhi_cntrl, &info);
return;
}
if (mhi_find_next_file_offset(mhi_cntrl, &info, table_info))
return;
}
}
EXPORT_SYMBOL(mhi_dump_sfr);
/* setup rddm vector table for rddm transfer and program rxvec */
void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
struct image_info *img_info)
{
struct mhi_buf *mhi_buf = img_info->mhi_buf;
struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
void __iomem *base = mhi_cntrl->bhie;
u32 sequence_id;
int i = 0;
for (i = 0; i < img_info->entries - 1; i++, mhi_buf++, bhi_vec++) {
MHI_VERB("Setting vector:%pad size:%zu\n",
&mhi_buf->dma_addr, mhi_buf->len);
bhi_vec->dma_addr = mhi_buf->dma_addr;
bhi_vec->size = mhi_buf->len;
}
MHI_LOG("BHIe programming for RDDM\n");
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_HIGH_OFFS,
upper_32_bits(mhi_buf->dma_addr));
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECADDR_LOW_OFFS,
lower_32_bits(mhi_buf->dma_addr));
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
if (unlikely(!sequence_id))
sequence_id = 1;
mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS,
BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT,
sequence_id);
MHI_LOG("address:%pad len:0x%lx sequence:%u\n",
&mhi_buf->dma_addr, mhi_buf->len, sequence_id);
}
/* collect rddm during kernel panic */
static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl)
{
int ret;
u32 rx_status;
enum mhi_ee ee;
const u32 delayus = 5000;
u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
const u32 rddm_timeout_us = 200000;
int rddm_retry = rddm_timeout_us / delayus; /* time to enter rddm */
void __iomem *base = mhi_cntrl->bhie;
MHI_LOG("Entered with pm_state:%s dev_state:%s ee:%s\n",
to_mhi_pm_state_str(mhi_cntrl->pm_state),
TO_MHI_STATE_STR(mhi_cntrl->dev_state),
TO_MHI_EXEC_STR(mhi_cntrl->ee));
/*
* This should only be executing during a kernel panic, we expect all
* other cores to shutdown while we're collecting rddm buffer. After
* returning from this function, we expect device to reset.
*
* Normaly, we would read/write pm_state only after grabbing
* pm_lock, since we're in a panic, skipping it. Also there is no
* gurantee this state change would take effect since
* we're setting it w/o grabbing pmlock, it's best effort
*/
mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT;
/* update should take the effect immediately */
smp_wmb();
/*
* Make sure device is not already in RDDM.
* In case device asserts and a kernel panic follows, device will
* already be in RDDM. Do not trigger SYS ERR again and proceed with
* waiting for image download completion.
*/
ee = mhi_get_exec_env(mhi_cntrl);
if (ee != MHI_EE_RDDM) {
MHI_LOG("Trigger device into RDDM mode using SYSERR\n");
mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
MHI_LOG("Waiting for device to enter RDDM\n");
while (rddm_retry--) {
ee = mhi_get_exec_env(mhi_cntrl);
if (ee == MHI_EE_RDDM)
break;
udelay(delayus);
}
if (rddm_retry <= 0) {
/* Hardware reset; force device to enter rddm */
MHI_LOG(
"Did not enter RDDM, do a host req. reset\n");
mhi_write_reg(mhi_cntrl, mhi_cntrl->regs,
MHI_SOC_RESET_REQ_OFFSET,
MHI_SOC_RESET_REQ);
udelay(delayus);
}
ee = mhi_get_exec_env(mhi_cntrl);
}
MHI_LOG("Waiting for image download completion, current EE:%s\n",
TO_MHI_EXEC_STR(ee));
while (retry--) {
ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS,
BHIE_RXVECSTATUS_STATUS_BMSK,
BHIE_RXVECSTATUS_STATUS_SHFT,
&rx_status);
if (ret)
return -EIO;
if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) {
MHI_LOG("RDDM successfully collected\n");
return 0;
}
udelay(delayus);
}
ee = mhi_get_exec_env(mhi_cntrl);
ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status);
MHI_ERR("Did not complete RDDM transfer\n");
MHI_ERR("Current EE:%s\n", TO_MHI_EXEC_STR(ee));
MHI_ERR("RXVEC_STATUS:0x%x, ret:%d\n", rx_status, ret);
return -EIO;
}
/* download ramdump image from device */
int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic)
{
void __iomem *base = mhi_cntrl->bhie;
u32 rx_status;
if (in_panic)
return __mhi_download_rddm_in_panic(mhi_cntrl);
MHI_LOG("Waiting for image download completion\n");
/* waiting for image download completion */
wait_event_timeout(mhi_cntrl->state_event,
mhi_read_reg_field(mhi_cntrl, base,
BHIE_RXVECSTATUS_OFFS,
BHIE_RXVECSTATUS_STATUS_BMSK,
BHIE_RXVECSTATUS_STATUS_SHFT,
&rx_status) || rx_status,
msecs_to_jiffies(mhi_cntrl->timeout_ms));
return (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) ? 0 : -EIO;
}
EXPORT_SYMBOL(mhi_download_rddm_img);
static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
const struct mhi_buf *mhi_buf)
{
void __iomem *base = mhi_cntrl->bhie;
rwlock_t *pm_lock = &mhi_cntrl->pm_lock;
u32 tx_status;
read_lock_bh(pm_lock);
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
read_unlock_bh(pm_lock);
return -EIO;
}
MHI_LOG("Starting BHIe Programming\n");
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_HIGH_OFFS,
upper_32_bits(mhi_buf->dma_addr));
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECADDR_LOW_OFFS,
lower_32_bits(mhi_buf->dma_addr));
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len);
mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS,
BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT,
mhi_cntrl->sequence_id);
read_unlock_bh(pm_lock);
MHI_LOG("Upper:0x%x Lower:0x%x len:0x%lx sequence:%u\n",
upper_32_bits(mhi_buf->dma_addr),
lower_32_bits(mhi_buf->dma_addr),
mhi_buf->len, mhi_cntrl->sequence_id);
MHI_LOG("Waiting for image transfer completion\n");
/* waiting for image download completion */
wait_event_timeout(mhi_cntrl->state_event,
MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) ||
mhi_read_reg_field(mhi_cntrl, base,
BHIE_TXVECSTATUS_OFFS,
BHIE_TXVECSTATUS_STATUS_BMSK,
BHIE_TXVECSTATUS_STATUS_SHFT,
&tx_status) || tx_status,
msecs_to_jiffies(mhi_cntrl->timeout_ms));
if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
return -EIO;
return (tx_status == BHIE_TXVECSTATUS_STATUS_XFER_COMPL) ? 0 : -EIO;
}
static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl,
dma_addr_t dma_addr,
size_t size)
{
u32 tx_status, val;
int i, ret;
void __iomem *base = mhi_cntrl->bhi;
rwlock_t *pm_lock = &mhi_cntrl->pm_lock;
struct {
char *name;
u32 offset;
} error_reg[] = {
{ "ERROR_CODE", BHI_ERRCODE },
{ "ERROR_DBG1", BHI_ERRDBG1 },
{ "ERROR_DBG2", BHI_ERRDBG2 },
{ "ERROR_DBG3", BHI_ERRDBG3 },
{ NULL },
};
MHI_LOG("Starting BHI programming\n");
/* program start sbl download via bhi protocol */
read_lock_bh(pm_lock);
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
read_unlock_bh(pm_lock);
goto invalid_pm_state;
}
mhi_write_reg(mhi_cntrl, base, BHI_STATUS, 0);
mhi_write_reg(mhi_cntrl, base, BHI_IMGADDR_HIGH,
upper_32_bits(dma_addr));
mhi_write_reg(mhi_cntrl, base, BHI_IMGADDR_LOW,
lower_32_bits(dma_addr));
mhi_write_reg(mhi_cntrl, base, BHI_IMGSIZE, size);
mhi_cntrl->session_id = prandom_u32() & BHI_TXDB_SEQNUM_BMSK;
mhi_write_reg(mhi_cntrl, base, BHI_IMGTXDB, mhi_cntrl->session_id);
read_unlock_bh(pm_lock);
MHI_LOG("Waiting for image transfer completion\n");
/* waiting for image download completion */
wait_event_timeout(mhi_cntrl->state_event,
MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) ||
mhi_read_reg_field(mhi_cntrl, base, BHI_STATUS,
BHI_STATUS_MASK, BHI_STATUS_SHIFT,
&tx_status) || tx_status,
msecs_to_jiffies(mhi_cntrl->timeout_ms));
if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))
goto invalid_pm_state;
if (tx_status == BHI_STATUS_ERROR) {
MHI_ERR("Image transfer failed\n");
read_lock_bh(pm_lock);
if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) {
for (i = 0; error_reg[i].name; i++) {
ret = mhi_read_reg(mhi_cntrl, base,
error_reg[i].offset, &val);
if (ret)
break;
MHI_ERR("reg:%s value:0x%x\n",
error_reg[i].name, val);
}
}
read_unlock_bh(pm_lock);
goto invalid_pm_state;
}
return (tx_status == BHI_STATUS_SUCCESS) ? 0 : -ETIMEDOUT;
invalid_pm_state:
return -EIO;
}
void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
struct image_info *image_info)
{
int i;
struct mhi_buf *mhi_buf = image_info->mhi_buf;
for (i = 0; i < image_info->entries; i++, mhi_buf++)
mhi_free_contig_coherent(mhi_cntrl, mhi_buf->len, mhi_buf->buf,
mhi_buf->dma_addr);
kfree(image_info->mhi_buf);
kfree(image_info);
}
int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
struct image_info **image_info,
size_t alloc_size)
{
size_t seg_size = mhi_cntrl->seg_len;
/* requier additional entry for vec table */
int segments = DIV_ROUND_UP(alloc_size, seg_size) + 1;
int i;
struct image_info *img_info;
struct mhi_buf *mhi_buf;
MHI_LOG("Allocating bytes:%zu seg_size:%zu total_seg:%u\n",
alloc_size, seg_size, segments);
img_info = kzalloc(sizeof(*img_info), GFP_KERNEL);
if (!img_info)
return -ENOMEM;
/* allocate memory for entries */
img_info->mhi_buf = kcalloc(segments, sizeof(*img_info->mhi_buf),
GFP_KERNEL);
if (!img_info->mhi_buf)
goto error_alloc_mhi_buf;
/* allocate and populate vector table */
mhi_buf = img_info->mhi_buf;
for (i = 0; i < segments; i++, mhi_buf++) {
size_t vec_size = seg_size;
/* last entry is for vector table */
if (i == segments - 1)
vec_size = sizeof(struct bhi_vec_entry) * i;
mhi_buf->len = vec_size;
mhi_buf->buf = mhi_alloc_contig_coherent(mhi_cntrl, vec_size,
&mhi_buf->dma_addr, GFP_KERNEL);
if (!mhi_buf->buf)
goto error_alloc_segment;
MHI_LOG("Entry:%d Address:0x%llx size:%lu\n", i,
mhi_buf->dma_addr, mhi_buf->len);
}
img_info->bhi_vec = img_info->mhi_buf[segments - 1].buf;
img_info->entries = segments;
*image_info = img_info;
MHI_LOG("Successfully allocated bhi vec table\n");
return 0;
error_alloc_segment:
for (--i, --mhi_buf; i >= 0; i--, mhi_buf--)
mhi_free_contig_coherent(mhi_cntrl, mhi_buf->len, mhi_buf->buf,
mhi_buf->dma_addr);
error_alloc_mhi_buf:
kfree(img_info);
return -ENOMEM;
}
static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl,
const struct firmware *firmware,
struct image_info *img_info)
{
size_t remainder = firmware->size;
size_t to_cpy;
const u8 *buf = firmware->data;
int i = 0;
struct mhi_buf *mhi_buf = img_info->mhi_buf;
struct bhi_vec_entry *bhi_vec = img_info->bhi_vec;
while (remainder) {
MHI_ASSERT(i >= img_info->entries, "malformed vector table");
to_cpy = min(remainder, mhi_buf->len);
memcpy(mhi_buf->buf, buf, to_cpy);
bhi_vec->dma_addr = mhi_buf->dma_addr;
bhi_vec->size = to_cpy;
MHI_VERB("Setting Vector:0x%llx size: %llu\n",
bhi_vec->dma_addr, bhi_vec->size);
buf += to_cpy;
remainder -= to_cpy;
i++;
bhi_vec++;
mhi_buf++;
}
}
void mhi_fw_load_worker(struct work_struct *work)
{
int ret;
struct mhi_controller *mhi_cntrl;
const char *fw_name;
const struct firmware *firmware = NULL;
struct image_info *image_info;
void *buf;
dma_addr_t dma_addr;
size_t size;
mhi_cntrl = container_of(work, struct mhi_controller, fw_worker);
MHI_LOG("Waiting for device to enter PBL from EE:%s\n",
TO_MHI_EXEC_STR(mhi_cntrl->ee));
ret = wait_event_timeout(mhi_cntrl->state_event,
MHI_IN_PBL(mhi_cntrl->ee) ||
MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
msecs_to_jiffies(mhi_cntrl->timeout_ms));
if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
MHI_ERR("MHI is not in valid state\n");
return;
}
MHI_LOG("Device current EE:%s\n", TO_MHI_EXEC_STR(mhi_cntrl->ee));
/* if device in pthru, do reset to ready state transition */
if (mhi_cntrl->ee == MHI_EE_PTHRU)
goto fw_load_ee_pthru;
fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ?
mhi_cntrl->edl_image : mhi_cntrl->fw_image;
if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size ||
!mhi_cntrl->seg_len))) {
MHI_ERR("No firmware image defined or !sbl_size || !seg_len\n");
return;
}
ret = request_firmware(&firmware, fw_name, mhi_cntrl->dev);
if (ret) {
MHI_ERR("Error loading firmware, ret:%d\n", ret);
return;
}
size = (mhi_cntrl->fbc_download) ? mhi_cntrl->sbl_size : firmware->size;
/* the sbl size provided is maximum size, not necessarily image size */
if (size > firmware->size)
size = firmware->size;
buf = mhi_alloc_coherent(mhi_cntrl, size, &dma_addr, GFP_KERNEL);
if (!buf) {
MHI_ERR("Could not allocate memory for image\n");
release_firmware(firmware);
return;
}
/* load sbl image */
memcpy(buf, firmware->data, size);
ret = mhi_fw_load_sbl(mhi_cntrl, dma_addr, size);
mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);
if (!mhi_cntrl->fbc_download || ret || mhi_cntrl->ee == MHI_EE_EDL)
release_firmware(firmware);
/* error or in edl, we're done */
if (ret || mhi_cntrl->ee == MHI_EE_EDL)
return;
write_lock_irq(&mhi_cntrl->pm_lock);
mhi_cntrl->dev_state = MHI_STATE_RESET;
write_unlock_irq(&mhi_cntrl->pm_lock);
/*
* if we're doing fbc, populate vector tables while
* device transitioning into MHI READY state
*/
if (mhi_cntrl->fbc_download) {
ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image,
firmware->size);
if (ret) {
MHI_ERR("Error alloc size of %zu\n", firmware->size);
goto error_alloc_fw_table;
}
MHI_LOG("Copying firmware image into vector table\n");
/* load the firmware into BHIE vec table */
mhi_firmware_copy(mhi_cntrl, firmware, mhi_cntrl->fbc_image);
}
fw_load_ee_pthru:
/* transitioning into MHI RESET->READY state */
ret = mhi_ready_state_transition(mhi_cntrl);
MHI_LOG("To Reset->Ready PM_STATE:%s MHI_STATE:%s EE:%s, ret:%d\n",
to_mhi_pm_state_str(mhi_cntrl->pm_state),
TO_MHI_STATE_STR(mhi_cntrl->dev_state),
TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);
if (!mhi_cntrl->fbc_download)
return;
if (ret) {
MHI_ERR("Did not transition to READY state\n");
goto error_read;
}
/* wait for SBL event */
ret = wait_event_timeout(mhi_cntrl->state_event,
mhi_cntrl->ee == MHI_EE_SBL ||
MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state),
msecs_to_jiffies(mhi_cntrl->timeout_ms));
if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
MHI_ERR("MHI did not enter BHIE\n");
goto error_read;
}
/* start full firmware image download */
image_info = mhi_cntrl->fbc_image;
ret = mhi_fw_load_amss(mhi_cntrl,
/* last entry is vec table */
&image_info->mhi_buf[image_info->entries - 1]);
MHI_LOG("amss fw_load, ret:%d\n", ret);
release_firmware(firmware);
return;
error_read:
mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
mhi_cntrl->fbc_image = NULL;
error_alloc_fw_table:
release_firmware(firmware);
}

View File

@ -0,0 +1,227 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/termios.h>
#include <linux/wait.h>
#include <linux/mhi.h>
#include "mhi_internal.h"
struct dtr_ctrl_msg {
u32 preamble;
u32 msg_id;
u32 dest_id;
u32 size;
u32 msg;
} __packed;
#define CTRL_MAGIC (0x4C525443)
#define CTRL_MSG_DTR BIT(0)
#define CTRL_MSG_RTS BIT(1)
#define CTRL_MSG_DCD BIT(0)
#define CTRL_MSG_DSR BIT(1)
#define CTRL_MSG_RI BIT(3)
#define CTRL_HOST_STATE (0x10)
#define CTRL_DEVICE_STATE (0x11)
#define CTRL_GET_CHID(dtr) (dtr->dest_id & 0xFF)
static int mhi_dtr_tiocmset(struct mhi_controller *mhi_cntrl,
struct mhi_device *mhi_dev,
u32 tiocm)
{
struct dtr_ctrl_msg *dtr_msg = NULL;
struct mhi_chan *dtr_chan = mhi_cntrl->dtr_dev->ul_chan;
spinlock_t *res_lock = &mhi_dev->dev.devres_lock;
u32 cur_tiocm;
int ret = 0;
cur_tiocm = mhi_dev->tiocm & ~(TIOCM_CD | TIOCM_DSR | TIOCM_RI);
tiocm &= (TIOCM_DTR | TIOCM_RTS);
/* state did not changed */
if (cur_tiocm == tiocm)
return 0;
mutex_lock(&dtr_chan->mutex);
dtr_msg = kzalloc(sizeof(*dtr_msg), GFP_KERNEL);
if (!dtr_msg) {
ret = -ENOMEM;
goto tiocm_exit;
}
dtr_msg->preamble = CTRL_MAGIC;
dtr_msg->msg_id = CTRL_HOST_STATE;
dtr_msg->dest_id = mhi_dev->ul_chan_id;
dtr_msg->size = sizeof(u32);
if (tiocm & TIOCM_DTR)
dtr_msg->msg |= CTRL_MSG_DTR;
if (tiocm & TIOCM_RTS)
dtr_msg->msg |= CTRL_MSG_RTS;
reinit_completion(&dtr_chan->completion);
ret = mhi_queue_transfer(mhi_cntrl->dtr_dev, DMA_TO_DEVICE, dtr_msg,
sizeof(*dtr_msg), MHI_EOT);
if (ret)
goto tiocm_exit;
ret = wait_for_completion_timeout(&dtr_chan->completion,
msecs_to_jiffies(mhi_cntrl->timeout_ms));
if (!ret) {
MHI_ERR("Failed to receive transfer callback\n");
ret = -EIO;
goto tiocm_exit;
}
ret = 0;
spin_lock_irq(res_lock);
mhi_dev->tiocm &= ~(TIOCM_DTR | TIOCM_RTS);
mhi_dev->tiocm |= tiocm;
spin_unlock_irq(res_lock);
tiocm_exit:
kfree(dtr_msg);
mutex_unlock(&dtr_chan->mutex);
return ret;
}
long mhi_ioctl(struct mhi_device *mhi_dev, unsigned int cmd, unsigned long arg)
{
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
int ret;
/* ioctl not supported by this controller */
if (!mhi_cntrl->dtr_dev)
return -EIO;
switch (cmd) {
case TIOCMGET:
return mhi_dev->tiocm;
case TIOCMSET:
{
u32 tiocm;
ret = get_user(tiocm, (u32 __user *)arg);
if (ret)
return ret;
return mhi_dtr_tiocmset(mhi_cntrl, mhi_dev, tiocm);
}
default:
break;
}
return -ENOIOCTLCMD;
}
EXPORT_SYMBOL(mhi_ioctl);
static void mhi_dtr_dl_xfer_cb(struct mhi_device *mhi_dev,
struct mhi_result *mhi_result)
{
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
struct dtr_ctrl_msg *dtr_msg = mhi_result->buf_addr;
u32 chan;
spinlock_t *res_lock;
if (mhi_result->bytes_xferd != sizeof(*dtr_msg)) {
MHI_ERR("Unexpected length %zu received\n",
mhi_result->bytes_xferd);
return;
}
MHI_VERB("preamble:0x%x msg_id:%u dest_id:%u msg:0x%x\n",
dtr_msg->preamble, dtr_msg->msg_id, dtr_msg->dest_id,
dtr_msg->msg);
chan = CTRL_GET_CHID(dtr_msg);
if (chan >= mhi_cntrl->max_chan)
return;
mhi_dev = mhi_cntrl->mhi_chan[chan].mhi_dev;
if (!mhi_dev)
return;
res_lock = &mhi_dev->dev.devres_lock;
spin_lock_irq(res_lock);
mhi_dev->tiocm &= ~(TIOCM_CD | TIOCM_DSR | TIOCM_RI);
if (dtr_msg->msg & CTRL_MSG_DCD)
mhi_dev->tiocm |= TIOCM_CD;
if (dtr_msg->msg & CTRL_MSG_DSR)
mhi_dev->tiocm |= TIOCM_DSR;
if (dtr_msg->msg & CTRL_MSG_RI)
mhi_dev->tiocm |= TIOCM_RI;
spin_unlock_irq(res_lock);
/* Notify the update */
mhi_notify(mhi_dev, MHI_CB_DTR_SIGNAL);
}
static void mhi_dtr_ul_xfer_cb(struct mhi_device *mhi_dev,
struct mhi_result *mhi_result)
{
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
struct mhi_chan *dtr_chan = mhi_cntrl->dtr_dev->ul_chan;
MHI_VERB("Received with status:%d\n", mhi_result->transaction_status);
if (!mhi_result->transaction_status)
complete(&dtr_chan->completion);
}
static void mhi_dtr_remove(struct mhi_device *mhi_dev)
{
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
mhi_cntrl->dtr_dev = NULL;
}
static int mhi_dtr_probe(struct mhi_device *mhi_dev,
const struct mhi_device_id *id)
{
struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
int ret;
MHI_LOG("Enter for DTR control channel\n");
ret = mhi_prepare_for_transfer(mhi_dev);
if (!ret)
mhi_cntrl->dtr_dev = mhi_dev;
MHI_LOG("Exit with ret:%d\n", ret);
return ret;
}
static const struct mhi_device_id mhi_dtr_table[] = {
{ .chan = "IP_CTRL" },
{},
};
static struct mhi_driver mhi_dtr_driver = {
.id_table = mhi_dtr_table,
.remove = mhi_dtr_remove,
.probe = mhi_dtr_probe,
.ul_xfer_cb = mhi_dtr_ul_xfer_cb,
.dl_xfer_cb = mhi_dtr_dl_xfer_cb,
.driver = {
.name = "MHI_DTR",
.owner = THIS_MODULE,
}
};
int __init mhi_dtr_init(void)
{
return mhi_driver_register(&mhi_dtr_driver);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,940 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */
#include <linux/msm_rtb.h>
#ifndef _MHI_INT_H
#define _MHI_INT_H
extern struct bus_type mhi_bus_type;
/* MHI mmio register mapping */
#define PCI_INVALID_READ(val) (val == U32_MAX)
#define MHI_REG_SIZE (SZ_4K)
#define MHIREGLEN (0x0)
#define MHIREGLEN_MHIREGLEN_MASK (0xFFFFFFFF)
#define MHIREGLEN_MHIREGLEN_SHIFT (0)
#define MHIVER (0x8)
#define MHIVER_MHIVER_MASK (0xFFFFFFFF)
#define MHIVER_MHIVER_SHIFT (0)
#define MHICFG (0x10)
#define MHICFG_NHWER_MASK (0xFF000000)
#define MHICFG_NHWER_SHIFT (24)
#define MHICFG_NER_MASK (0xFF0000)
#define MHICFG_NER_SHIFT (16)
#define MHICFG_NHWCH_MASK (0xFF00)
#define MHICFG_NHWCH_SHIFT (8)
#define MHICFG_NCH_MASK (0xFF)
#define MHICFG_NCH_SHIFT (0)
#define CHDBOFF (0x18)
#define CHDBOFF_CHDBOFF_MASK (0xFFFFFFFF)
#define CHDBOFF_CHDBOFF_SHIFT (0)
#define ERDBOFF (0x20)
#define ERDBOFF_ERDBOFF_MASK (0xFFFFFFFF)
#define ERDBOFF_ERDBOFF_SHIFT (0)
#define BHIOFF (0x28)
#define BHIOFF_BHIOFF_MASK (0xFFFFFFFF)
#define BHIOFF_BHIOFF_SHIFT (0)
#define BHIEOFF (0x2C)
#define BHIEOFF_BHIEOFF_MASK (0xFFFFFFFF)
#define BHIEOFF_BHIEOFF_SHIFT (0)
#define DEBUGOFF (0x30)
#define DEBUGOFF_DEBUGOFF_MASK (0xFFFFFFFF)
#define DEBUGOFF_DEBUGOFF_SHIFT (0)
#define MHICTRL (0x38)
#define MHICTRL_MHISTATE_MASK (0x0000FF00)
#define MHICTRL_MHISTATE_SHIFT (8)
#define MHICTRL_RESET_MASK (0x2)
#define MHICTRL_RESET_SHIFT (1)
#define MHISTATUS (0x48)
#define MHISTATUS_MHISTATE_MASK (0x0000FF00)
#define MHISTATUS_MHISTATE_SHIFT (8)
#define MHISTATUS_SYSERR_MASK (0x4)
#define MHISTATUS_SYSERR_SHIFT (2)
#define MHISTATUS_READY_MASK (0x1)
#define MHISTATUS_READY_SHIFT (0)
#define CCABAP_LOWER (0x58)
#define CCABAP_LOWER_CCABAP_LOWER_MASK (0xFFFFFFFF)
#define CCABAP_LOWER_CCABAP_LOWER_SHIFT (0)
#define CCABAP_HIGHER (0x5C)
#define CCABAP_HIGHER_CCABAP_HIGHER_MASK (0xFFFFFFFF)
#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT (0)
#define ECABAP_LOWER (0x60)
#define ECABAP_LOWER_ECABAP_LOWER_MASK (0xFFFFFFFF)
#define ECABAP_LOWER_ECABAP_LOWER_SHIFT (0)
#define ECABAP_HIGHER (0x64)
#define ECABAP_HIGHER_ECABAP_HIGHER_MASK (0xFFFFFFFF)
#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT (0)
#define CRCBAP_LOWER (0x68)
#define CRCBAP_LOWER_CRCBAP_LOWER_MASK (0xFFFFFFFF)
#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT (0)
#define CRCBAP_HIGHER (0x6C)
#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK (0xFFFFFFFF)
#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT (0)
#define CRDB_LOWER (0x70)
#define CRDB_LOWER_CRDB_LOWER_MASK (0xFFFFFFFF)
#define CRDB_LOWER_CRDB_LOWER_SHIFT (0)
#define CRDB_HIGHER (0x74)
#define CRDB_HIGHER_CRDB_HIGHER_MASK (0xFFFFFFFF)
#define CRDB_HIGHER_CRDB_HIGHER_SHIFT (0)
#define MHICTRLBASE_LOWER (0x80)
#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK (0xFFFFFFFF)
#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT (0)
#define MHICTRLBASE_HIGHER (0x84)
#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK (0xFFFFFFFF)
#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT (0)
#define MHICTRLLIMIT_LOWER (0x88)
#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK (0xFFFFFFFF)
#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT (0)
#define MHICTRLLIMIT_HIGHER (0x8C)
#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK (0xFFFFFFFF)
#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT (0)
#define MHIDATABASE_LOWER (0x98)
#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK (0xFFFFFFFF)
#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT (0)
#define MHIDATABASE_HIGHER (0x9C)
#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK (0xFFFFFFFF)
#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT (0)
#define MHIDATALIMIT_LOWER (0xA0)
#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK (0xFFFFFFFF)
#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT (0)
#define MHIDATALIMIT_HIGHER (0xA4)
#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF)
#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0)
/* Host request register */
#define MHI_SOC_RESET_REQ_OFFSET (0xB0)
#define MHI_SOC_RESET_REQ BIT(0)
/* MHI misc capability registers */
#define MISC_OFFSET (0x24)
#define MISC_CAP_MASK (0xFFFFFFFF)
#define MISC_CAP_SHIFT (0)
#define CAP_CAPID_MASK (0xFF000000)
#define CAP_CAPID_SHIFT (24)
#define CAP_NEXT_CAP_MASK (0x00FFF000)
#define CAP_NEXT_CAP_SHIFT (12)
/* MHI Timesync offsets */
#define TIMESYNC_CFG_OFFSET (0x00)
#define TIMESYNC_CFG_CAPID_MASK (CAP_CAPID_MASK)
#define TIMESYNC_CFG_CAPID_SHIFT (CAP_CAPID_SHIFT)
#define TIMESYNC_CFG_NEXT_OFF_MASK (CAP_NEXT_CAP_MASK)
#define TIMESYNC_CFG_NEXT_OFF_SHIFT (CAP_NEXT_CAP_SHIFT)
#define TIMESYNC_CFG_NUMCMD_MASK (0xFF)
#define TIMESYNC_CFG_NUMCMD_SHIFT (0)
#define TIMESYNC_DB_OFFSET (0x4)
#define TIMESYNC_TIME_LOW_OFFSET (0x8)
#define TIMESYNC_TIME_HIGH_OFFSET (0xC)
#define TIMESYNC_CAP_ID (2)
/* MHI Bandwidth scaling offsets */
#define BW_SCALE_CFG_OFFSET (0x04)
#define BW_SCALE_CFG_CHAN_DB_ID_MASK (0xFE000000)
#define BW_SCALE_CFG_CHAN_DB_ID_SHIFT (25)
#define BW_SCALE_CFG_ENABLED_MASK (0x01000000)
#define BW_SCALE_CFG_ENABLED_SHIFT (24)
#define BW_SCALE_CFG_ER_ID_MASK (0x00F80000)
#define BW_SCALE_CFG_ER_ID_SHIFT (19)
#define BW_SCALE_CAP_ID (3)
/* MHI BHI offfsets */
#define BHI_BHIVERSION_MINOR (0x00)
#define BHI_BHIVERSION_MAJOR (0x04)
#define BHI_IMGADDR_LOW (0x08)
#define BHI_IMGADDR_HIGH (0x0C)
#define BHI_IMGSIZE (0x10)
#define BHI_RSVD1 (0x14)
#define BHI_IMGTXDB (0x18)
#define BHI_TXDB_SEQNUM_BMSK (0x3FFFFFFF)
#define BHI_TXDB_SEQNUM_SHFT (0)
#define BHI_RSVD2 (0x1C)
#define BHI_INTVEC (0x20)
#define BHI_RSVD3 (0x24)
#define BHI_EXECENV (0x28)
#define BHI_STATUS (0x2C)
#define BHI_ERRCODE (0x30)
#define BHI_ERRDBG1 (0x34)
#define BHI_ERRDBG2 (0x38)
#define BHI_ERRDBG3 (0x3C)
#define BHI_SERIALNU (0x40)
#define BHI_SBLANTIROLLVER (0x44)
#define BHI_NUMSEG (0x48)
#define BHI_MSMHWID(n) (0x4C + (0x4 * n))
#define BHI_OEMPKHASH(n) (0x64 + (0x4 * n))
#define BHI_RSVD5 (0xC4)
#define BHI_STATUS_MASK (0xC0000000)
#define BHI_STATUS_SHIFT (30)
#define BHI_STATUS_ERROR (3)
#define BHI_STATUS_SUCCESS (2)
#define BHI_STATUS_RESET (0)
/* MHI BHIE offsets */
#define BHIE_MSMSOCID_OFFS (0x0000)
#define BHIE_TXVECADDR_LOW_OFFS (0x002C)
#define BHIE_TXVECADDR_HIGH_OFFS (0x0030)
#define BHIE_TXVECSIZE_OFFS (0x0034)
#define BHIE_TXVECDB_OFFS (0x003C)
#define BHIE_TXVECDB_SEQNUM_BMSK (0x3FFFFFFF)
#define BHIE_TXVECDB_SEQNUM_SHFT (0)
#define BHIE_TXVECSTATUS_OFFS (0x0044)
#define BHIE_TXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF)
#define BHIE_TXVECSTATUS_SEQNUM_SHFT (0)
#define BHIE_TXVECSTATUS_STATUS_BMSK (0xC0000000)
#define BHIE_TXVECSTATUS_STATUS_SHFT (30)
#define BHIE_TXVECSTATUS_STATUS_RESET (0x00)
#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL (0x02)
#define BHIE_TXVECSTATUS_STATUS_ERROR (0x03)
#define BHIE_RXVECADDR_LOW_OFFS (0x0060)
#define BHIE_RXVECADDR_HIGH_OFFS (0x0064)
#define BHIE_RXVECSIZE_OFFS (0x0068)
#define BHIE_RXVECDB_OFFS (0x0070)
#define BHIE_RXVECDB_SEQNUM_BMSK (0x3FFFFFFF)
#define BHIE_RXVECDB_SEQNUM_SHFT (0)
#define BHIE_RXVECSTATUS_OFFS (0x0078)
#define BHIE_RXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF)
#define BHIE_RXVECSTATUS_SEQNUM_SHFT (0)
#define BHIE_RXVECSTATUS_STATUS_BMSK (0xC0000000)
#define BHIE_RXVECSTATUS_STATUS_SHFT (30)
#define BHIE_RXVECSTATUS_STATUS_RESET (0x00)
#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL (0x02)
#define BHIE_RXVECSTATUS_STATUS_ERROR (0x03)
#define SOC_HW_VERSION_OFFS (0x224)
#define SOC_HW_VERSION_FAM_NUM_BMSK (0xF0000000)
#define SOC_HW_VERSION_FAM_NUM_SHFT (28)
#define SOC_HW_VERSION_DEV_NUM_BMSK (0x0FFF0000)
#define SOC_HW_VERSION_DEV_NUM_SHFT (16)
#define SOC_HW_VERSION_MAJOR_VER_BMSK (0x0000FF00)
#define SOC_HW_VERSION_MAJOR_VER_SHFT (8)
#define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF)
#define SOC_HW_VERSION_MINOR_VER_SHFT (0)
/* timesync time calculations */
#define LOCAL_TICKS_TO_US(x) (div_u64((x) * 100ULL, \
div_u64(mhi_cntrl->local_timer_freq, 10000ULL)))
#define REMOTE_TICKS_TO_US(x) (div_u64((x) * 100ULL, \
div_u64(mhi_cntrl->remote_timer_freq, 10000ULL)))
struct mhi_event_ctxt {
u32 reserved : 8;
u32 intmodc : 8;
u32 intmodt : 16;
u32 ertype;
u32 msivec;
u64 rbase __packed __aligned(4);
u64 rlen __packed __aligned(4);
u64 rp __packed __aligned(4);
u64 wp __packed __aligned(4);
};
struct mhi_chan_ctxt {
u32 chstate : 8;
u32 brstmode : 2;
u32 pollcfg : 6;
u32 reserved : 16;
u32 chtype;
u32 erindex;
u64 rbase __packed __aligned(4);
u64 rlen __packed __aligned(4);
u64 rp __packed __aligned(4);
u64 wp __packed __aligned(4);
};
struct mhi_cmd_ctxt {
u32 reserved0;
u32 reserved1;
u32 reserved2;
u64 rbase __packed __aligned(4);
u64 rlen __packed __aligned(4);
u64 rp __packed __aligned(4);
u64 wp __packed __aligned(4);
};
struct mhi_tre {
u64 ptr;
u32 dword[2];
};
struct bhi_vec_entry {
u64 dma_addr;
u64 size;
};
enum mhi_cmd_type {
MHI_CMD_TYPE_NOP = 1,
MHI_CMD_TYPE_RESET = 16,
MHI_CMD_TYPE_STOP = 17,
MHI_CMD_TYPE_START = 18,
MHI_CMD_TYPE_TSYNC = 24,
};
/* no operation command */
#define MHI_TRE_CMD_NOOP_PTR (0)
#define MHI_TRE_CMD_NOOP_DWORD0 (0)
#define MHI_TRE_CMD_NOOP_DWORD1 (MHI_CMD_TYPE_NOP << 16)
/* channel reset command */
#define MHI_TRE_CMD_RESET_PTR (0)
#define MHI_TRE_CMD_RESET_DWORD0 (0)
#define MHI_TRE_CMD_RESET_DWORD1(chid) ((chid << 24) | \
(MHI_CMD_TYPE_RESET << 16))
/* channel stop command */
#define MHI_TRE_CMD_STOP_PTR (0)
#define MHI_TRE_CMD_STOP_DWORD0 (0)
#define MHI_TRE_CMD_STOP_DWORD1(chid) ((chid << 24) | (MHI_CMD_TYPE_STOP << 16))
/* channel start command */
#define MHI_TRE_CMD_START_PTR (0)
#define MHI_TRE_CMD_START_DWORD0 (0)
#define MHI_TRE_CMD_START_DWORD1(chid) ((chid << 24) | \
(MHI_CMD_TYPE_START << 16))
/* time sync cfg command */
#define MHI_TRE_CMD_TSYNC_CFG_PTR (0)
#define MHI_TRE_CMD_TSYNC_CFG_DWORD0 (0)
#define MHI_TRE_CMD_TSYNC_CFG_DWORD1(er) ((MHI_CMD_TYPE_TSYNC << 16) | \
(er << 24))
#define MHI_TRE_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF)
#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF)
/* event descriptor macros */
#define MHI_TRE_EV_PTR(ptr) (ptr)
#define MHI_TRE_EV_DWORD0(code, len) ((code << 24) | len)
#define MHI_TRE_EV_DWORD1(chid, type) ((chid << 24) | (type << 16))
#define MHI_TRE_GET_EV_PTR(tre) ((tre)->ptr)
#define MHI_TRE_GET_EV_CODE(tre) (((tre)->dword[0] >> 24) & 0xFF)
#define MHI_TRE_GET_EV_LEN(tre) ((tre)->dword[0] & 0xFFFF)
#define MHI_TRE_GET_EV_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF)
#define MHI_TRE_GET_EV_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF)
#define MHI_TRE_GET_EV_STATE(tre) (((tre)->dword[0] >> 24) & 0xFF)
#define MHI_TRE_GET_EV_EXECENV(tre) (((tre)->dword[0] >> 24) & 0xFF)
#define MHI_TRE_GET_EV_TSYNC_SEQ(tre) ((tre)->dword[0])
#define MHI_TRE_GET_EV_TIME(tre) ((tre)->ptr)
#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits((tre)->ptr)
#define MHI_TRE_GET_EV_VEID(tre) (((tre)->dword[0] >> 16) & 0xFF)
#define MHI_TRE_GET_EV_LINKSPEED(tre) (((tre)->dword[1] >> 24) & 0xFF)
#define MHI_TRE_GET_EV_LINKWIDTH(tre) ((tre)->dword[0] & 0xFF)
#define MHI_TRE_GET_EV_BW_REQ_SEQ(tre) (((tre)->dword[0] >> 8) & 0xFF)
/* transfer descriptor macros */
#define MHI_TRE_DATA_PTR(ptr) (ptr)
#define MHI_TRE_DATA_DWORD0(len) (len & MHI_MAX_MTU)
#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 10) \
| (ieot << 9) | (ieob << 8) | chain)
/* rsc transfer descriptor macros */
#define MHI_RSCTRE_DATA_PTR(ptr, len) (((u64)len << 48) | ptr)
#define MHI_RSCTRE_DATA_DWORD0(cookie) (cookie)
#define MHI_RSCTRE_DATA_DWORD1 (MHI_PKT_TYPE_COALESCING << 16)
enum MHI_CMD {
MHI_CMD_RESET_CHAN,
MHI_CMD_START_CHAN,
MHI_CMD_STOP_CHAN,
MHI_CMD_TIMSYNC_CFG,
};
enum MHI_PKT_TYPE {
MHI_PKT_TYPE_INVALID = 0x0,
MHI_PKT_TYPE_NOOP_CMD = 0x1,
MHI_PKT_TYPE_TRANSFER = 0x2,
MHI_PKT_TYPE_COALESCING = 0x8,
MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10,
MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11,
MHI_PKT_TYPE_START_CHAN_CMD = 0x12,
MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20,
MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21,
MHI_PKT_TYPE_TX_EVENT = 0x22,
MHI_PKT_TYPE_RSC_TX_EVENT = 0x28,
MHI_PKT_TYPE_EE_EVENT = 0x40,
MHI_PKT_TYPE_TSYNC_EVENT = 0x48,
MHI_PKT_TYPE_BW_REQ_EVENT = 0x50,
MHI_PKT_TYPE_STALE_EVENT, /* internal event */
};
/* MHI transfer completion events */
enum MHI_EV_CCS {
MHI_EV_CC_INVALID = 0x0,
MHI_EV_CC_SUCCESS = 0x1,
MHI_EV_CC_EOT = 0x2,
MHI_EV_CC_OVERFLOW = 0x3,
MHI_EV_CC_EOB = 0x4,
MHI_EV_CC_OOB = 0x5,
MHI_EV_CC_DB_MODE = 0x6,
MHI_EV_CC_UNDEFINED_ERR = 0x10,
MHI_EV_CC_BAD_TRE = 0x11,
};
enum MHI_CH_STATE {
MHI_CH_STATE_DISABLED = 0x0,
MHI_CH_STATE_ENABLED = 0x1,
MHI_CH_STATE_RUNNING = 0x2,
MHI_CH_STATE_SUSPENDED = 0x3,
MHI_CH_STATE_STOP = 0x4,
MHI_CH_STATE_ERROR = 0x5,
};
enum MHI_BRSTMODE {
MHI_BRSTMODE_DISABLE = 0x2,
MHI_BRSTMODE_ENABLE = 0x3,
};
#define MHI_INVALID_BRSTMODE(mode) (mode != MHI_BRSTMODE_DISABLE && \
mode != MHI_BRSTMODE_ENABLE)
extern const char * const mhi_ee_str[MHI_EE_MAX];
#define TO_MHI_EXEC_STR(ee) (((ee) >= MHI_EE_MAX) ? \
"INVALID_EE" : mhi_ee_str[ee])
#define MHI_IN_PBL(ee) (ee == MHI_EE_PBL || ee == MHI_EE_PTHRU || \
ee == MHI_EE_EDL)
#define MHI_IN_MISSION_MODE(ee) (ee == MHI_EE_AMSS || ee == MHI_EE_WFW)
enum MHI_ST_TRANSITION {
MHI_ST_TRANSITION_PBL,
MHI_ST_TRANSITION_READY,
MHI_ST_TRANSITION_SBL,
MHI_ST_TRANSITION_MISSION_MODE,
MHI_ST_TRANSITION_DISABLE,
MHI_ST_TRANSITION_MAX,
};
extern const char * const mhi_state_tran_str[MHI_ST_TRANSITION_MAX];
#define TO_MHI_STATE_TRANS_STR(state) (((state) >= MHI_ST_TRANSITION_MAX) ? \
"INVALID_STATE" : mhi_state_tran_str[state])
extern const char * const mhi_state_str[MHI_STATE_MAX];
#define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \
!mhi_state_str[state]) ? \
"INVALID_STATE" : mhi_state_str[state])
extern const char * const mhi_log_level_str[MHI_MSG_LVL_MAX];
#define TO_MHI_LOG_LEVEL_STR(level) ((level >= MHI_MSG_LVL_MAX || \
!mhi_log_level_str[level]) ? \
"Mask all" : mhi_log_level_str[level])
enum {
MHI_PM_BIT_DISABLE,
MHI_PM_BIT_POR,
MHI_PM_BIT_M0,
MHI_PM_BIT_M2,
MHI_PM_BIT_M3_ENTER,
MHI_PM_BIT_M3,
MHI_PM_BIT_M3_EXIT,
MHI_PM_BIT_FW_DL_ERR,
MHI_PM_BIT_DEVICE_ERR_DETECT,
MHI_PM_BIT_SYS_ERR_DETECT,
MHI_PM_BIT_SYS_ERR_PROCESS,
MHI_PM_BIT_SHUTDOWN_PROCESS,
MHI_PM_BIT_LD_ERR_FATAL_DETECT,
MHI_PM_BIT_SHUTDOWN_NO_ACCESS,
MHI_PM_BIT_MAX
};
/* internal power states */
enum MHI_PM_STATE {
MHI_PM_DISABLE = BIT(MHI_PM_BIT_DISABLE), /* MHI is not enabled */
MHI_PM_POR = BIT(MHI_PM_BIT_POR), /* reset state */
MHI_PM_M0 = BIT(MHI_PM_BIT_M0),
MHI_PM_M2 = BIT(MHI_PM_BIT_M2),
MHI_PM_M3_ENTER = BIT(MHI_PM_BIT_M3_ENTER),
MHI_PM_M3 = BIT(MHI_PM_BIT_M3),
MHI_PM_M3_EXIT = BIT(MHI_PM_BIT_M3_EXIT),
/* firmware download failure state */
MHI_PM_FW_DL_ERR = BIT(MHI_PM_BIT_FW_DL_ERR),
/* error or shutdown detected or processing state */
MHI_PM_DEVICE_ERR_DETECT = BIT(MHI_PM_BIT_DEVICE_ERR_DETECT),
MHI_PM_SYS_ERR_DETECT = BIT(MHI_PM_BIT_SYS_ERR_DETECT),
MHI_PM_SYS_ERR_PROCESS = BIT(MHI_PM_BIT_SYS_ERR_PROCESS),
MHI_PM_SHUTDOWN_PROCESS = BIT(MHI_PM_BIT_SHUTDOWN_PROCESS),
/* link not accessible */
MHI_PM_LD_ERR_FATAL_DETECT = BIT(MHI_PM_BIT_LD_ERR_FATAL_DETECT),
MHI_PM_SHUTDOWN_NO_ACCESS = BIT(MHI_PM_BIT_SHUTDOWN_NO_ACCESS),
};
#define MHI_REG_ACCESS_VALID(pm_state) ((pm_state & (MHI_PM_POR | MHI_PM_M0 | \
MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \
MHI_PM_DEVICE_ERR_DETECT | MHI_PM_SYS_ERR_DETECT | \
MHI_PM_SYS_ERR_PROCESS | MHI_PM_SHUTDOWN_PROCESS | \
MHI_PM_FW_DL_ERR)))
#define MHI_PM_IN_ERROR_STATE(pm_state) (pm_state >= MHI_PM_FW_DL_ERR)
#define MHI_PM_IN_FATAL_STATE(pm_state) (pm_state >= MHI_PM_LD_ERR_FATAL_DETECT)
#define MHI_DB_ACCESS_VALID(mhi_cntrl) (mhi_cntrl->pm_state & \
mhi_cntrl->db_access)
#define MHI_WAKE_DB_CLEAR_VALID(pm_state) (pm_state & (MHI_PM_M0 | \
MHI_PM_M2 | MHI_PM_M3_EXIT))
#define MHI_WAKE_DB_SET_VALID(pm_state) (pm_state & MHI_PM_M2)
#define MHI_WAKE_DB_FORCE_SET_VALID(pm_state) MHI_WAKE_DB_CLEAR_VALID(pm_state)
#define MHI_EVENT_ACCESS_INVALID(pm_state) (pm_state == MHI_PM_DISABLE || \
MHI_PM_IN_ERROR_STATE(pm_state))
#define MHI_PM_IN_SUSPEND_STATE(pm_state) (pm_state & \
(MHI_PM_M3_ENTER | MHI_PM_M3))
/* accepted buffer type for the channel */
enum MHI_XFER_TYPE {
MHI_XFER_BUFFER,
MHI_XFER_SKB,
MHI_XFER_SCLIST,
MHI_XFER_NOP, /* CPU offload channel, host does not accept transfer */
MHI_XFER_DMA, /* receive dma address, already mapped by client */
MHI_XFER_RSC_DMA, /* RSC type, accept premapped buffer */
};
#define NR_OF_CMD_RINGS (1)
#define CMD_EL_PER_RING (128)
#define PRIMARY_CMD_RING (0)
#define MHI_BW_SCALE_CHAN_DB (126)
#define MHI_DEV_WAKE_DB (127)
#define MHI_MAX_MTU (0xffff)
#define MHI_BW_SCALE_SETUP(er_index) ((MHI_BW_SCALE_CHAN_DB << \
BW_SCALE_CFG_CHAN_DB_ID_SHIFT) & BW_SCALE_CFG_CHAN_DB_ID_MASK | \
(1 << BW_SCALE_CFG_ENABLED_SHIFT) & BW_SCALE_CFG_ENABLED_MASK | \
((er_index) << BW_SCALE_CFG_ER_ID_SHIFT) & BW_SCALE_CFG_ER_ID_MASK)
#define MHI_BW_SCALE_RESULT(status, seq) ((status & 0xF) << 8 | (seq & 0xFF))
#define MHI_BW_SCALE_NACK 0xF
enum MHI_ER_TYPE {
MHI_ER_TYPE_INVALID = 0x0,
MHI_ER_TYPE_VALID = 0x1,
};
enum mhi_er_priority {
MHI_ER_PRIORITY_HIGH,
MHI_ER_PRIORITY_MEDIUM,
MHI_ER_PRIORITY_LOW,
};
#define IS_MHI_ER_PRIORITY_LOW(ev) (ev->priority >= MHI_ER_PRIORITY_LOW)
#define IS_MHI_ER_PRIORITY_HIGH(ev) (ev->priority == MHI_ER_PRIORITY_HIGH)
enum mhi_er_data_type {
MHI_ER_DATA_ELEMENT_TYPE,
MHI_ER_CTRL_ELEMENT_TYPE,
MHI_ER_TSYNC_ELEMENT_TYPE,
MHI_ER_BW_SCALE_ELEMENT_TYPE,
MHI_ER_DATA_TYPE_MAX = MHI_ER_BW_SCALE_ELEMENT_TYPE,
};
enum mhi_ch_ee_mask {
MHI_CH_EE_PBL = BIT(MHI_EE_PBL),
MHI_CH_EE_SBL = BIT(MHI_EE_SBL),
MHI_CH_EE_AMSS = BIT(MHI_EE_AMSS),
MHI_CH_EE_RDDM = BIT(MHI_EE_RDDM),
MHI_CH_EE_PTHRU = BIT(MHI_EE_PTHRU),
MHI_CH_EE_WFW = BIT(MHI_EE_WFW),
MHI_CH_EE_EDL = BIT(MHI_EE_EDL),
};
enum mhi_ch_type {
MHI_CH_TYPE_INVALID = 0,
MHI_CH_TYPE_OUTBOUND = DMA_TO_DEVICE,
MHI_CH_TYPE_INBOUND = DMA_FROM_DEVICE,
MHI_CH_TYPE_INBOUND_COALESCED = 3,
};
struct db_cfg {
bool reset_req;
bool db_mode;
u32 pollcfg;
enum MHI_BRSTMODE brstmode;
dma_addr_t db_val;
void (*process_db)(struct mhi_controller *mhi_cntrl,
struct db_cfg *db_cfg, void __iomem *io_addr,
dma_addr_t db_val);
};
struct mhi_pm_transitions {
enum MHI_PM_STATE from_state;
u32 to_states;
};
struct state_transition {
struct list_head node;
enum MHI_ST_TRANSITION state;
enum MHI_PM_STATE pm_state;
};
struct mhi_ctxt {
struct mhi_event_ctxt *er_ctxt;
struct mhi_chan_ctxt *chan_ctxt;
struct mhi_cmd_ctxt *cmd_ctxt;
dma_addr_t er_ctxt_addr;
dma_addr_t chan_ctxt_addr;
dma_addr_t cmd_ctxt_addr;
};
struct mhi_ring {
dma_addr_t dma_handle;
dma_addr_t iommu_base;
u64 *ctxt_wp; /* point to ctxt wp */
void *pre_aligned;
void *base;
void *rp;
void *wp;
size_t el_size;
size_t len;
size_t elements;
size_t alloc_size;
void __iomem *db_addr;
};
struct mhi_cmd {
struct mhi_ring ring;
spinlock_t lock;
};
struct mhi_buf_info {
dma_addr_t p_addr;
void *v_addr;
void *bb_addr;
void *wp;
size_t len;
void *cb_buf;
bool used; /* indicate element is free to use */
bool pre_mapped; /* already pre-mapped by client */
enum dma_data_direction dir;
};
struct mhi_event {
struct list_head node;
u32 er_index;
u32 intmod;
u32 msi;
int chan; /* this event ring is dedicated to a channel */
enum mhi_er_priority priority;
enum mhi_er_data_type data_type;
struct mhi_ring ring;
struct db_cfg db_cfg;
bool hw_ring;
bool cl_manage;
bool offload_ev; /* managed by a device driver */
bool request_irq; /* has dedicated interrupt handler */
spinlock_t lock;
struct mhi_chan *mhi_chan; /* dedicated to channel */
struct tasklet_struct task;
int (*process_event)(struct mhi_controller *mhi_cntrl,
struct mhi_event *mhi_event,
u32 event_quota);
struct mhi_controller *mhi_cntrl;
};
struct mhi_chan {
u32 chan;
const char *name;
/*
* important, when consuming increment tre_ring first, when releasing
* decrement buf_ring first. If tre_ring has space, buf_ring
* guranteed to have space so we do not need to check both rings.
*/
struct mhi_ring buf_ring;
struct mhi_ring tre_ring;
u32 er_index;
enum mhi_ch_type type;
enum dma_data_direction dir;
struct db_cfg db_cfg;
u32 ee_mask;
enum MHI_XFER_TYPE xfer_type;
enum MHI_CH_STATE ch_state;
enum MHI_EV_CCS ccs;
bool bei; /* based on interrupt moderation, true if greater than 0 */
bool lpm_notify;
bool configured;
bool offload_ch;
bool pre_alloc;
bool auto_start;
bool wake_capable; /* channel should wake up system */
/* functions that generate the transfer ring elements */
int (*gen_tre)(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan, void *buf, void *cb,
size_t len, enum MHI_FLAGS flags);
int (*queue_xfer)(struct mhi_device *mhi_dev,
struct mhi_chan *mhi_chan, void *buf,
size_t len, enum MHI_FLAGS flags);
/* xfer call back */
struct mhi_device *mhi_dev;
void (*xfer_cb)(struct mhi_device *mhi_dev, struct mhi_result *result);
struct mutex mutex;
struct completion completion;
rwlock_t lock;
struct list_head node;
};
struct tsync_node {
struct list_head node;
u32 sequence;
u64 local_time;
u64 remote_time;
struct mhi_device *mhi_dev;
void (*cb_func)(struct mhi_device *mhi_dev, u32 sequence,
u64 local_time, u64 remote_time);
};
struct mhi_timesync {
u32 er_index;
void __iomem *db;
void __iomem *time_reg;
enum MHI_EV_CCS ccs;
struct completion completion;
spinlock_t lock; /* list protection */
struct mutex lpm_mutex; /* lpm protection */
struct list_head head;
};
struct mhi_bus {
struct list_head controller_list;
struct mutex lock;
};
/* default MHI timeout */
#define MHI_TIMEOUT_MS (1000)
extern struct mhi_bus mhi_bus;
/* debug fs related functions */
int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_event_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_states_show(struct seq_file *m, void *d);
int mhi_debugfs_trigger_reset(void *data, u64 val);
void mhi_deinit_debugfs(struct mhi_controller *mhi_cntrl);
void mhi_init_debugfs(struct mhi_controller *mhi_cntrl);
/* power management apis */
enum MHI_PM_STATE __must_check mhi_tryset_pm_state(
struct mhi_controller *mhi_cntrl,
enum MHI_PM_STATE state);
const char *to_mhi_pm_state_str(enum MHI_PM_STATE state);
void mhi_reset_chan(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan);
enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl);
int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl,
enum MHI_ST_TRANSITION state);
void mhi_pm_st_worker(struct work_struct *work);
void mhi_fw_load_worker(struct work_struct *work);
void mhi_process_sys_err(struct mhi_controller *mhi_cntrl);
void mhi_low_priority_worker(struct work_struct *work);
int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl);
void mhi_ctrl_ev_task(unsigned long data);
int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl);
void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl);
int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl);
void mhi_notify(struct mhi_device *mhi_dev, enum MHI_CB cb_reason);
int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl,
struct mhi_event *mhi_event, u32 event_quota);
int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl,
struct mhi_event *mhi_event, u32 event_quota);
int mhi_process_tsync_event_ring(struct mhi_controller *mhi_cntrl,
struct mhi_event *mhi_event, u32 event_quota);
int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
struct mhi_event *mhi_event, u32 event_quota);
int mhi_send_cmd(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
enum MHI_CMD cmd);
int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl);
static inline void mhi_trigger_resume(struct mhi_controller *mhi_cntrl)
{
mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data);
mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data);
pm_wakeup_hard_event(&mhi_cntrl->mhi_dev->dev);
}
/* queue transfer buffer */
int mhi_gen_tre(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan,
void *buf, void *cb, size_t buf_len, enum MHI_FLAGS flags);
int mhi_queue_buf(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan,
void *buf, size_t len, enum MHI_FLAGS mflags);
int mhi_queue_skb(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan,
void *buf, size_t len, enum MHI_FLAGS mflags);
int mhi_queue_sclist(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan,
void *buf, size_t len, enum MHI_FLAGS mflags);
int mhi_queue_nop(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan,
void *buf, size_t len, enum MHI_FLAGS mflags);
int mhi_queue_dma(struct mhi_device *mhi_dev, struct mhi_chan *mhi_chan,
void *buf, size_t len, enum MHI_FLAGS mflags);
/* register access methods */
void mhi_db_brstmode(struct mhi_controller *mhi_cntrl, struct db_cfg *db_cfg,
void __iomem *db_addr, dma_addr_t wp);
void mhi_db_brstmode_disable(struct mhi_controller *mhi_cntrl,
struct db_cfg *db_mode, void __iomem *db_addr,
dma_addr_t wp);
int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl,
void __iomem *base, u32 offset, u32 *out);
int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,
void __iomem *base, u32 offset, u32 mask,
u32 shift, u32 *out);
void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
u32 offset, u32 val);
void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base,
u32 offset, u32 mask, u32 shift, u32 val);
void mhi_ring_er_db(struct mhi_event *mhi_event);
void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr,
dma_addr_t wp);
void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd);
void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan);
int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl, u32 capability,
u32 *offset);
void *mhi_to_virtual(struct mhi_ring *ring, dma_addr_t addr);
int mhi_init_timesync(struct mhi_controller *mhi_cntrl);
int mhi_create_timesync_sysfs(struct mhi_controller *mhi_cntrl);
void mhi_destroy_timesync(struct mhi_controller *mhi_cntrl);
int mhi_create_sysfs(struct mhi_controller *mhi_cntrl);
void mhi_destroy_sysfs(struct mhi_controller *mhi_cntrl);
int mhi_early_notify_device(struct device *dev, void *data);
/* timesync log support */
static inline void mhi_timesync_log(struct mhi_controller *mhi_cntrl)
{
struct mhi_timesync *mhi_tsync = mhi_cntrl->mhi_tsync;
if (mhi_tsync && mhi_cntrl->tsync_log)
mhi_cntrl->tsync_log(mhi_cntrl,
readq_no_log(mhi_tsync->time_reg));
}
/* memory allocation methods */
static inline void *mhi_alloc_coherent(struct mhi_controller *mhi_cntrl,
size_t size,
dma_addr_t *dma_handle,
gfp_t gfp)
{
void *buf = dma_alloc_coherent(mhi_cntrl->dev, size, dma_handle, gfp);
if (buf)
atomic_add(size, &mhi_cntrl->alloc_size);
return buf;
}
static inline void mhi_free_coherent(struct mhi_controller *mhi_cntrl,
size_t size,
void *vaddr,
dma_addr_t dma_handle)
{
atomic_sub(size, &mhi_cntrl->alloc_size);
dma_free_coherent(mhi_cntrl->dev, size, vaddr, dma_handle);
}
static inline void *mhi_alloc_contig_coherent(
struct mhi_controller *mhi_cntrl,
size_t size, dma_addr_t *dma_handle,
gfp_t gfp)
{
void *buf = dma_alloc_attrs(mhi_cntrl->dev, size, dma_handle, gfp,
DMA_ATTR_FORCE_CONTIGUOUS);
if (buf)
atomic_add(size, &mhi_cntrl->alloc_size);
return buf;
}
static inline void mhi_free_contig_coherent(
struct mhi_controller *mhi_cntrl,
size_t size, void *vaddr,
dma_addr_t dma_handle)
{
atomic_sub(size, &mhi_cntrl->alloc_size);
dma_free_attrs(mhi_cntrl->dev, size, vaddr, dma_handle,
DMA_ATTR_FORCE_CONTIGUOUS);
}
struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl);
static inline void mhi_dealloc_device(struct mhi_controller *mhi_cntrl,
struct mhi_device *mhi_dev)
{
kfree(mhi_dev);
}
int mhi_destroy_device(struct device *dev, void *data);
void mhi_create_devices(struct mhi_controller *mhi_cntrl);
int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
struct image_info **image_info, size_t alloc_size);
void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
struct image_info *image_info);
int mhi_map_single_no_bb(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf_info);
int mhi_map_single_use_bb(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf_info);
void mhi_unmap_single_no_bb(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf_info);
void mhi_unmap_single_use_bb(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf_info);
/* initialization methods */
int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan);
void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan);
int mhi_init_mmio(struct mhi_controller *mhi_cntrl);
int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl);
void mhi_deinit_dev_ctxt(struct mhi_controller *mhi_cntrl);
int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl);
void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl);
int mhi_dtr_init(void);
void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
struct image_info *img_info);
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
struct mhi_chan *mhi_chan);
/* isr handlers */
irqreturn_t mhi_msi_handlr(int irq_number, void *dev);
irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev);
irqreturn_t mhi_intvec_handlr(int irq_number, void *dev);
void mhi_ev_task(unsigned long data);
#ifdef CONFIG_MHI_DEBUG
#define MHI_ASSERT(cond, msg) do { \
if (cond) \
panic(msg); \
} while (0)
#else
#define MHI_ASSERT(cond, msg) do { \
if (cond) { \
MHI_ERR(msg); \
WARN_ON(cond); \
} \
} while (0)
#endif
#endif /* _MHI_INT_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "MHI device support"
config MHI_NETDEV
tristate "MHI NETDEV"
depends on MHI_BUS
help
MHI based net device driver for transferring IP traffic
between host and modem. By enabling this driver, clients
can transfer data using standard network interface. Over
the air traffic goes thru mhi netdev interface.
config MHI_UCI
tristate "MHI UCI"
depends on MHI_BUS
help
MHI based uci driver is for transferring data between host and
modem using standard file operations from user space. Open, read,
write, ioctl, and close operations are supported by this driver.
Please check mhi_uci_match_table for all supported channels that
are exposed to userspace.
config MHI_SATELLITE
tristate "MHI SATELLITE"
depends on MHI_BUS
help
MHI proxy satellite device driver enables NON-HLOS MHI satellite
drivers to communicate with device over PCIe link without host
involvement. Host facilitates propagation of events from device
to NON-HLOS MHI satellite drivers, channel states, and power
management over IPC communication. It helps in HLOS power
savings.
endmenu

View File

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MHI_NETDEV) +=mhi_netdev.o
obj-$(CONFIG_MHI_UCI) +=mhi_uci.o
obj-$(CONFIG_MHI_SATELLITE) +=mhi_satellite.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,759 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.*/
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ipc_logging.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/termios.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
#include <linux/mhi.h>
#define DEVICE_NAME "mhi"
#define MHI_UCI_DRIVER_NAME "mhi_uci"
struct uci_chan {
wait_queue_head_t wq;
spinlock_t lock;
struct list_head pending; /* user space waiting to read */
struct uci_buf *cur_buf; /* current buffer user space reading */
size_t rx_size;
};
struct uci_buf {
void *data;
size_t len;
struct list_head node;
};
struct uci_dev {
struct list_head node;
dev_t devt;
struct device *dev;
struct mhi_device *mhi_dev;
const char *chan;
struct mutex mutex; /* sync open and close */
struct uci_chan ul_chan;
struct uci_chan dl_chan;
size_t mtu;
size_t actual_mtu; /* maximum size of incoming buffer */
int ref_count;
bool enabled;
u32 tiocm;
void *ipc_log;
};
struct mhi_uci_drv {
struct list_head head;
struct mutex lock;
struct class *class;
int major;
dev_t dev_t;
};
static enum MHI_DEBUG_LEVEL msg_lvl = MHI_MSG_LVL_ERROR;
#ifdef CONFIG_MHI_DEBUG
#define IPC_LOG_LVL (MHI_MSG_LVL_VERBOSE)
#define MHI_UCI_IPC_LOG_PAGES (25)
#else
#define IPC_LOG_LVL (MHI_MSG_LVL_ERROR)
#define MHI_UCI_IPC_LOG_PAGES (1)
#endif
#ifdef CONFIG_MHI_DEBUG
#define MSG_VERB(fmt, ...) do { \
if (msg_lvl <= MHI_MSG_LVL_VERBOSE) \
printk("%s[D][%s] " fmt, KERN_ERR, __func__, \
##__VA_ARGS__); \
if (IPC_LOG_LVL <= MHI_MSG_LVL_VERBOSE) \
ipc_log_string(uci_dev->ipc_log, "%s[D][%s] " fmt, \
"", __func__, ##__VA_ARGS__); \
} while (0)
#else
#define MSG_VERB(fmt, ...)
#endif
#define MSG_LOG(fmt, ...) do { \
if (msg_lvl <= MHI_MSG_LVL_INFO) \
printk("%s[I][%s] " fmt, KERN_ERR, __func__, \
##__VA_ARGS__); \
if (IPC_LOG_LVL <= MHI_MSG_LVL_INFO) \
ipc_log_string(uci_dev->ipc_log, "%s[I][%s] " fmt, \
"", __func__, ##__VA_ARGS__); \
} while (0)
#define MSG_ERR(fmt, ...) do { \
if (msg_lvl <= MHI_MSG_LVL_ERROR) \
printk("%s[E][%s] " fmt, KERN_ERR, __func__, \
##__VA_ARGS__); \
if (IPC_LOG_LVL <= MHI_MSG_LVL_ERROR) \
ipc_log_string(uci_dev->ipc_log, "%s[E][%s] " fmt, \
"", __func__, ##__VA_ARGS__); \
} while (0)
#define MAX_UCI_DEVICES (64)
static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
static struct mhi_uci_drv mhi_uci_drv;
static int mhi_queue_inbound(struct uci_dev *uci_dev)
{
struct mhi_device *mhi_dev = uci_dev->mhi_dev;
int nr_trbs = mhi_get_no_free_descriptors(mhi_dev, DMA_FROM_DEVICE);
size_t mtu = uci_dev->mtu;
size_t actual_mtu = uci_dev->actual_mtu;
void *buf;
struct uci_buf *uci_buf;
int ret = -EIO, i;
for (i = 0; i < nr_trbs; i++) {
buf = kmalloc(mtu, GFP_KERNEL);
if (!buf)
return -ENOMEM;
uci_buf = buf + actual_mtu;
uci_buf->data = buf;
MSG_VERB("Allocated buf %d of %d size %ld\n", i, nr_trbs,
actual_mtu);
ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE, buf,
actual_mtu, MHI_EOT);
if (ret) {
kfree(buf);
MSG_ERR("Failed to queue buffer %d\n", i);
return ret;
}
}
return ret;
}
static long mhi_uci_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
{
struct uci_dev *uci_dev = file->private_data;
struct mhi_device *mhi_dev = uci_dev->mhi_dev;
struct uci_chan *uci_chan = &uci_dev->dl_chan;
long ret = -ENOIOCTLCMD;
mutex_lock(&uci_dev->mutex);
if (cmd == TIOCMGET) {
spin_lock_bh(&uci_chan->lock);
ret = uci_dev->tiocm;
spin_unlock_bh(&uci_chan->lock);
} else if (uci_dev->enabled) {
ret = mhi_ioctl(mhi_dev, cmd, arg);
if (!ret) {
spin_lock_bh(&uci_chan->lock);
uci_dev->tiocm = mhi_dev->tiocm;
spin_unlock_bh(&uci_chan->lock);
}
}
mutex_unlock(&uci_dev->mutex);
return ret;
}
static int mhi_uci_release(struct inode *inode, struct file *file)
{
struct uci_dev *uci_dev = file->private_data;
mutex_lock(&uci_dev->mutex);
uci_dev->ref_count--;
if (!uci_dev->ref_count) {
struct uci_buf *itr, *tmp;
struct uci_chan *uci_chan;
MSG_LOG("Last client left, closing node\n");
if (uci_dev->enabled)
mhi_unprepare_from_transfer(uci_dev->mhi_dev);
/* clean inbound channel */
uci_chan = &uci_dev->dl_chan;
list_for_each_entry_safe(itr, tmp, &uci_chan->pending, node) {
list_del(&itr->node);
kfree(itr->data);
}
if (uci_chan->cur_buf)
kfree(uci_chan->cur_buf->data);
uci_chan->cur_buf = NULL;
if (!uci_dev->enabled) {
MSG_LOG("Node is deleted, freeing dev node\n");
mutex_unlock(&uci_dev->mutex);
mutex_destroy(&uci_dev->mutex);
clear_bit(MINOR(uci_dev->devt), uci_minors);
kfree(uci_dev);
return 0;
}
}
MSG_LOG("exit: ref_count:%d\n", uci_dev->ref_count);
mutex_unlock(&uci_dev->mutex);
return 0;
}
static __poll_t mhi_uci_poll(struct file *file, poll_table *wait)
{
struct uci_dev *uci_dev = file->private_data;
struct mhi_device *mhi_dev = uci_dev->mhi_dev;
struct uci_chan *uci_chan;
__poll_t mask = 0;
poll_wait(file, &uci_dev->dl_chan.wq, wait);
poll_wait(file, &uci_dev->ul_chan.wq, wait);
uci_chan = &uci_dev->dl_chan;
spin_lock_bh(&uci_chan->lock);
if (!uci_dev->enabled) {
mask = EPOLLERR;
} else {
if (!list_empty(&uci_chan->pending) || uci_chan->cur_buf) {
MSG_VERB("Client can read from node\n");
mask |= EPOLLIN | EPOLLRDNORM;
}
if (uci_dev->tiocm) {
MSG_VERB("Line status changed\n");
mask |= EPOLLPRI;
}
}
spin_unlock_bh(&uci_chan->lock);
uci_chan = &uci_dev->ul_chan;
spin_lock_bh(&uci_chan->lock);
if (!uci_dev->enabled) {
mask |= EPOLLERR;
} else if (mhi_get_no_free_descriptors(mhi_dev, DMA_TO_DEVICE) > 0) {
MSG_VERB("Client can write to node\n");
mask |= EPOLLOUT | EPOLLWRNORM;
}
spin_unlock_bh(&uci_chan->lock);
MSG_LOG("Client attempted to poll, returning mask 0x%x\n", mask);
return mask;
}
static ssize_t mhi_uci_write(struct file *file,
const char __user *buf,
size_t count,
loff_t *offp)
{
struct uci_dev *uci_dev = file->private_data;
struct mhi_device *mhi_dev = uci_dev->mhi_dev;
struct uci_chan *uci_chan = &uci_dev->ul_chan;
size_t bytes_xfered = 0;
int ret, nr_avail;
if (!buf || !count)
return -EINVAL;
/* confirm channel is active */
spin_lock_bh(&uci_chan->lock);
if (!uci_dev->enabled) {
spin_unlock_bh(&uci_chan->lock);
return -ERESTARTSYS;
}
MSG_VERB("Enter: to xfer:%lu bytes\n", count);
while (count) {
size_t xfer_size;
void *kbuf;
enum MHI_FLAGS flags;
spin_unlock_bh(&uci_chan->lock);
/* wait for free descriptors */
ret = wait_event_interruptible(uci_chan->wq,
(!uci_dev->enabled) ||
(nr_avail = mhi_get_no_free_descriptors(mhi_dev,
DMA_TO_DEVICE)) > 0);
if (ret == -ERESTARTSYS || !uci_dev->enabled) {
MSG_LOG("Exit signal caught for node or not enabled\n");
return -ERESTARTSYS;
}
xfer_size = min_t(size_t, count, uci_dev->mtu);
kbuf = kmalloc(xfer_size, GFP_KERNEL);
if (!kbuf) {
MSG_ERR("Failed to allocate memory %lu\n", xfer_size);
return -ENOMEM;
}
ret = copy_from_user(kbuf, buf, xfer_size);
if (unlikely(ret)) {
kfree(kbuf);
return ret;
}
spin_lock_bh(&uci_chan->lock);
/* if ring is full after this force EOT */
if (nr_avail > 1 && (count - xfer_size))
flags = MHI_CHAIN;
else
flags = MHI_EOT;
if (uci_dev->enabled)
ret = mhi_queue_transfer(mhi_dev, DMA_TO_DEVICE, kbuf,
xfer_size, flags);
else
ret = -ERESTARTSYS;
if (ret) {
kfree(kbuf);
goto sys_interrupt;
}
bytes_xfered += xfer_size;
count -= xfer_size;
buf += xfer_size;
}
spin_unlock_bh(&uci_chan->lock);
MSG_VERB("Exit: Number of bytes xferred:%lu\n", bytes_xfered);
return bytes_xfered;
sys_interrupt:
spin_unlock_bh(&uci_chan->lock);
return ret;
}
static ssize_t mhi_uci_read(struct file *file,
char __user *buf,
size_t count,
loff_t *ppos)
{
struct uci_dev *uci_dev = file->private_data;
struct mhi_device *mhi_dev = uci_dev->mhi_dev;
struct uci_chan *uci_chan = &uci_dev->dl_chan;
struct uci_buf *uci_buf;
char *ptr;
size_t to_copy;
int ret = 0;
if (!buf)
return -EINVAL;
MSG_VERB("Client provided buf len:%lu\n", count);
/* confirm channel is active */
spin_lock_bh(&uci_chan->lock);
if (!uci_dev->enabled) {
spin_unlock_bh(&uci_chan->lock);
return -ERESTARTSYS;
}
/* No data available to read, wait */
if (!uci_chan->cur_buf && list_empty(&uci_chan->pending)) {
MSG_VERB("No data available to read waiting\n");
spin_unlock_bh(&uci_chan->lock);
ret = wait_event_interruptible(uci_chan->wq,
(!uci_dev->enabled ||
!list_empty(&uci_chan->pending)));
if (ret == -ERESTARTSYS) {
MSG_LOG("Exit signal caught for node\n");
return -ERESTARTSYS;
}
spin_lock_bh(&uci_chan->lock);
if (!uci_dev->enabled) {
MSG_LOG("node is disabled\n");
ret = -ERESTARTSYS;
goto read_error;
}
}
/* new read, get the next descriptor from the list */
if (!uci_chan->cur_buf) {
uci_buf = list_first_entry_or_null(&uci_chan->pending,
struct uci_buf, node);
if (unlikely(!uci_buf)) {
ret = -EIO;
goto read_error;
}
list_del(&uci_buf->node);
uci_chan->cur_buf = uci_buf;
uci_chan->rx_size = uci_buf->len;
MSG_VERB("Got pkt of size:%zu\n", uci_chan->rx_size);
}
uci_buf = uci_chan->cur_buf;
spin_unlock_bh(&uci_chan->lock);
/* Copy the buffer to user space */
to_copy = min_t(size_t, count, uci_chan->rx_size);
ptr = uci_buf->data + (uci_buf->len - uci_chan->rx_size);
ret = copy_to_user(buf, ptr, to_copy);
if (ret)
return ret;
MSG_VERB("Copied %lu of %lu bytes\n", to_copy, uci_chan->rx_size);
uci_chan->rx_size -= to_copy;
/* we finished with this buffer, queue it back to hardware */
if (!uci_chan->rx_size) {
spin_lock_bh(&uci_chan->lock);
uci_chan->cur_buf = NULL;
if (uci_dev->enabled)
ret = mhi_queue_transfer(mhi_dev, DMA_FROM_DEVICE,
uci_buf->data,
uci_dev->actual_mtu, MHI_EOT);
else
ret = -ERESTARTSYS;
if (ret) {
MSG_ERR("Failed to recycle element\n");
kfree(uci_buf->data);
goto read_error;
}
spin_unlock_bh(&uci_chan->lock);
}
MSG_VERB("Returning %lu bytes\n", to_copy);
return to_copy;
read_error:
spin_unlock_bh(&uci_chan->lock);
return ret;
}
static int mhi_uci_open(struct inode *inode, struct file *filp)
{
struct uci_dev *uci_dev = NULL, *tmp_dev;
int ret = -EIO;
struct uci_buf *buf_itr, *tmp;
struct uci_chan *dl_chan;
mutex_lock(&mhi_uci_drv.lock);
list_for_each_entry(tmp_dev, &mhi_uci_drv.head, node) {
if (tmp_dev->devt == inode->i_rdev) {
uci_dev = tmp_dev;
break;
}
}
/* could not find a minor node */
if (!uci_dev)
goto error_exit;
mutex_lock(&uci_dev->mutex);
if (!uci_dev->enabled) {
MSG_ERR("Node exist, but not in active state!\n");
goto error_open_chan;
}
uci_dev->ref_count++;
MSG_LOG("Node open, ref counts %u\n", uci_dev->ref_count);
if (uci_dev->ref_count == 1) {
MSG_LOG("Starting channel\n");
ret = mhi_prepare_for_transfer(uci_dev->mhi_dev);
if (ret) {
MSG_ERR("Error starting transfer channels\n");
uci_dev->ref_count--;
goto error_open_chan;
}
ret = mhi_queue_inbound(uci_dev);
if (ret)
goto error_rx_queue;
}
filp->private_data = uci_dev;
mutex_unlock(&uci_dev->mutex);
mutex_unlock(&mhi_uci_drv.lock);
return 0;
error_rx_queue:
dl_chan = &uci_dev->dl_chan;
mhi_unprepare_from_transfer(uci_dev->mhi_dev);
list_for_each_entry_safe(buf_itr, tmp, &dl_chan->pending, node) {
list_del(&buf_itr->node);
kfree(buf_itr->data);
}
error_open_chan:
mutex_unlock(&uci_dev->mutex);
error_exit:
mutex_unlock(&mhi_uci_drv.lock);
return ret;
}
static const struct file_operations mhidev_fops = {
.open = mhi_uci_open,
.release = mhi_uci_release,
.read = mhi_uci_read,
.write = mhi_uci_write,
.poll = mhi_uci_poll,
.unlocked_ioctl = mhi_uci_ioctl,
};
static void mhi_uci_remove(struct mhi_device *mhi_dev)
{
struct uci_dev *uci_dev = mhi_device_get_devdata(mhi_dev);
MSG_LOG("Enter\n");
mutex_lock(&mhi_uci_drv.lock);
mutex_lock(&uci_dev->mutex);
/* disable the node */
spin_lock_irq(&uci_dev->dl_chan.lock);
spin_lock_irq(&uci_dev->ul_chan.lock);
uci_dev->enabled = false;
spin_unlock_irq(&uci_dev->ul_chan.lock);
spin_unlock_irq(&uci_dev->dl_chan.lock);
wake_up(&uci_dev->dl_chan.wq);
wake_up(&uci_dev->ul_chan.wq);
/* delete the node to prevent new opens */
device_destroy(mhi_uci_drv.class, uci_dev->devt);
uci_dev->dev = NULL;
list_del(&uci_dev->node);
/* safe to free memory only if all file nodes are closed */
if (!uci_dev->ref_count) {
mutex_unlock(&uci_dev->mutex);
mutex_destroy(&uci_dev->mutex);
clear_bit(MINOR(uci_dev->devt), uci_minors);
kfree(uci_dev);
mutex_unlock(&mhi_uci_drv.lock);
return;
}
MSG_LOG("Exit\n");
mutex_unlock(&uci_dev->mutex);
mutex_unlock(&mhi_uci_drv.lock);
}
static int mhi_uci_probe(struct mhi_device *mhi_dev,
const struct mhi_device_id *id)
{
struct uci_dev *uci_dev;
int minor;
char node_name[32];
int dir;
uci_dev = kzalloc(sizeof(*uci_dev), GFP_KERNEL);
if (!uci_dev)
return -ENOMEM;
mutex_init(&uci_dev->mutex);
uci_dev->mhi_dev = mhi_dev;
minor = find_first_zero_bit(uci_minors, MAX_UCI_DEVICES);
if (minor >= MAX_UCI_DEVICES) {
kfree(uci_dev);
return -ENOSPC;
}
mutex_lock(&uci_dev->mutex);
mutex_lock(&mhi_uci_drv.lock);
uci_dev->devt = MKDEV(mhi_uci_drv.major, minor);
uci_dev->dev = device_create(mhi_uci_drv.class, &mhi_dev->dev,
uci_dev->devt, uci_dev,
DEVICE_NAME "_%04x_%02u.%02u.%02u%s%d",
mhi_dev->dev_id, mhi_dev->domain,
mhi_dev->bus, mhi_dev->slot, "_pipe_",
mhi_dev->ul_chan_id);
set_bit(minor, uci_minors);
/* create debugging buffer */
snprintf(node_name, sizeof(node_name), "mhi_uci_%04x_%02u.%02u.%02u_%d",
mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus, mhi_dev->slot,
mhi_dev->ul_chan_id);
uci_dev->ipc_log = ipc_log_context_create(MHI_UCI_IPC_LOG_PAGES,
node_name, 0);
for (dir = 0; dir < 2; dir++) {
struct uci_chan *uci_chan = (dir) ?
&uci_dev->ul_chan : &uci_dev->dl_chan;
spin_lock_init(&uci_chan->lock);
init_waitqueue_head(&uci_chan->wq);
INIT_LIST_HEAD(&uci_chan->pending);
}
uci_dev->mtu = min_t(size_t, id->driver_data, mhi_dev->mtu);
uci_dev->actual_mtu = uci_dev->mtu - sizeof(struct uci_buf);
mhi_device_set_devdata(mhi_dev, uci_dev);
uci_dev->enabled = true;
list_add(&uci_dev->node, &mhi_uci_drv.head);
mutex_unlock(&mhi_uci_drv.lock);
mutex_unlock(&uci_dev->mutex);
MSG_LOG("channel:%s successfully probed\n", mhi_dev->chan_name);
return 0;
};
static void mhi_ul_xfer_cb(struct mhi_device *mhi_dev,
struct mhi_result *mhi_result)
{
struct uci_dev *uci_dev = mhi_device_get_devdata(mhi_dev);
struct uci_chan *uci_chan = &uci_dev->ul_chan;
MSG_VERB("status:%d xfer_len:%zu\n", mhi_result->transaction_status,
mhi_result->bytes_xferd);
kfree(mhi_result->buf_addr);
if (!mhi_result->transaction_status)
wake_up(&uci_chan->wq);
}
static void mhi_dl_xfer_cb(struct mhi_device *mhi_dev,
struct mhi_result *mhi_result)
{
struct uci_dev *uci_dev = mhi_device_get_devdata(mhi_dev);
struct uci_chan *uci_chan = &uci_dev->dl_chan;
unsigned long flags;
struct uci_buf *buf;
MSG_VERB("status:%d receive_len:%zu\n", mhi_result->transaction_status,
mhi_result->bytes_xferd);
if (mhi_result->transaction_status == -ENOTCONN) {
kfree(mhi_result->buf_addr);
return;
}
spin_lock_irqsave(&uci_chan->lock, flags);
buf = mhi_result->buf_addr + uci_dev->actual_mtu;
buf->data = mhi_result->buf_addr;
buf->len = mhi_result->bytes_xferd;
list_add_tail(&buf->node, &uci_chan->pending);
spin_unlock_irqrestore(&uci_chan->lock, flags);
if (mhi_dev->dev.power.wakeup)
pm_wakeup_hard_event(&mhi_dev->dev);
wake_up(&uci_chan->wq);
}
static void mhi_status_cb(struct mhi_device *mhi_dev, enum MHI_CB reason)
{
struct uci_dev *uci_dev = mhi_device_get_devdata(mhi_dev);
struct uci_chan *uci_chan = &uci_dev->dl_chan;
unsigned long flags;
if (reason == MHI_CB_DTR_SIGNAL) {
spin_lock_irqsave(&uci_chan->lock, flags);
uci_dev->tiocm = mhi_dev->tiocm;
spin_unlock_irqrestore(&uci_chan->lock, flags);
wake_up(&uci_chan->wq);
}
}
/* .driver_data stores max mtu */
static const struct mhi_device_id mhi_uci_match_table[] = {
{ .chan = "LOOPBACK", .driver_data = 0x1000 },
{ .chan = "SAHARA", .driver_data = 0x8000 },
{ .chan = "DIAG", .driver_data = 0x1000 },
{ .chan = "EFS", .driver_data = 0x1000 },
{ .chan = "QMI0", .driver_data = 0x1000 },
{ .chan = "QMI1", .driver_data = 0x1000 },
{ .chan = "TF", .driver_data = 0x1000 },
{ .chan = "DCI", .driver_data = 0x1000 },
{ .chan = "DUN", .driver_data = 0x1000 },
{},
};
static struct mhi_driver mhi_uci_driver = {
.id_table = mhi_uci_match_table,
.remove = mhi_uci_remove,
.probe = mhi_uci_probe,
.ul_xfer_cb = mhi_ul_xfer_cb,
.dl_xfer_cb = mhi_dl_xfer_cb,
.status_cb = mhi_status_cb,
.driver = {
.name = MHI_UCI_DRIVER_NAME,
.owner = THIS_MODULE,
},
};
static int mhi_uci_init(void)
{
int ret;
ret = register_chrdev(0, MHI_UCI_DRIVER_NAME, &mhidev_fops);
if (ret < 0)
return ret;
mhi_uci_drv.major = ret;
mhi_uci_drv.class = class_create(THIS_MODULE, MHI_UCI_DRIVER_NAME);
if (IS_ERR(mhi_uci_drv.class))
return -ENODEV;
mutex_init(&mhi_uci_drv.lock);
INIT_LIST_HEAD(&mhi_uci_drv.head);
ret = mhi_driver_register(&mhi_uci_driver);
if (ret)
class_destroy(mhi_uci_drv.class);
return ret;
}
module_init(mhi_uci_init);
static void __exit mhi_uci_exit(void)
{
if (mhi_uci_drv.major) {
unregister_chrdev_region(MKDEV(mhi_uci_drv.major, 0),
mhi_uci_drv.major);
mhi_uci_drv.major = 0;
}
class_destroy(mhi_uci_drv.class);
mhi_driver_unregister(&mhi_uci_driver);
}
module_exit(mhi_uci_exit);
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("MHI_UCI");
MODULE_DESCRIPTION("MHI UCI Driver");

View File

@ -523,6 +523,23 @@ source "drivers/s390/char/Kconfig"
source "drivers/char/xillybus/Kconfig"
config MSM_ADSPRPC
tristate "QTI FastRPC driver"
depends on RPMSG && QCOM_SECURE_BUFFER && MSM_SERVICE_LOCATOR && MSM_SERVICE_NOTIFIER && PM_SLEEP && HAS_DMA && CMA && MMU
help
Provides a communication mechanism that allows clients to
make remote method invocations across processor boundary to
applications/compute DSP processor.
Say M if you want to enable this module.
config ADSPRPC_DEBUG
bool "Debug logs in FastRPC driver"
help
Enable debug logs in the fastrpc driver. Flag will be
disabled by default to maximize RPC performance as debug
logging will impact RPC overhead.
Say Y here if you want to enable the logs.
config ADI
tristate "SPARC Privileged ADI driver"
depends on SPARC64

View File

@ -51,4 +51,9 @@ js-rtc-y = rtc.o
obj-$(CONFIG_XILLYBUS) += xillybus/
obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
frpc-adsprpc-objs += adsprpc.o
ifdef CONFIG_COMPAT
frpc-adsprpc-objs += adsprpc_compat.o
endif
obj-$(CONFIG_MSM_ADSPRPC) += frpc-adsprpc.o
obj-$(CONFIG_ADI) += adi.o

5363
drivers/char/adsprpc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,804 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/compat.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/msm_ion.h>
#include "adsprpc_compat.h"
#include "adsprpc_shared.h"
#define COMPAT_FASTRPC_IOCTL_INVOKE \
_IOWR('R', 1, struct compat_fastrpc_ioctl_invoke)
#define COMPAT_FASTRPC_IOCTL_MMAP \
_IOWR('R', 2, struct compat_fastrpc_ioctl_mmap)
#define COMPAT_FASTRPC_IOCTL_MUNMAP \
_IOWR('R', 3, struct compat_fastrpc_ioctl_munmap)
#define COMPAT_FASTRPC_IOCTL_INVOKE_FD \
_IOWR('R', 4, struct compat_fastrpc_ioctl_invoke_fd)
#define COMPAT_FASTRPC_IOCTL_INIT \
_IOWR('R', 6, struct compat_fastrpc_ioctl_init)
#define COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS \
_IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs)
#define COMPAT_FASTRPC_IOCTL_GETPERF \
_IOWR('R', 9, struct compat_fastrpc_ioctl_perf)
#define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \
_IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs)
#define COMPAT_FASTRPC_IOCTL_INVOKE_CRC \
_IOWR('R', 11, struct compat_fastrpc_ioctl_invoke_crc)
#define COMPAT_FASTRPC_IOCTL_CONTROL \
_IOWR('R', 12, struct compat_fastrpc_ioctl_control)
#define COMPAT_FASTRPC_IOCTL_MMAP_64 \
_IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
_IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64)
#define COMPAT_FASTRPC_IOCTL_GET_DSP_INFO \
_IOWR('R', 17, \
struct compat_fastrpc_ioctl_remote_dsp_capability)
#define COMPAT_FASTRPC_IOCTL_INVOKE2 \
_IOWR('R', 18, struct compat_fastrpc_ioctl_invoke2)
struct compat_remote_buf {
compat_uptr_t pv; /* buffer pointer */
compat_size_t len; /* length of buffer */
};
union compat_remote_arg {
struct compat_remote_buf buf;
compat_uint_t h;
};
struct compat_fastrpc_ioctl_invoke {
compat_uint_t handle; /* remote handle */
compat_uint_t sc; /* scalars describing the data */
compat_uptr_t pra; /* remote arguments list */
};
struct compat_fastrpc_ioctl_invoke_fd {
struct compat_fastrpc_ioctl_invoke inv;
compat_uptr_t fds; /* fd list */
};
struct compat_fastrpc_ioctl_invoke_attrs {
struct compat_fastrpc_ioctl_invoke inv;
compat_uptr_t fds; /* fd list */
compat_uptr_t attrs; /* attribute list */
};
struct compat_fastrpc_ioctl_invoke_crc {
struct compat_fastrpc_ioctl_invoke inv;
compat_uptr_t fds; /* fd list */
compat_uptr_t attrs; /* attribute list */
compat_uptr_t crc; /* crc list */
};
struct compat_fastrpc_ioctl_invoke_async {
struct compat_fastrpc_ioctl_invoke inv;
compat_uptr_t fds; /* fd list */
compat_uptr_t attrs; /* attribute list */
compat_uptr_t crc; /* crc list */
compat_uptr_t job; /* Async job */
};
struct compat_fastrpc_ioctl_invoke2 {
compat_uint_t req; /* type of invocation request */
compat_uptr_t invparam; /* invocation request param */
compat_uint_t size; /* size of invocation param */
compat_int_t err; /* reserved */
};
struct compat_fastrpc_ioctl_mmap {
compat_int_t fd; /* ion fd */
compat_uint_t flags; /* flags for dsp to map with */
compat_uptr_t vaddrin; /* optional virtual address */
compat_size_t size; /* size */
compat_uptr_t vaddrout; /* dsps virtual address */
};
struct compat_fastrpc_ioctl_mmap_64 {
compat_int_t fd; /* ion fd */
compat_uint_t flags; /* flags for dsp to map with */
compat_u64 vaddrin; /* optional virtual address */
compat_size_t size; /* size */
compat_u64 vaddrout; /* dsps virtual address */
};
struct compat_fastrpc_ioctl_munmap {
compat_uptr_t vaddrout; /* address to unmap */
compat_size_t size; /* size */
};
struct compat_fastrpc_ioctl_munmap_64 {
compat_u64 vaddrout; /* address to unmap */
compat_size_t size; /* size */
};
struct compat_fastrpc_ioctl_init {
compat_uint_t flags; /* one of FASTRPC_INIT_* macros */
compat_uptr_t file; /* pointer to elf file */
compat_int_t filelen; /* elf file length */
compat_int_t filefd; /* ION fd for the file */
compat_uptr_t mem; /* mem for the PD */
compat_int_t memlen; /* mem length */
compat_int_t memfd; /* ION fd for the mem */
};
struct compat_fastrpc_ioctl_init_attrs {
struct compat_fastrpc_ioctl_init init;
compat_int_t attrs; /* attributes to init process */
compat_int_t siglen; /* test signature file length */
};
struct compat_fastrpc_ioctl_perf { /* kernel performance data */
compat_uptr_t data;
compat_int_t numkeys;
compat_uptr_t keys;
};
#define FASTRPC_CONTROL_LATENCY (1)
struct compat_fastrpc_ctrl_latency {
compat_uint_t enable; /* latency control enable */
compat_uint_t latency; /* target latency in us */
};
#define FASTRPC_CONTROL_KALLOC (3)
struct compat_fastrpc_ctrl_kalloc {
compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
};
struct compat_fastrpc_ioctl_control {
compat_uint_t req;
union {
struct compat_fastrpc_ctrl_latency lp;
struct compat_fastrpc_ctrl_kalloc kalloc;
};
};
struct compat_fastrpc_ioctl_remote_dsp_capability {
/*
* @param[in]: DSP domain ADSP_DOMAIN_ID,
* SDSP_DOMAIN_ID, or CDSP_DOMAIN_ID
*/
compat_uint_t domain;
/*
* @param[in]: One of the DSP attributes
* from enum remote_dsp_attributes
*/
compat_uint_t attribute_ID;
/*
* @param[out]: Result of the DSP
* capability query based on attribute_ID
*/
compat_uint_t capability;
};
static int compat_get_fastrpc_ioctl_invoke(
struct compat_fastrpc_ioctl_invoke_async __user *inv32,
struct fastrpc_ioctl_invoke_async __user *inv,
unsigned int cmd)
{
compat_uint_t u = 0, sc = 0;
compat_size_t s;
compat_uptr_t p;
union compat_remote_arg *pra32;
union remote_arg *pra;
int err = 0, len = 0, j = 0;
err = get_user(sc, &inv32->inv.sc);
if (err)
return err;
len = REMOTE_SCALARS_LENGTH(sc);
pra = (union remote_arg *)(inv + 1);
err = put_user(pra, &inv->inv.pra);
err |= put_user(sc, &inv->inv.sc);
err |= get_user(u, &inv32->inv.handle);
err |= put_user(u, &inv->inv.handle);
err |= get_user(p, &inv32->inv.pra);
if (err)
return err;
pra32 = compat_ptr(p);
pra = (union remote_arg *)(inv + 1);
for (j = 0; j < len; j++) {
err |= get_user(p, &pra32[j].buf.pv);
err |= put_user(p, (uintptr_t *)&pra[j].buf.pv);
err |= get_user(s, &pra32[j].buf.len);
err |= put_user(s, &pra[j].buf.len);
}
err |= put_user(NULL, &inv->fds);
if (cmd != COMPAT_FASTRPC_IOCTL_INVOKE) {
err |= get_user(p, &inv32->fds);
err |= put_user(p, (compat_uptr_t *)&inv->fds);
}
err |= put_user(NULL, &inv->attrs);
if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS) ||
(cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) ||
(cmd == FASTRPC_INVOKE2_ASYNC)) {
err |= get_user(p, &inv32->attrs);
err |= put_user(p, (compat_uptr_t *)&inv->attrs);
}
err |= put_user(NULL, (compat_uptr_t __user **)&inv->crc);
if (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) {
err |= get_user(p, &inv32->crc);
err |= put_user(p, (compat_uptr_t __user *)&inv->crc);
}
err |= put_user(NULL, &inv->job);
if (cmd == FASTRPC_INVOKE2_ASYNC) {
err |= get_user(p, &inv32->job);
err |= put_user(p, (compat_uptr_t __user *)&inv->job);
}
return err;
}
static int compat_fastrpc_ioctl_invoke(struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct compat_fastrpc_ioctl_invoke_async __user *inv32;
struct fastrpc_ioctl_invoke_async __user *inv;
compat_uint_t sc = 0;
int err = 0, len = 0;
inv32 = compat_ptr(arg);
err = get_user(sc, &inv32->inv.sc);
if (err)
return err;
len = REMOTE_SCALARS_LENGTH(sc);
VERIFY(err, NULL != (inv = compat_alloc_user_space(
sizeof(*inv) + len * sizeof(union remote_arg))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(inv32,
inv, cmd));
if (err)
return err;
return filp->f_op->unlocked_ioctl(filp,
FASTRPC_IOCTL_INVOKE_CRC, (unsigned long)inv);
}
static int compat_get_fastrpc_ioctl_invoke2(
struct compat_fastrpc_ioctl_invoke2 __user *inv32,
struct fastrpc_ioctl_invoke2 __user **inva,
unsigned int cmd)
{
int err = 0;
compat_uptr_t pparam;
compat_uint_t req, size;
struct fastrpc_ioctl_invoke2 __user *inv2_user = NULL;
struct fastrpc_ioctl_invoke_async __user *asyncinv_user;
err = get_user(req, &inv32->req);
err |= get_user(pparam, &inv32->invparam);
err |= get_user(size, &inv32->size);
if (err)
goto bail;
switch (req) {
case FASTRPC_INVOKE2_ASYNC:
{
struct compat_fastrpc_ioctl_invoke_async __user *lasync32;
compat_uint_t sc = 0;
int len = 0;
VERIFY(err, size == sizeof(*lasync32));
if (err) {
err = -EBADE;
goto bail;
}
lasync32 = compat_ptr(pparam);
err = get_user(sc, &lasync32->inv.sc);
if (err)
goto bail;
len = REMOTE_SCALARS_LENGTH(sc);
VERIFY(err, NULL != (inv2_user = compat_alloc_user_space(
sizeof(*inv2_user) + sizeof(*asyncinv_user) +
len * sizeof(union remote_arg))));
if (err) {
err = -EFAULT;
goto bail;
}
asyncinv_user =
(struct fastrpc_ioctl_invoke_async __user *)(inv2_user + 1);
VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(lasync32,
asyncinv_user, req));
if (err)
goto bail;
err |= put_user(req, &inv2_user->req);
err |= put_user((uintptr_t __user)asyncinv_user,
&inv2_user->invparam);
err |= put_user(sizeof(*asyncinv_user), &inv2_user->size);
if (err)
goto bail;
break;
}
case FASTRPC_INVOKE2_ASYNC_RESPONSE:
{
VERIFY(err,
size == sizeof(struct fastrpc_ioctl_async_response));
if (err) {
err = -EBADE;
goto bail;
}
VERIFY(err, NULL != (inv2_user = compat_alloc_user_space(
sizeof(*inv2_user))));
if (err) {
err = -EFAULT;
goto bail;
}
err |= put_user(req, &inv2_user->req);
err |=
put_user(pparam, &inv2_user->invparam);
err |= put_user(size, &inv2_user->size);
if (err)
goto bail;
break;
}
default:
err = -EBADRQC;
break;
}
*inva = inv2_user;
bail:
return err;
}
static int compat_fastrpc_ioctl_invoke2(struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct compat_fastrpc_ioctl_invoke2 __user *inv32;
struct fastrpc_ioctl_invoke2 __user *inv;
int err = 0;
inv32 = compat_ptr(arg);
VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke2(inv32,
&inv, cmd));
if (err)
return err;
return filp->f_op->unlocked_ioctl(filp,
FASTRPC_IOCTL_INVOKE2, (unsigned long)inv);
}
static int compat_get_fastrpc_ioctl_mmap(
struct compat_fastrpc_ioctl_mmap __user *map32,
struct fastrpc_ioctl_mmap __user *map)
{
compat_uint_t u;
compat_int_t i;
compat_size_t s;
compat_uptr_t p;
int err;
err = get_user(i, &map32->fd);
err |= put_user(i, &map->fd);
err |= get_user(u, &map32->flags);
err |= put_user(u, &map->flags);
err |= get_user(p, &map32->vaddrin);
err |= put_user(p, (uintptr_t *)&map->vaddrin);
err |= get_user(s, &map32->size);
err |= put_user(s, &map->size);
return err;
}
static int compat_get_fastrpc_ioctl_mmap_64(
struct compat_fastrpc_ioctl_mmap_64 __user *map32,
struct fastrpc_ioctl_mmap __user *map)
{
compat_uint_t u;
compat_int_t i;
compat_size_t s;
compat_u64 p;
int err;
err = get_user(i, &map32->fd);
err |= put_user(i, &map->fd);
err |= get_user(u, &map32->flags);
err |= put_user(u, &map->flags);
err |= get_user(p, &map32->vaddrin);
err |= put_user(p, &map->vaddrin);
err |= get_user(s, &map32->size);
err |= put_user(s, &map->size);
return err;
}
static int compat_put_fastrpc_ioctl_mmap(
struct compat_fastrpc_ioctl_mmap __user *map32,
struct fastrpc_ioctl_mmap __user *map)
{
compat_uptr_t p;
int err;
err = get_user(p, &map->vaddrout);
err |= put_user(p, &map32->vaddrout);
return err;
}
static int compat_put_fastrpc_ioctl_mmap_64(
struct compat_fastrpc_ioctl_mmap_64 __user *map32,
struct fastrpc_ioctl_mmap __user *map)
{
compat_u64 p;
int err;
err = get_user(p, &map->vaddrout);
err |= put_user(p, &map32->vaddrout);
return err;
}
static int compat_get_fastrpc_ioctl_munmap(
struct compat_fastrpc_ioctl_munmap __user *unmap32,
struct fastrpc_ioctl_munmap __user *unmap)
{
compat_uptr_t p;
compat_size_t s;
int err;
err = get_user(p, &unmap32->vaddrout);
err |= put_user(p, &unmap->vaddrout);
err |= get_user(s, &unmap32->size);
err |= put_user(s, &unmap->size);
return err;
}
static int compat_get_fastrpc_ioctl_munmap_64(
struct compat_fastrpc_ioctl_munmap_64 __user *unmap32,
struct fastrpc_ioctl_munmap __user *unmap)
{
compat_u64 p;
compat_size_t s;
int err;
err = get_user(p, &unmap32->vaddrout);
err |= put_user(p, &unmap->vaddrout);
err |= get_user(s, &unmap32->size);
err |= put_user(s, &unmap->size);
return err;
}
static int compat_get_fastrpc_ioctl_perf(
struct compat_fastrpc_ioctl_perf __user *perf32,
struct fastrpc_ioctl_perf __user *perf)
{
compat_uptr_t p;
int err;
err = get_user(p, &perf32->data);
err |= put_user(p, &perf->data);
err |= get_user(p, &perf32->keys);
err |= put_user(p, &perf->keys);
return err;
}
static int compat_get_fastrpc_ioctl_control(
struct compat_fastrpc_ioctl_control __user *ctrl32,
struct fastrpc_ioctl_control __user *ctrl)
{
compat_uptr_t p;
int err;
err = get_user(p, &ctrl32->req);
err |= put_user(p, &ctrl->req);
if (p == FASTRPC_CONTROL_LATENCY) {
err |= get_user(p, &ctrl32->lp.enable);
err |= put_user(p, &ctrl->lp.enable);
err |= get_user(p, &ctrl32->lp.latency);
err |= put_user(p, &ctrl->lp.latency);
}
return err;
}
static int compat_get_fastrpc_ioctl_init(
struct compat_fastrpc_ioctl_init_attrs __user *init32,
struct fastrpc_ioctl_init_attrs __user *init,
unsigned int cmd)
{
compat_uint_t u;
compat_uptr_t p;
compat_int_t i;
int err;
err = get_user(u, &init32->init.flags);
err |= put_user(u, &init->init.flags);
err |= get_user(p, &init32->init.file);
err |= put_user(p, &init->init.file);
err |= get_user(i, &init32->init.filelen);
err |= put_user(i, &init->init.filelen);
err |= get_user(i, &init32->init.filefd);
err |= put_user(i, &init->init.filefd);
err |= get_user(p, &init32->init.mem);
err |= put_user(p, &init->init.mem);
err |= get_user(i, &init32->init.memlen);
err |= put_user(i, &init->init.memlen);
err |= get_user(i, &init32->init.memfd);
err |= put_user(i, &init->init.memfd);
err |= put_user(0, &init->attrs);
if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
err |= get_user(i, &init32->attrs);
err |= put_user(i, (compat_uptr_t *)&init->attrs);
}
err |= put_user(0, &init->siglen);
if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
err |= get_user(i, &init32->siglen);
err |= put_user(i, (compat_uptr_t *)&init->siglen);
}
return err;
}
static int compat_put_fastrpc_ioctl_get_dsp_info(
struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32,
struct fastrpc_ioctl_remote_dsp_capability __user *info)
{
compat_uint_t u;
int err = 0;
err |= get_user(u, &info->capability);
err |= put_user(u, &info32->capability);
return err;
}
static int fastrpc_setmode(struct file *filp, unsigned int cmd,
unsigned long arg)
{
return filp->f_op->unlocked_ioctl(filp, cmd,
(unsigned long)compat_ptr(arg));
}
static int compat_fastrpc_control(struct file *filp,
unsigned long arg)
{
int err = 0;
struct compat_fastrpc_ioctl_control __user *ctrl32;
struct fastrpc_ioctl_control __user *ctrl;
compat_uptr_t p;
ctrl32 = compat_ptr(arg);
VERIFY(err, NULL != (ctrl = compat_alloc_user_space(
sizeof(*ctrl))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32,
ctrl));
if (err)
return err;
err = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_CONTROL,
(unsigned long)ctrl);
if (err)
return err;
err = get_user(p, &ctrl32->req);
if (err)
return err;
if (p == FASTRPC_CONTROL_KALLOC) {
err = get_user(p, &ctrl->kalloc.kalloc_support);
err |= put_user(p, &ctrl32->kalloc.kalloc_support);
}
return err;
}
static int compat_fastrpc_getperf(struct file *filp,
unsigned long arg)
{
int err = 0;
struct compat_fastrpc_ioctl_perf __user *perf32;
struct fastrpc_ioctl_perf *perf;
compat_uint_t u;
long ret;
perf32 = compat_ptr(arg);
VERIFY(err, NULL != (perf = compat_alloc_user_space(
sizeof(*perf))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_perf(perf32,
perf));
if (err)
return err;
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETPERF,
(unsigned long)perf);
if (ret)
return ret;
err = get_user(u, &perf->numkeys);
err |= put_user(u, &perf32->numkeys);
return err;
}
static int compat_fastrpc_get_dsp_info(struct file *filp,
unsigned long arg)
{
struct compat_fastrpc_ioctl_remote_dsp_capability __user *info32;
struct fastrpc_ioctl_remote_dsp_capability *info;
compat_uint_t u;
long ret;
int err = 0;
info32 = compat_ptr(arg);
VERIFY(err, NULL != (info = compat_alloc_user_space(
sizeof(*info))));
if (err)
return -EFAULT;
err = get_user(u, &info32->domain);
err |= put_user(u, &info->domain);
if (err)
return err;
ret = filp->f_op->unlocked_ioctl(filp,
FASTRPC_IOCTL_GET_DSP_INFO,
(unsigned long)info);
if (ret)
return ret;
err = compat_put_fastrpc_ioctl_get_dsp_info(info32, info);
return err;
}
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int err = 0;
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
return -ENOTTY;
switch (cmd) {
case COMPAT_FASTRPC_IOCTL_INVOKE:
case COMPAT_FASTRPC_IOCTL_INVOKE_FD:
case COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS:
case COMPAT_FASTRPC_IOCTL_INVOKE_CRC:
{
return compat_fastrpc_ioctl_invoke(filp, cmd, arg);
}
case COMPAT_FASTRPC_IOCTL_INVOKE2:
{
return compat_fastrpc_ioctl_invoke2(filp, cmd, arg);
}
case COMPAT_FASTRPC_IOCTL_MMAP:
{
struct compat_fastrpc_ioctl_mmap __user *map32;
struct fastrpc_ioctl_mmap __user *map;
long ret;
map32 = compat_ptr(arg);
VERIFY(err, NULL != (map = compat_alloc_user_space(
sizeof(*map))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap(map32, map));
if (err)
return err;
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MMAP,
(unsigned long)map);
if (ret)
return ret;
VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map));
return err;
}
case COMPAT_FASTRPC_IOCTL_MMAP_64:
{
struct compat_fastrpc_ioctl_mmap_64 __user *map32;
struct fastrpc_ioctl_mmap __user *map;
long ret;
map32 = compat_ptr(arg);
VERIFY(err, NULL != (map = compat_alloc_user_space(
sizeof(*map))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map));
if (err)
return err;
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MMAP_64,
(unsigned long)map);
if (ret)
return ret;
VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map));
return err;
}
case COMPAT_FASTRPC_IOCTL_MUNMAP:
{
struct compat_fastrpc_ioctl_munmap __user *unmap32;
struct fastrpc_ioctl_munmap __user *unmap;
unmap32 = compat_ptr(arg);
VERIFY(err, NULL != (unmap = compat_alloc_user_space(
sizeof(*unmap))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap(unmap32,
unmap));
if (err)
return err;
return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP,
(unsigned long)unmap);
}
case COMPAT_FASTRPC_IOCTL_MUNMAP_64:
{
struct compat_fastrpc_ioctl_munmap_64 __user *unmap32;
struct fastrpc_ioctl_munmap __user *unmap;
unmap32 = compat_ptr(arg);
VERIFY(err, NULL != (unmap = compat_alloc_user_space(
sizeof(*unmap))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32,
unmap));
if (err)
return err;
return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP_64,
(unsigned long)unmap);
}
case COMPAT_FASTRPC_IOCTL_INIT:
/* fall through */
case COMPAT_FASTRPC_IOCTL_INIT_ATTRS:
{
struct compat_fastrpc_ioctl_init_attrs __user *init32;
struct fastrpc_ioctl_init_attrs __user *init;
init32 = compat_ptr(arg);
VERIFY(err, NULL != (init = compat_alloc_user_space(
sizeof(*init))));
if (err)
return -EFAULT;
VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32,
init, cmd));
if (err)
return err;
return filp->f_op->unlocked_ioctl(filp,
FASTRPC_IOCTL_INIT_ATTRS, (unsigned long)init);
}
case FASTRPC_IOCTL_GETINFO:
{
compat_uptr_t __user *info32;
uint32_t __user *info;
compat_uint_t u;
long ret;
info32 = compat_ptr(arg);
VERIFY(err, NULL != (info = compat_alloc_user_space(
sizeof(*info))));
if (err)
return -EFAULT;
err = get_user(u, info32);
err |= put_user(u, info);
if (err)
return err;
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETINFO,
(unsigned long)info);
if (ret)
return ret;
err = get_user(u, info);
err |= put_user(u, info32);
return err;
}
case FASTRPC_IOCTL_SETMODE:
return fastrpc_setmode(filp, cmd, arg);
case COMPAT_FASTRPC_IOCTL_CONTROL:
{
return compat_fastrpc_control(filp, arg);
}
case COMPAT_FASTRPC_IOCTL_GETPERF:
{
return compat_fastrpc_getperf(filp, arg);
}
case COMPAT_FASTRPC_IOCTL_GET_DSP_INFO:
{
return compat_fastrpc_get_dsp_info(filp, arg);
}
default:
return -ENOIOCTLCMD;
}
}

View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014, 2018-2019 The Linux Foundation. All rights reserved.
*/
#ifndef ADSPRPC_COMPAT_H
#define ADSPRPC_COMPAT_H
#if IS_ENABLED(CONFIG_COMPAT)
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
#else
#define compat_fastrpc_device_ioctl NULL
#endif /* CONFIG_COMPAT */
#endif /* ADSPRPC_COMPAT_H */

View File

@ -0,0 +1,381 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef ADSPRPC_SHARED_H
#define ADSPRPC_SHARED_H
#include <linux/types.h>
#define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke)
#define FASTRPC_IOCTL_MMAP _IOWR('R', 2, struct fastrpc_ioctl_mmap)
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 3, struct fastrpc_ioctl_munmap)
#define FASTRPC_IOCTL_MMAP_64 _IOWR('R', 14, struct fastrpc_ioctl_mmap_64)
#define FASTRPC_IOCTL_MUNMAP_64 _IOWR('R', 15, struct fastrpc_ioctl_munmap_64)
#define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd)
#define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t)
#define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init)
#define FASTRPC_IOCTL_INVOKE_ATTRS \
_IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs)
#define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t)
#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf)
#define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs)
#define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc)
#define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control)
#define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd)
#define FASTRPC_IOCTL_GET_DSP_INFO \
_IOWR('R', 17, struct fastrpc_ioctl_remote_dsp_capability)
#define FASTRPC_IOCTL_INVOKE2 _IOWR('R', 18, struct fastrpc_ioctl_invoke2)
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
#define DEVICE_NAME "adsprpc-smd"
#define DEVICE_NAME_SECURE "adsprpc-smd-secure"
/* Set for buffers that have no virtual mapping in userspace */
#define FASTRPC_ATTR_NOVA 0x1
/* Set for buffers that are NOT dma coherent */
#define FASTRPC_ATTR_NON_COHERENT 0x2
/* Set for buffers that are dma coherent */
#define FASTRPC_ATTR_COHERENT 0x4
/* Fastrpc attribute for keeping the map persistent */
#define FASTRPC_ATTR_KEEP_MAP 0x8
/* Fastrpc attribute for no mapping of fd */
#define FASTRPC_ATTR_NOMAP (16)
/*
* Fastrpc attribute to skip flush by fastrpc
*/
#define FASTRPC_ATTR_FORCE_NOFLUSH (32)
/*
* Fastrpc attribute to skip invalidate by fastrpc
*/
#define FASTRPC_ATTR_FORCE_NOINVALIDATE (64)
/* Driver should operate in parallel with the co-processor */
#define FASTRPC_MODE_PARALLEL 0
/* Driver should operate in serial mode with the co-processor */
#define FASTRPC_MODE_SERIAL 1
/* Driver should operate in profile mode with the co-processor */
#define FASTRPC_MODE_PROFILE 2
/* Set FastRPC session ID to 1 */
#define FASTRPC_MODE_SESSION 4
/* INIT a new process or attach to guestos */
#define FASTRPC_INIT_ATTACH 0
#define FASTRPC_INIT_CREATE 1
#define FASTRPC_INIT_CREATE_STATIC 2
#define FASTRPC_INIT_ATTACH_SENSORS 3
/* Retrives number of input buffers from the scalars parameter */
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
/* Retrives number of output buffers from the scalars parameter */
#define REMOTE_SCALARS_OUTBUFS(sc) (((sc) >> 8) & 0x0ff)
/* Retrives number of input handles from the scalars parameter */
#define REMOTE_SCALARS_INHANDLES(sc) (((sc) >> 4) & 0x0f)
/* Retrives number of output handles from the scalars parameter */
#define REMOTE_SCALARS_OUTHANDLES(sc) ((sc) & 0x0f)
#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\
REMOTE_SCALARS_OUTBUFS(sc) +\
REMOTE_SCALARS_INHANDLES(sc) +\
REMOTE_SCALARS_OUTHANDLES(sc))
#define REMOTE_SCALARS_MAKEX(attr, method, in, out, oin, oout) \
((((uint32_t) (attr) & 0x7) << 29) | \
(((uint32_t) (method) & 0x1f) << 24) | \
(((uint32_t) (in) & 0xff) << 16) | \
(((uint32_t) (out) & 0xff) << 8) | \
(((uint32_t) (oin) & 0x0f) << 4) | \
((uint32_t) (oout) & 0x0f))
#define REMOTE_SCALARS_MAKE(method, in, out) \
REMOTE_SCALARS_MAKEX(0, method, in, out, 0, 0)
#ifndef VERIFY_PRINT_ERROR
#define VERIFY_EPRINTF(format, args) (void)0
#endif
#ifndef VERIFY_PRINT_INFO
#define VERIFY_IPRINTF(args) (void)0
#endif
#ifndef VERIFY
#define __STR__(x) #x ":"
#define __TOSTR__(x) __STR__(x)
#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__)
#define VERIFY(err, val) \
do {\
VERIFY_IPRINTF(__FILE_LINE__"info: calling: " #val "\n");\
if ((val) == 0) {\
(err) = (err) == 0 ? -1 : (err);\
VERIFY_EPRINTF(__FILE_LINE__"error: %d: " #val "\n", (err));\
} else {\
VERIFY_IPRINTF(__FILE_LINE__"info: passed: " #val "\n");\
} \
} while (0)
#endif
#define remote_arg64_t union remote_arg64
struct remote_buf64 {
uint64_t pv;
uint64_t len;
};
struct remote_dma_handle64 {
int fd;
uint32_t offset;
uint32_t len;
};
union remote_arg64 {
struct remote_buf64 buf;
struct remote_dma_handle64 dma;
uint32_t h;
};
#define remote_arg_t union remote_arg
struct remote_buf {
void *pv; /* buffer pointer */
size_t len; /* length of buffer */
};
struct remote_dma_handle {
int fd;
uint32_t offset;
};
union remote_arg {
struct remote_buf buf; /* buffer info */
struct remote_dma_handle dma;
uint32_t h; /* remote handle */
};
struct fastrpc_ioctl_invoke {
uint32_t handle; /* remote handle */
uint32_t sc; /* scalars describing the data */
remote_arg_t *pra; /* remote arguments list */
};
struct fastrpc_ioctl_invoke_fd {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
};
struct fastrpc_ioctl_invoke_attrs {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
unsigned int *attrs; /* attribute list */
};
struct fastrpc_ioctl_invoke_crc {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
unsigned int *attrs; /* attribute list */
unsigned int *crc;
};
struct fastrpc_async_job {
uint32_t isasyncjob; /* flag to distinguish async job */
uint64_t jobid; /* job id generated by user */
uint32_t reserved; /* reserved */
};
struct fastrpc_ioctl_invoke_async {
struct fastrpc_ioctl_invoke inv;
int *fds; /* fd list */
unsigned int *attrs; /* attribute list */
unsigned int *crc;
struct fastrpc_async_job *job; /* async job*/
};
struct fastrpc_ioctl_async_response {
uint64_t jobid;/* job id generated by user */
int result; /* result from DSP */
};
enum fastrpc_invoke2_type {
FASTRPC_INVOKE2_ASYNC = 1,
FASTRPC_INVOKE2_ASYNC_RESPONSE = 2,
};
struct fastrpc_ioctl_invoke2 {
uint32_t req; /* type of invocation request */
uintptr_t invparam; /* invocation request param */
uint32_t size; /* size of invocation param */
int err; /* reserved */
};
struct fastrpc_ioctl_init {
uint32_t flags; /* one of FASTRPC_INIT_* macros */
uintptr_t file; /* pointer to elf file */
uint32_t filelen; /* elf file length */
int32_t filefd; /* ION fd for the file */
uintptr_t mem; /* mem for the PD */
uint32_t memlen; /* mem length */
int32_t memfd; /* ION fd for the mem */
};
struct fastrpc_ioctl_init_attrs {
struct fastrpc_ioctl_init init;
int attrs;
unsigned int siglen;
};
struct fastrpc_ioctl_munmap {
uintptr_t vaddrout; /* address to unmap */
size_t size; /* size */
};
struct fastrpc_ioctl_munmap_64 {
uint64_t vaddrout; /* address to unmap */
size_t size; /* size */
};
struct fastrpc_ioctl_mmap {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
uintptr_t vaddrin; /* optional virtual address */
size_t size; /* size */
uintptr_t vaddrout; /* dsps virtual address */
};
struct fastrpc_ioctl_mmap_64 {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
uint64_t vaddrin; /* optional virtual address */
size_t size; /* size */
uint64_t vaddrout; /* dsps virtual address */
};
struct fastrpc_ioctl_munmap_fd {
int fd; /* fd */
uint32_t flags; /* control flags */
uintptr_t va; /* va */
ssize_t len; /* length */
};
struct fastrpc_ioctl_perf { /* kernel performance data */
uintptr_t data;
uint32_t numkeys;
uintptr_t keys;
};
enum fastrpc_control_type {
FASTRPC_CONTROL_LATENCY = 1,
FASTRPC_CONTROL_SMMU = 2,
FASTRPC_CONTROL_KALLOC = 3,
FASTRPC_CONTROL_WAKELOCK = 4,
};
struct fastrpc_ctrl_latency {
uint32_t enable; /* latency control enable */
uint32_t latency; /* latency request in us */
};
struct fastrpc_ctrl_kalloc {
uint32_t kalloc_support; /* Remote memory allocation from kernel */
};
struct fastrpc_ctrl_wakelock {
uint32_t enable; /* wakelock control enable */
};
struct fastrpc_ioctl_control {
uint32_t req;
union {
struct fastrpc_ctrl_latency lp;
struct fastrpc_ctrl_kalloc kalloc;
struct fastrpc_ctrl_wakelock wp;
};
};
#define FASTRPC_MAX_DSP_ATTRIBUTES (9)
#define ASYNC_FASTRPC_CAP (8)
struct fastrpc_ioctl_remote_dsp_capability {
uint32_t domain;
uint32_t attribute_ID;
uint32_t capability;
};
struct smq_null_invoke {
uint64_t ctx; /* invoke caller context */
uint32_t handle; /* handle to invoke */
uint32_t sc; /* scalars structure describing the data */
};
struct smq_phy_page {
uint64_t addr; /* physical address */
uint64_t size; /* size of contiguous region */
};
struct smq_invoke_buf {
int num; /* number of contiguous regions */
int pgidx; /* index to start of contiguous region */
};
struct smq_invoke {
struct smq_null_invoke header;
struct smq_phy_page page; /* remote arg and list of pages address */
};
struct smq_msg {
uint32_t pid; /* process group id */
uint32_t tid; /* thread id */
struct smq_invoke invoke;
};
struct smq_invoke_rsp {
uint64_t ctx; /* invoke caller context */
int retval; /* invoke return value */
};
enum fastrpc_response_flags {
NORMAL_RESPONSE = 0,
EARLY_RESPONSE = 1,
USER_EARLY_SIGNAL = 2,
COMPLETE_SIGNAL = 3
};
struct smq_invoke_rspv2 {
uint64_t ctx; /* invoke caller context */
int retval; /* invoke return value */
uint32_t flags; /* early response flags */
uint32_t early_wake_time; /* user predicted early wakeup time in us */
uint32_t version; /* Version number for validation */
};
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
uint32_t sc)
{
unsigned int len = REMOTE_SCALARS_LENGTH(sc);
return (struct smq_invoke_buf *)(&pra[len]);
}
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
struct smq_invoke_buf *buf)
{
unsigned int nTotal = REMOTE_SCALARS_LENGTH(sc);
return (struct smq_phy_page *)(&buf[nTotal]);
}
#endif

View File

@ -321,6 +321,20 @@ config HW_RANDOM_HISI_V2
If unsure, say Y.
config HW_RANDOM_MSM_LEGACY
tristate "QTI MSM Random Number Generator support (LEGACY)"
depends on HW_RANDOM && ARCH_QCOM
select CRYPTO_AES
select CRYPTO_ECB
help
This driver provides kernel-side support for the Random Number
Generator hardware found on QTI MSM SoCs.
To compile this driver as a module, choose M here: the
module will be called msm_rng.
If unsure, say Y.
config HW_RANDOM_ST
tristate "ST Microelectronics HW Random Number Generator support"
depends on HW_RANDOM && ARCH_STI

View File

@ -30,6 +30,7 @@ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
obj-$(CONFIG_HW_RANDOM_HISI_V2) += hisi-trng-v2.o
obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
obj-$(CONFIG_HW_RANDOM_MSM_LEGACY) += msm_rng.o
obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o
obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o

View File

@ -0,0 +1,484 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2013, 2015, 2017-2020 The Linux Foundation. All rights
* reserved.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/of.h>
#include <linux/qrng.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/crypto.h>
#include <crypto/internal/rng.h>
#include <linux/interconnect.h>
#include <linux/sched/signal.h>
#define DRIVER_NAME "msm_rng"
/* Device specific register offsets */
#define PRNG_DATA_OUT_OFFSET 0x0000
#define PRNG_STATUS_OFFSET 0x0004
#define PRNG_LFSR_CFG_OFFSET 0x0100
#define PRNG_CONFIG_OFFSET 0x0104
/* Device specific register masks and config values */
#define PRNG_LFSR_CFG_MASK 0xFFFF0000
#define PRNG_LFSR_CFG_CLOCKS 0x0000DDDD
#define PRNG_CONFIG_MASK 0xFFFFFFFD
#define PRNG_HW_ENABLE 0x00000002
#define MAX_HW_FIFO_DEPTH 16 /* FIFO is 16 words deep */
#define MAX_HW_FIFO_SIZE (MAX_HW_FIFO_DEPTH * 4) /* FIFO is 32 bits wide */
#define RETRY_MAX_CNT 5 /* max retry times to read register */
#define RETRY_DELAY_INTERVAL 440 /* retry delay interval in us */
struct msm_rng_device {
struct platform_device *pdev;
void __iomem *base;
struct clk *prng_clk;
struct mutex rng_lock;
struct icc_path *icc_path;
};
static struct msm_rng_device msm_rng_device_info;
static struct msm_rng_device *msm_rng_dev_cached;
static struct mutex cached_rng_lock;
static long msm_rng_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
long ret = 0;
switch (cmd) {
case QRNG_IOCTL_RESET_BUS_BANDWIDTH:
pr_debug("calling msm_rng_bus_scale(LOW)\n");
ret = icc_set_bw(msm_rng_device_info.icc_path, 0, 0);
if (ret)
pr_err("failed qrng_reset_bus_bw, ret = %ld\n", ret);
break;
default:
pr_err("Unsupported IOCTL call\n");
break;
}
return ret;
}
/*
*
* This function calls hardware random bit generator directory and retuns it
* back to caller
*
*/
static int msm_rng_direct_read(struct msm_rng_device *msm_rng_dev,
void *data, size_t max)
{
struct platform_device *pdev;
void __iomem *base;
size_t currsize = 0;
u32 val = 0;
u32 *retdata = data;
int ret;
int failed = 0;
pdev = msm_rng_dev->pdev;
base = msm_rng_dev->base;
/* no room for word data */
if (max < 4)
return 0;
mutex_lock(&msm_rng_dev->rng_lock);
if (msm_rng_dev->icc_path) {
ret = icc_set_bw(msm_rng_dev->icc_path, 0, 300000);
if (ret) {
pr_err("bus_scale_client_update_req failed\n");
goto bus_err;
}
}
/* enable PRNG clock */
if (msm_rng_dev->prng_clk) {
ret = clk_prepare_enable(msm_rng_dev->prng_clk);
if (ret) {
pr_err("failed to enable prng clock\n");
goto err;
}
}
/* read random data from h/w */
do {
/* check status bit if data is available */
if (!(readl_relaxed(base + PRNG_STATUS_OFFSET)
& 0x00000001)) {
if (failed++ == RETRY_MAX_CNT) {
if (currsize == 0)
pr_err("Data not available\n");
break;
}
udelay(RETRY_DELAY_INTERVAL);
} else {
/* read FIFO */
val = readl_relaxed(base + PRNG_DATA_OUT_OFFSET);
/* write data back to callers pointer */
*(retdata++) = val;
currsize += 4;
/* make sure we stay on 32bit boundary */
if ((max - currsize) < 4)
break;
}
} while (currsize < max);
/* vote to turn off clock */
if (msm_rng_dev->prng_clk)
clk_disable_unprepare(msm_rng_dev->prng_clk);
err:
if (msm_rng_dev->icc_path) {
ret = icc_set_bw(msm_rng_dev->icc_path, 0, 0);
if (ret)
pr_err("bus_scale_client_update_req failed\n");
}
bus_err:
mutex_unlock(&msm_rng_dev->rng_lock);
val = 0L;
return currsize;
}
static int msm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
struct msm_rng_device *msm_rng_dev;
int rv = 0;
msm_rng_dev = (struct msm_rng_device *)rng->priv;
rv = msm_rng_direct_read(msm_rng_dev, data, max);
return rv;
}
static struct hwrng msm_rng = {
.name = DRIVER_NAME,
.read = msm_rng_read,
.quality = 1024,
};
static int msm_rng_enable_hw(struct msm_rng_device *msm_rng_dev)
{
unsigned long val = 0;
unsigned long reg_val = 0;
int ret = 0;
if (msm_rng_dev->icc_path) {
ret = icc_set_bw(msm_rng_dev->icc_path, 0, 30000);
if (ret)
pr_err("bus_scale_client_update_req failed\n");
}
/* Enable the PRNG CLK */
if (msm_rng_dev->prng_clk) {
ret = clk_prepare_enable(msm_rng_dev->prng_clk);
if (ret) {
dev_err(&(msm_rng_dev->pdev)->dev,
"failed to enable clock in probe\n");
return -EPERM;
}
}
/* Enable PRNG h/w only if it is NOT ON */
val = readl_relaxed(msm_rng_dev->base + PRNG_CONFIG_OFFSET) &
PRNG_HW_ENABLE;
/* PRNG H/W is not ON */
if (val != PRNG_HW_ENABLE) {
val = readl_relaxed(msm_rng_dev->base + PRNG_LFSR_CFG_OFFSET);
val &= PRNG_LFSR_CFG_MASK;
val |= PRNG_LFSR_CFG_CLOCKS;
writel_relaxed(val, msm_rng_dev->base + PRNG_LFSR_CFG_OFFSET);
/* The PRNG CONFIG register should be first written */
mb();
reg_val = readl_relaxed(msm_rng_dev->base + PRNG_CONFIG_OFFSET)
& PRNG_CONFIG_MASK;
reg_val |= PRNG_HW_ENABLE;
writel_relaxed(reg_val, msm_rng_dev->base + PRNG_CONFIG_OFFSET);
/* The PRNG clk should be disabled only after we enable the
* PRNG h/w by writing to the PRNG CONFIG register.
*/
mb();
}
if (msm_rng_dev->prng_clk)
clk_disable_unprepare(msm_rng_dev->prng_clk);
if (msm_rng_dev->icc_path) {
ret = icc_set_bw(msm_rng_dev->icc_path, 0, 0);
if (ret)
pr_err("bus_scale_client_update_req failed\n");
}
return 0;
}
static const struct file_operations msm_rng_fops = {
.unlocked_ioctl = msm_rng_ioctl,
};
static struct class *msm_rng_class;
static struct cdev msm_rng_cdev;
static int msm_rng_probe(struct platform_device *pdev)
{
struct resource *res;
struct msm_rng_device *msm_rng_dev = NULL;
void __iomem *base = NULL;
bool configure_qrng = true;
int error = 0;
struct device *dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "invalid address\n");
error = -EFAULT;
goto err_exit;
}
msm_rng_dev = kzalloc(sizeof(struct msm_rng_device), GFP_KERNEL);
if (!msm_rng_dev) {
error = -ENOMEM;
goto err_exit;
}
base = ioremap(res->start, resource_size(res));
if (!base) {
dev_err(&pdev->dev, "ioremap failed\n");
error = -ENOMEM;
goto err_iomap;
}
msm_rng_dev->base = base;
/* create a handle for clock control */
if (pdev->dev.of_node) {
if (of_property_read_bool(pdev->dev.of_node,
"qcom,no-clock-support"))
msm_rng_dev->prng_clk = NULL;
else
msm_rng_dev->prng_clk = clk_get(&pdev->dev,
"km_clk_src");
}
if (IS_ERR(msm_rng_dev->prng_clk)) {
dev_err(&pdev->dev, "failed to register clock source\n");
error = -ENODEV;
goto err_clk_get;
}
/* save away pdev and register driver data */
msm_rng_dev->pdev = pdev;
platform_set_drvdata(pdev, msm_rng_dev);
if (pdev->dev.of_node) {
msm_rng_dev->icc_path = of_icc_get(&pdev->dev, "data_path");
msm_rng_device_info.icc_path = msm_rng_dev->icc_path;
if (IS_ERR(msm_rng_dev->icc_path)) {
error = PTR_ERR(msm_rng_dev->icc_path);
dev_err(&pdev->dev, "get icc path err %d\n", error);
goto err_icc_get;
}
}
/* Enable rng h/w for the targets which can access the entire
* address space of PRNG.
*/
if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
"qcom,no-qrng-config")))
configure_qrng = false;
if (configure_qrng) {
error = msm_rng_enable_hw(msm_rng_dev);
if (error)
goto err_icc_get;
}
mutex_init(&msm_rng_dev->rng_lock);
mutex_init(&cached_rng_lock);
/* register with hwrng framework */
msm_rng.priv = (unsigned long) msm_rng_dev;
error = hwrng_register(&msm_rng);
if (error) {
dev_err(&pdev->dev, "failed to register hwrng\n");
goto err_reg_hwrng;
}
error = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);
if (error) {
dev_err(&pdev->dev, "failed to register chrdev\n");
goto err_reg_chrdev;
}
msm_rng_class = class_create(THIS_MODULE, "msm-rng");
if (IS_ERR(msm_rng_class)) {
pr_err("class_create failed\n");
error = PTR_ERR(msm_rng_class);
goto err_create_cls;
}
dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
NULL, "msm-rng");
if (IS_ERR(dev)) {
pr_err("Device create failed\n");
error = PTR_ERR(dev);
goto err_create_dev;
}
cdev_init(&msm_rng_cdev, &msm_rng_fops);
msm_rng_dev_cached = msm_rng_dev;
return error;
err_create_dev:
class_destroy(msm_rng_class);
err_create_cls:
unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
err_reg_chrdev:
hwrng_unregister(&msm_rng);
err_reg_hwrng:
if (msm_rng_dev->icc_path)
icc_put(msm_rng_dev->icc_path);
err_icc_get:
if (msm_rng_dev->prng_clk)
clk_put(msm_rng_dev->prng_clk);
err_clk_get:
iounmap(msm_rng_dev->base);
err_iomap:
kzfree(msm_rng_dev);
err_exit:
return error;
}
static int msm_rng_remove(struct platform_device *pdev)
{
struct msm_rng_device *msm_rng_dev = platform_get_drvdata(pdev);
unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
hwrng_unregister(&msm_rng);
if (msm_rng_dev->prng_clk)
clk_put(msm_rng_dev->prng_clk);
iounmap(msm_rng_dev->base);
platform_set_drvdata(pdev, NULL);
if (msm_rng_dev->icc_path)
icc_put(msm_rng_dev->icc_path);
kzfree(msm_rng_dev);
msm_rng_dev_cached = NULL;
return 0;
}
static int qrng_get_random(struct crypto_rng *tfm, const u8 *src,
unsigned int slen, u8 *rdata,
unsigned int dlen)
{
int sizeread = 0;
int rv = -EFAULT;
if (!msm_rng_dev_cached) {
pr_err("%s: msm_rng_dev is not initialized\n", __func__);
rv = -ENODEV;
goto err_exit;
}
if (!rdata) {
pr_err("%s: data buffer is null\n", __func__);
rv = -EINVAL;
goto err_exit;
}
if (signal_pending(current) ||
mutex_lock_interruptible(&cached_rng_lock)) {
pr_err("%s: mutex lock interrupted\n", __func__);
rv = -ERESTARTSYS;
goto err_exit;
}
sizeread = msm_rng_direct_read(msm_rng_dev_cached, rdata, dlen);
if (sizeread == dlen)
rv = 0;
mutex_unlock(&cached_rng_lock);
err_exit:
return rv;
}
static int qrng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
{
return 0;
}
static struct rng_alg rng_algs[] = { {
.generate = qrng_get_random,
.seed = qrng_reset,
.seedsize = 0,
.base = {
.cra_name = "qrng",
.cra_driver_name = "fips_hw_qrng",
.cra_priority = 300,
.cra_ctxsize = 0,
.cra_module = THIS_MODULE,
}
} };
static const struct of_device_id qrng_match[] = {
{.compatible = "qcom,msm-rng"},
{},
};
static struct platform_driver rng_driver = {
.probe = msm_rng_probe,
.remove = msm_rng_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = qrng_match,
},
};
static int __init msm_rng_init(void)
{
int ret;
msm_rng_dev_cached = NULL;
ret = platform_driver_register(&rng_driver);
if (ret) {
pr_err("%s: platform_driver_register error:%d\n",
__func__, ret);
goto err_exit;
}
ret = crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs));
if (ret) {
pr_err("%s: crypto_register_algs error:%d\n",
__func__, ret);
goto err_exit;
}
err_exit:
return ret;
}
module_init(msm_rng_init);
static void __exit msm_rng_exit(void)
{
crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs));
platform_driver_unregister(&rng_driver);
}
module_exit(msm_rng_exit);
MODULE_DESCRIPTION("QTI MSM Random Number Driver");
MODULE_LICENSE("GPL v2");

View File

@ -978,13 +978,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if (wait_startup(chip, 0) != 0) {
rc = -ENODEV;
goto out_err;
goto err_start;
}
/* Take control of the TPM's interrupt hardware and shut it off */
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
goto out_err;
goto err_start;
intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
@ -993,21 +993,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
rc = tpm_chip_start(chip);
if (rc)
goto out_err;
goto err_start;
rc = tpm2_probe(chip);
tpm_chip_stop(chip);
if (rc)
goto out_err;
goto err_probe;
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
if (rc < 0)
goto out_err;
goto err_probe;
priv->manufacturer_id = vendor;
rc = tpm_tis_read8(priv, TPM_RID(0), &rid);
if (rc < 0)
goto out_err;
goto err_probe;
dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n",
(chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
@ -1016,13 +1016,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
probe = probe_itpm(chip);
if (probe < 0) {
rc = -ENODEV;
goto out_err;
goto err_probe;
}
/* Figure out the capabilities */
rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps);
if (rc < 0)
goto out_err;
goto err_probe;
dev_dbg(dev, "TPM interface capabilities (0x%x):\n",
intfcaps);
@ -1056,7 +1056,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if (tpm_get_timeouts(chip)) {
dev_err(dev, "Could not get TPM timeouts and durations\n");
rc = -ENODEV;
goto out_err;
goto err_probe;
}
if (irq) {
@ -1070,15 +1070,18 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
}
}
tpm_chip_stop(chip);
rc = tpm_chip_register(chip);
if (rc)
goto out_err;
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, false);
goto err_start;
return 0;
out_err:
err_probe:
tpm_chip_stop(chip);
err_start:
if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL))
chip->ops->clk_enable(chip, false);

View File

@ -23,6 +23,15 @@ config COMMON_CLK
menu "Common Clock Framework"
depends on COMMON_CLK
config COMMON_CLK_QCOM_DEBUG
bool "QCOM clock debug features"
depends on DEBUG_FS && QGKI
help
Support for QCOM debug features. These features include
modifications to existing debugfs nodes to make them writable (e.g.
clk_enable_count, clk_rate), as well as new debugfs nodes (e.g.
clk_enabled_list, debug_suspend, trace_clocks).
config COMMON_CLK_WM831X
tristate "Clock driver for WM831x/2x PMICs"
depends on MFD_WM831X

View File

@ -295,6 +295,9 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
unsigned long parent_rate, best = 0, now, maxdiv;
unsigned long parent_rate_saved = *best_parent_rate;
if (!hw || !parent)
return -EINVAL;
if (!rate)
rate = 1;
@ -508,6 +511,7 @@ struct clk_hw *__clk_hw_register_divider(struct device *dev,
/* register the clock */
hw = &div->hw;
ret = clk_hw_register(dev, hw);
hw->init = NULL;
if (ret) {
kfree(div);
hw = ERR_PTR(ret);

View File

@ -98,6 +98,7 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
ret = clk_hw_register(dev, hw);
else
ret = of_clk_hw_register(np, hw);
hw->init = NULL;
if (ret) {
kfree(fix);
hw = ERR_PTR(ret);

View File

@ -89,6 +89,7 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
ret = clk_hw_register(dev, hw);
else if (np)
ret = of_clk_hw_register(np, hw);
hw->init = NULL;
if (ret) {
kfree(fixed);
hw = ERR_PTR(ret);

Some files were not shown because too many files have changed in this diff Show More