
* 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>
6970 lines
206 KiB
Perl
Executable File
6970 lines
206 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# (c) 2001, Dave Jones. (the file handling bit)
|
|
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
|
|
# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
|
|
# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
|
|
# (c) 2010-2018 Joe Perches <joe@perches.com>
|
|
|
|
use strict;
|
|
use warnings;
|
|
use POSIX;
|
|
use File::Basename;
|
|
use Cwd 'abs_path';
|
|
use Term::ANSIColor qw(:constants);
|
|
use Encode qw(decode encode);
|
|
|
|
use constant BEFORE_SHORTTEXT => 0;
|
|
use constant IN_SHORTTEXT_BLANKLINE => 1;
|
|
use constant IN_SHORTTEXT => 2;
|
|
use constant AFTER_SHORTTEXT => 3;
|
|
use constant CHECK_NEXT_SHORTTEXT => 4;
|
|
use constant SHORTTEXT_LIMIT => 75;
|
|
|
|
my $P = $0;
|
|
my $D = dirname(abs_path($P));
|
|
|
|
my $V = '0.32';
|
|
|
|
use Getopt::Long qw(:config no_auto_abbrev);
|
|
|
|
my $quiet = 0;
|
|
my $tree = 1;
|
|
my $chk_signoff = 1;
|
|
my $chk_patch = 1;
|
|
my $tst_only;
|
|
my $emacs = 0;
|
|
my $terse = 0;
|
|
my $showfile = 0;
|
|
my $file = 0;
|
|
my $git = 0;
|
|
my %git_commits = ();
|
|
my $check = 0;
|
|
my $check_orig = 0;
|
|
my $summary = 1;
|
|
my $mailback = 0;
|
|
my $summary_file = 0;
|
|
my $show_types = 0;
|
|
my $list_types = 0;
|
|
my $fix = 0;
|
|
my $fix_inplace = 0;
|
|
my $root;
|
|
my %debug;
|
|
my %camelcase = ();
|
|
my %use_type = ();
|
|
my @use = ();
|
|
my %ignore_type = ();
|
|
my @ignore = ();
|
|
my $help = 0;
|
|
my $configuration_file = ".checkpatch.conf";
|
|
my $max_line_length = 80;
|
|
my $ignore_perl_version = 0;
|
|
my $minimum_perl_version = 5.10.0;
|
|
my $min_conf_desc_length = 4;
|
|
my $spelling_file = "$D/spelling.txt";
|
|
my $codespell = 0;
|
|
my $codespellfile = "/usr/share/codespell/dictionary.txt";
|
|
my $conststructsfile = "$D/const_structs.checkpatch";
|
|
my $typedefsfile = "";
|
|
my $color = "auto";
|
|
my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
|
|
# git output parsing needs US English output, so first set backtick child process LANGUAGE
|
|
my $git_command ='export LANGUAGE=en_US.UTF-8; git';
|
|
|
|
sub help {
|
|
my ($exitcode) = @_;
|
|
|
|
print << "EOM";
|
|
Usage: $P [OPTION]... [FILE]...
|
|
Version: $V
|
|
|
|
Options:
|
|
-q, --quiet quiet
|
|
--no-tree run without a kernel tree
|
|
--no-signoff do not check for 'Signed-off-by' line
|
|
--patch treat FILE as patchfile (default)
|
|
--emacs emacs compile window format
|
|
--terse one line per report
|
|
--showfile emit diffed file position, not input file position
|
|
-g, --git treat FILE as a single commit or git revision range
|
|
single git commit with:
|
|
<rev>
|
|
<rev>^
|
|
<rev>~n
|
|
multiple git commits with:
|
|
<rev1>..<rev2>
|
|
<rev1>...<rev2>
|
|
<rev>-<count>
|
|
git merges are ignored
|
|
-f, --file treat FILE as regular source file
|
|
--subjective, --strict enable more subjective tests
|
|
--list-types list the possible message types
|
|
--types TYPE(,TYPE2...) show only these comma separated message types
|
|
--ignore TYPE(,TYPE2...) ignore various comma separated message types
|
|
--show-types show the specific message type in the output
|
|
--max-line-length=n set the maximum line length, if exceeded, warn
|
|
--min-conf-desc-length=n set the min description length, if shorter, warn
|
|
--root=PATH PATH to the kernel tree root
|
|
--no-summary suppress the per-file summary
|
|
--mailback only produce a report in case of warnings/errors
|
|
--summary-file include the filename in summary
|
|
--debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
|
|
'values', 'possible', 'type', and 'attr' (default
|
|
is all off)
|
|
--test-only=WORD report only warnings/errors containing WORD
|
|
literally
|
|
--fix EXPERIMENTAL - may create horrible results
|
|
If correctable single-line errors exist, create
|
|
"<inputfile>.EXPERIMENTAL-checkpatch-fixes"
|
|
with potential errors corrected to the preferred
|
|
checkpatch style
|
|
--fix-inplace EXPERIMENTAL - may create horrible results
|
|
Is the same as --fix, but overwrites the input
|
|
file. It's your fault if there's no backup or git
|
|
--ignore-perl-version override checking of perl version. expect
|
|
runtime errors.
|
|
--codespell Use the codespell dictionary for spelling/typos
|
|
(default:/usr/share/codespell/dictionary.txt)
|
|
--codespellfile Use this codespell dictionary
|
|
--typedefsfile Read additional types from this file
|
|
--color[=WHEN] Use colors 'always', 'never', or only when output
|
|
is a terminal ('auto'). Default is 'auto'.
|
|
-h, --help, --version display this help and exit
|
|
|
|
When FILE is - read standard input.
|
|
EOM
|
|
|
|
exit($exitcode);
|
|
}
|
|
|
|
sub uniq {
|
|
my %seen;
|
|
return grep { !$seen{$_}++ } @_;
|
|
}
|
|
|
|
sub list_types {
|
|
my ($exitcode) = @_;
|
|
|
|
my $count = 0;
|
|
|
|
local $/ = undef;
|
|
|
|
open(my $script, '<', abs_path($P)) or
|
|
die "$P: Can't read '$P' $!\n";
|
|
|
|
my $text = <$script>;
|
|
close($script);
|
|
|
|
my @types = ();
|
|
# Also catch when type or level is passed through a variable
|
|
for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
|
|
push (@types, $_);
|
|
}
|
|
@types = sort(uniq(@types));
|
|
print("#\tMessage type\n\n");
|
|
foreach my $type (@types) {
|
|
print(++$count . "\t" . $type . "\n");
|
|
}
|
|
|
|
exit($exitcode);
|
|
}
|
|
|
|
my $conf = which_conf($configuration_file);
|
|
if (-f $conf) {
|
|
my @conf_args;
|
|
open(my $conffile, '<', "$conf")
|
|
or warn "$P: Can't find a readable $configuration_file file $!\n";
|
|
|
|
while (<$conffile>) {
|
|
my $line = $_;
|
|
|
|
$line =~ s/\s*\n?$//g;
|
|
$line =~ s/^\s*//g;
|
|
$line =~ s/\s+/ /g;
|
|
|
|
next if ($line =~ m/^\s*#/);
|
|
next if ($line =~ m/^\s*$/);
|
|
|
|
my @words = split(" ", $line);
|
|
foreach my $word (@words) {
|
|
last if ($word =~ m/^#/);
|
|
push (@conf_args, $word);
|
|
}
|
|
}
|
|
close($conffile);
|
|
unshift(@ARGV, @conf_args) if @conf_args;
|
|
}
|
|
|
|
# Perl's Getopt::Long allows options to take optional arguments after a space.
|
|
# Prevent --color by itself from consuming other arguments
|
|
foreach (@ARGV) {
|
|
if ($_ eq "--color" || $_ eq "-color") {
|
|
$_ = "--color=$color";
|
|
}
|
|
}
|
|
|
|
GetOptions(
|
|
'q|quiet+' => \$quiet,
|
|
'tree!' => \$tree,
|
|
'signoff!' => \$chk_signoff,
|
|
'patch!' => \$chk_patch,
|
|
'emacs!' => \$emacs,
|
|
'terse!' => \$terse,
|
|
'showfile!' => \$showfile,
|
|
'f|file!' => \$file,
|
|
'g|git!' => \$git,
|
|
'subjective!' => \$check,
|
|
'strict!' => \$check,
|
|
'ignore=s' => \@ignore,
|
|
'types=s' => \@use,
|
|
'show-types!' => \$show_types,
|
|
'list-types!' => \$list_types,
|
|
'max-line-length=i' => \$max_line_length,
|
|
'min-conf-desc-length=i' => \$min_conf_desc_length,
|
|
'root=s' => \$root,
|
|
'summary!' => \$summary,
|
|
'mailback!' => \$mailback,
|
|
'summary-file!' => \$summary_file,
|
|
'fix!' => \$fix,
|
|
'fix-inplace!' => \$fix_inplace,
|
|
'ignore-perl-version!' => \$ignore_perl_version,
|
|
'debug=s' => \%debug,
|
|
'test-only=s' => \$tst_only,
|
|
'codespell!' => \$codespell,
|
|
'codespellfile=s' => \$codespellfile,
|
|
'typedefsfile=s' => \$typedefsfile,
|
|
'color=s' => \$color,
|
|
'no-color' => \$color, #keep old behaviors of -nocolor
|
|
'nocolor' => \$color, #keep old behaviors of -nocolor
|
|
'h|help' => \$help,
|
|
'version' => \$help
|
|
) or help(1);
|
|
|
|
help(0) if ($help);
|
|
|
|
list_types(0) if ($list_types);
|
|
|
|
$fix = 1 if ($fix_inplace);
|
|
$check_orig = $check;
|
|
|
|
my $exit = 0;
|
|
|
|
my $perl_version_ok = 1;
|
|
if ($^V && $^V lt $minimum_perl_version) {
|
|
$perl_version_ok = 0;
|
|
printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
|
|
exit(1) if (!$ignore_perl_version);
|
|
}
|
|
|
|
#if no filenames are given, push '-' to read patch from stdin
|
|
if ($#ARGV < 0) {
|
|
push(@ARGV, '-');
|
|
}
|
|
|
|
if ($color =~ /^[01]$/) {
|
|
$color = !$color;
|
|
} elsif ($color =~ /^always$/i) {
|
|
$color = 1;
|
|
} elsif ($color =~ /^never$/i) {
|
|
$color = 0;
|
|
} elsif ($color =~ /^auto$/i) {
|
|
$color = (-t STDOUT);
|
|
} else {
|
|
die "Invalid color mode: $color\n";
|
|
}
|
|
|
|
sub hash_save_array_words {
|
|
my ($hashRef, $arrayRef) = @_;
|
|
|
|
my @array = split(/,/, join(',', @$arrayRef));
|
|
foreach my $word (@array) {
|
|
$word =~ s/\s*\n?$//g;
|
|
$word =~ s/^\s*//g;
|
|
$word =~ s/\s+/ /g;
|
|
$word =~ tr/[a-z]/[A-Z]/;
|
|
|
|
next if ($word =~ m/^\s*#/);
|
|
next if ($word =~ m/^\s*$/);
|
|
|
|
$hashRef->{$word}++;
|
|
}
|
|
}
|
|
|
|
sub hash_show_words {
|
|
my ($hashRef, $prefix) = @_;
|
|
|
|
if (keys %$hashRef) {
|
|
print "\nNOTE: $prefix message types:";
|
|
foreach my $word (sort keys %$hashRef) {
|
|
print " $word";
|
|
}
|
|
print "\n";
|
|
}
|
|
}
|
|
|
|
hash_save_array_words(\%ignore_type, \@ignore);
|
|
hash_save_array_words(\%use_type, \@use);
|
|
|
|
my $dbg_values = 0;
|
|
my $dbg_possible = 0;
|
|
my $dbg_type = 0;
|
|
my $dbg_attr = 0;
|
|
for my $key (keys %debug) {
|
|
## no critic
|
|
eval "\${dbg_$key} = '$debug{$key}';";
|
|
die "$@" if ($@);
|
|
}
|
|
|
|
my $rpt_cleaners = 0;
|
|
|
|
if ($terse) {
|
|
$emacs = 1;
|
|
$quiet++;
|
|
}
|
|
|
|
if ($tree) {
|
|
if (defined $root) {
|
|
if (!top_of_kernel_tree($root)) {
|
|
die "$P: $root: --root does not point at a valid tree\n";
|
|
}
|
|
} else {
|
|
if (top_of_kernel_tree('.')) {
|
|
$root = '.';
|
|
} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
|
|
top_of_kernel_tree($1)) {
|
|
$root = $1;
|
|
}
|
|
}
|
|
|
|
if (!defined $root) {
|
|
print "Must be run from the top-level dir. of a kernel tree\n";
|
|
exit(2);
|
|
}
|
|
}
|
|
|
|
my $emitted_corrupt = 0;
|
|
|
|
our $Ident = qr{
|
|
[A-Za-z_][A-Za-z\d_]*
|
|
(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
|
|
}x;
|
|
our $Storage = qr{extern|static|asmlinkage};
|
|
our $Sparse = qr{
|
|
__user|
|
|
__kernel|
|
|
__force|
|
|
__iomem|
|
|
__must_check|
|
|
__kprobes|
|
|
__ref|
|
|
__refconst|
|
|
__refdata|
|
|
__rcu|
|
|
__private
|
|
}x;
|
|
our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
|
|
our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
|
|
our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
|
|
our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
|
|
our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
|
|
|
|
# Notes to $Attribute:
|
|
# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
|
|
our $Attribute = qr{
|
|
const|
|
|
__percpu|
|
|
__nocast|
|
|
__safe|
|
|
__bitwise|
|
|
__packed__|
|
|
__packed2__|
|
|
__naked|
|
|
__maybe_unused|
|
|
__always_unused|
|
|
__noreturn|
|
|
__used|
|
|
__cold|
|
|
__pure|
|
|
__noclone|
|
|
__deprecated|
|
|
__read_mostly|
|
|
__ro_after_init|
|
|
__kprobes|
|
|
$InitAttribute|
|
|
____cacheline_aligned|
|
|
____cacheline_aligned_in_smp|
|
|
____cacheline_internodealigned_in_smp|
|
|
__weak
|
|
}x;
|
|
our $Modifier;
|
|
our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
|
|
our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
|
|
our $Lval = qr{$Ident(?:$Member)*};
|
|
|
|
our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
|
|
our $Binary = qr{(?i)0b[01]+$Int_type?};
|
|
our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
|
|
our $Int = qr{[0-9]+$Int_type?};
|
|
our $Octal = qr{0[0-7]+$Int_type?};
|
|
our $String = qr{"[X\t]*"};
|
|
our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
|
|
our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
|
|
our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
|
|
our $Float = qr{$Float_hex|$Float_dec|$Float_int};
|
|
our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
|
|
our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
|
|
our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
|
|
our $Arithmetic = qr{\+|-|\*|\/|%};
|
|
our $Operators = qr{
|
|
<=|>=|==|!=|
|
|
=>|->|<<|>>|<|>|!|~|
|
|
&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
|
|
}x;
|
|
|
|
our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
|
|
|
|
our $BasicType;
|
|
our $NonptrType;
|
|
our $NonptrTypeMisordered;
|
|
our $NonptrTypeWithAttr;
|
|
our $Type;
|
|
our $TypeMisordered;
|
|
our $Declare;
|
|
our $DeclareMisordered;
|
|
|
|
our $NON_ASCII_UTF8 = qr{
|
|
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
|
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
|
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
|
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
|
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
|
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
|
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
|
}x;
|
|
|
|
our $UTF8 = qr{
|
|
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
|
| $NON_ASCII_UTF8
|
|
}x;
|
|
|
|
our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
|
|
our $typeOtherOSTypedefs = qr{(?x:
|
|
u_(?:char|short|int|long) | # bsd
|
|
u(?:nchar|short|int|long) # sysv
|
|
)};
|
|
our $typeKernelTypedefs = qr{(?x:
|
|
(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
|
|
atomic_t
|
|
)};
|
|
our $typeTypedefs = qr{(?x:
|
|
$typeC99Typedefs\b|
|
|
$typeOtherOSTypedefs\b|
|
|
$typeKernelTypedefs\b
|
|
)};
|
|
|
|
our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
|
|
|
|
our $logFunctions = qr{(?x:
|
|
printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
|
|
(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
|
|
TP_printk|
|
|
WARN(?:_RATELIMIT|_ONCE|)|
|
|
panic|
|
|
MODULE_[A-Z_]+|
|
|
seq_vprintf|seq_printf|seq_puts
|
|
)};
|
|
|
|
our $allocFunctions = qr{(?x:
|
|
(?:(?:devm_)?
|
|
(?:kv|k|v)[czm]alloc(?:_node|_array)? |
|
|
kstrdup(?:_const)? |
|
|
kmemdup(?:_nul)?) |
|
|
(?:\w+)?alloc_skb(?:ip_align)? |
|
|
# dev_alloc_skb/netdev_alloc_skb, et al
|
|
dma_alloc_coherent
|
|
)};
|
|
|
|
our $signature_tags = qr{(?xi:
|
|
Signed-off-by:|
|
|
Co-developed-by:|
|
|
Acked-by:|
|
|
Tested-by:|
|
|
Reviewed-by:|
|
|
Reported-by:|
|
|
Suggested-by:|
|
|
To:|
|
|
Cc:
|
|
)};
|
|
|
|
our @typeListMisordered = (
|
|
qr{char\s+(?:un)?signed},
|
|
qr{int\s+(?:(?:un)?signed\s+)?short\s},
|
|
qr{int\s+short(?:\s+(?:un)?signed)},
|
|
qr{short\s+int(?:\s+(?:un)?signed)},
|
|
qr{(?:un)?signed\s+int\s+short},
|
|
qr{short\s+(?:un)?signed},
|
|
qr{long\s+int\s+(?:un)?signed},
|
|
qr{int\s+long\s+(?:un)?signed},
|
|
qr{long\s+(?:un)?signed\s+int},
|
|
qr{int\s+(?:un)?signed\s+long},
|
|
qr{int\s+(?:un)?signed},
|
|
qr{int\s+long\s+long\s+(?:un)?signed},
|
|
qr{long\s+long\s+int\s+(?:un)?signed},
|
|
qr{long\s+long\s+(?:un)?signed\s+int},
|
|
qr{long\s+long\s+(?:un)?signed},
|
|
qr{long\s+(?:un)?signed},
|
|
);
|
|
|
|
our @typeList = (
|
|
qr{void},
|
|
qr{(?:(?:un)?signed\s+)?char},
|
|
qr{(?:(?:un)?signed\s+)?short\s+int},
|
|
qr{(?:(?:un)?signed\s+)?short},
|
|
qr{(?:(?:un)?signed\s+)?int},
|
|
qr{(?:(?:un)?signed\s+)?long\s+int},
|
|
qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
|
|
qr{(?:(?:un)?signed\s+)?long\s+long},
|
|
qr{(?:(?:un)?signed\s+)?long},
|
|
qr{(?:un)?signed},
|
|
qr{float},
|
|
qr{double},
|
|
qr{bool},
|
|
qr{struct\s+$Ident},
|
|
qr{union\s+$Ident},
|
|
qr{enum\s+$Ident},
|
|
qr{${Ident}_t},
|
|
qr{${Ident}_handler},
|
|
qr{${Ident}_handler_fn},
|
|
@typeListMisordered,
|
|
);
|
|
|
|
our $C90_int_types = qr{(?x:
|
|
long\s+long\s+int\s+(?:un)?signed|
|
|
long\s+long\s+(?:un)?signed\s+int|
|
|
long\s+long\s+(?:un)?signed|
|
|
(?:(?:un)?signed\s+)?long\s+long\s+int|
|
|
(?:(?:un)?signed\s+)?long\s+long|
|
|
int\s+long\s+long\s+(?:un)?signed|
|
|
int\s+(?:(?:un)?signed\s+)?long\s+long|
|
|
|
|
long\s+int\s+(?:un)?signed|
|
|
long\s+(?:un)?signed\s+int|
|
|
long\s+(?:un)?signed|
|
|
(?:(?:un)?signed\s+)?long\s+int|
|
|
(?:(?:un)?signed\s+)?long|
|
|
int\s+long\s+(?:un)?signed|
|
|
int\s+(?:(?:un)?signed\s+)?long|
|
|
|
|
int\s+(?:un)?signed|
|
|
(?:(?:un)?signed\s+)?int
|
|
)};
|
|
|
|
our @typeListFile = ();
|
|
our @typeListWithAttr = (
|
|
@typeList,
|
|
qr{struct\s+$InitAttribute\s+$Ident},
|
|
qr{union\s+$InitAttribute\s+$Ident},
|
|
);
|
|
|
|
our @modifierList = (
|
|
qr{fastcall},
|
|
);
|
|
our @modifierListFile = ();
|
|
|
|
our @mode_permission_funcs = (
|
|
["module_param", 3],
|
|
["module_param_(?:array|named|string)", 4],
|
|
["module_param_array_named", 5],
|
|
["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
|
|
["proc_create(?:_data|)", 2],
|
|
["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
|
|
["IIO_DEV_ATTR_[A-Z_]+", 1],
|
|
["SENSOR_(?:DEVICE_|)ATTR_2", 2],
|
|
["SENSOR_TEMPLATE(?:_2|)", 3],
|
|
["__ATTR", 2],
|
|
);
|
|
|
|
#Create a search pattern for all these functions to speed up a loop below
|
|
our $mode_perms_search = "";
|
|
foreach my $entry (@mode_permission_funcs) {
|
|
$mode_perms_search .= '|' if ($mode_perms_search ne "");
|
|
$mode_perms_search .= $entry->[0];
|
|
}
|
|
$mode_perms_search = "(?:${mode_perms_search})";
|
|
|
|
our %deprecated_apis = (
|
|
"synchronize_rcu_bh" => "synchronize_rcu",
|
|
"synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
|
|
"call_rcu_bh" => "call_rcu",
|
|
"rcu_barrier_bh" => "rcu_barrier",
|
|
"synchronize_sched" => "synchronize_rcu",
|
|
"synchronize_sched_expedited" => "synchronize_rcu_expedited",
|
|
"call_rcu_sched" => "call_rcu",
|
|
"rcu_barrier_sched" => "rcu_barrier",
|
|
"get_state_synchronize_sched" => "get_state_synchronize_rcu",
|
|
"cond_synchronize_sched" => "cond_synchronize_rcu",
|
|
);
|
|
|
|
#Create a search pattern for all these strings to speed up a loop below
|
|
our $deprecated_apis_search = "";
|
|
foreach my $entry (keys %deprecated_apis) {
|
|
$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
|
|
$deprecated_apis_search .= $entry;
|
|
}
|
|
$deprecated_apis_search = "(?:${deprecated_apis_search})";
|
|
|
|
our $mode_perms_world_writable = qr{
|
|
S_IWUGO |
|
|
S_IWOTH |
|
|
S_IRWXUGO |
|
|
S_IALLUGO |
|
|
0[0-7][0-7][2367]
|
|
}x;
|
|
|
|
our %mode_permission_string_types = (
|
|
"S_IRWXU" => 0700,
|
|
"S_IRUSR" => 0400,
|
|
"S_IWUSR" => 0200,
|
|
"S_IXUSR" => 0100,
|
|
"S_IRWXG" => 0070,
|
|
"S_IRGRP" => 0040,
|
|
"S_IWGRP" => 0020,
|
|
"S_IXGRP" => 0010,
|
|
"S_IRWXO" => 0007,
|
|
"S_IROTH" => 0004,
|
|
"S_IWOTH" => 0002,
|
|
"S_IXOTH" => 0001,
|
|
"S_IRWXUGO" => 0777,
|
|
"S_IRUGO" => 0444,
|
|
"S_IWUGO" => 0222,
|
|
"S_IXUGO" => 0111,
|
|
);
|
|
|
|
#Create a search pattern for all these strings to speed up a loop below
|
|
our $mode_perms_string_search = "";
|
|
foreach my $entry (keys %mode_permission_string_types) {
|
|
$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
|
|
$mode_perms_string_search .= $entry;
|
|
}
|
|
our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
|
|
our $multi_mode_perms_string_search = qr{
|
|
${single_mode_perms_string_search}
|
|
(?:\s*\|\s*${single_mode_perms_string_search})*
|
|
}x;
|
|
|
|
sub perms_to_octal {
|
|
my ($string) = @_;
|
|
|
|
return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
|
|
|
|
my $val = "";
|
|
my $oval = "";
|
|
my $to = 0;
|
|
my $curpos = 0;
|
|
my $lastpos = 0;
|
|
while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
|
|
$curpos = pos($string);
|
|
my $match = $2;
|
|
my $omatch = $1;
|
|
last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
|
|
$lastpos = $curpos;
|
|
$to |= $mode_permission_string_types{$match};
|
|
$val .= '\s*\|\s*' if ($val ne "");
|
|
$val .= $match;
|
|
$oval .= $omatch;
|
|
}
|
|
$oval =~ s/^\s*\|\s*//;
|
|
$oval =~ s/\s*\|\s*$//;
|
|
return sprintf("%04o", $to);
|
|
}
|
|
|
|
our $allowed_asm_includes = qr{(?x:
|
|
irq|
|
|
memory|
|
|
time|
|
|
reboot
|
|
)};
|
|
# memory.h: ARM has a custom one
|
|
|
|
# Load common spelling mistakes and build regular expression list.
|
|
my $misspellings;
|
|
my %spelling_fix;
|
|
|
|
if (open(my $spelling, '<', $spelling_file)) {
|
|
while (<$spelling>) {
|
|
my $line = $_;
|
|
|
|
$line =~ s/\s*\n?$//g;
|
|
$line =~ s/^\s*//g;
|
|
|
|
next if ($line =~ m/^\s*#/);
|
|
next if ($line =~ m/^\s*$/);
|
|
|
|
my ($suspect, $fix) = split(/\|\|/, $line);
|
|
|
|
$spelling_fix{$suspect} = $fix;
|
|
}
|
|
close($spelling);
|
|
} else {
|
|
warn "No typos will be found - file '$spelling_file': $!\n";
|
|
}
|
|
|
|
if ($codespell) {
|
|
if (open(my $spelling, '<', $codespellfile)) {
|
|
while (<$spelling>) {
|
|
my $line = $_;
|
|
|
|
$line =~ s/\s*\n?$//g;
|
|
$line =~ s/^\s*//g;
|
|
|
|
next if ($line =~ m/^\s*#/);
|
|
next if ($line =~ m/^\s*$/);
|
|
next if ($line =~ m/, disabled/i);
|
|
|
|
$line =~ s/,.*$//;
|
|
|
|
my ($suspect, $fix) = split(/->/, $line);
|
|
|
|
$spelling_fix{$suspect} = $fix;
|
|
}
|
|
close($spelling);
|
|
} else {
|
|
warn "No codespell typos will be found - file '$codespellfile': $!\n";
|
|
}
|
|
}
|
|
|
|
$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
|
|
|
|
sub read_words {
|
|
my ($wordsRef, $file) = @_;
|
|
|
|
if (open(my $words, '<', $file)) {
|
|
while (<$words>) {
|
|
my $line = $_;
|
|
|
|
$line =~ s/\s*\n?$//g;
|
|
$line =~ s/^\s*//g;
|
|
|
|
next if ($line =~ m/^\s*#/);
|
|
next if ($line =~ m/^\s*$/);
|
|
if ($line =~ /\s/) {
|
|
print("$file: '$line' invalid - ignored\n");
|
|
next;
|
|
}
|
|
|
|
$$wordsRef .= '|' if ($$wordsRef ne "");
|
|
$$wordsRef .= $line;
|
|
}
|
|
close($file);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
my $const_structs = "";
|
|
read_words(\$const_structs, $conststructsfile)
|
|
or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
|
|
|
|
my $typeOtherTypedefs = "";
|
|
if (length($typedefsfile)) {
|
|
read_words(\$typeOtherTypedefs, $typedefsfile)
|
|
or warn "No additional types will be considered - file '$typedefsfile': $!\n";
|
|
}
|
|
$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
|
|
|
|
sub build_types {
|
|
my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
|
|
my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
|
|
my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
|
|
my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
|
|
$Modifier = qr{(?:$Attribute|$Sparse|$mods)};
|
|
$BasicType = qr{
|
|
(?:$typeTypedefs\b)|
|
|
(?:${all}\b)
|
|
}x;
|
|
$NonptrType = qr{
|
|
(?:$Modifier\s+|const\s+)*
|
|
(?:
|
|
(?:typeof|__typeof__)\s*\([^\)]*\)|
|
|
(?:$typeTypedefs\b)|
|
|
(?:${all}\b)
|
|
)
|
|
(?:\s+$Modifier|\s+const)*
|
|
}x;
|
|
$NonptrTypeMisordered = qr{
|
|
(?:$Modifier\s+|const\s+)*
|
|
(?:
|
|
(?:${Misordered}\b)
|
|
)
|
|
(?:\s+$Modifier|\s+const)*
|
|
}x;
|
|
$NonptrTypeWithAttr = qr{
|
|
(?:$Modifier\s+|const\s+)*
|
|
(?:
|
|
(?:typeof|__typeof__)\s*\([^\)]*\)|
|
|
(?:$typeTypedefs\b)|
|
|
(?:${allWithAttr}\b)
|
|
)
|
|
(?:\s+$Modifier|\s+const)*
|
|
}x;
|
|
$Type = qr{
|
|
$NonptrType
|
|
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
|
|
(?:\s+$Inline|\s+$Modifier)*
|
|
}x;
|
|
$TypeMisordered = qr{
|
|
$NonptrTypeMisordered
|
|
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
|
|
(?:\s+$Inline|\s+$Modifier)*
|
|
}x;
|
|
$Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
|
|
$DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
|
|
}
|
|
build_types();
|
|
|
|
our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
|
|
|
|
# Using $balanced_parens, $LvalOrFunc, or $FuncArg
|
|
# requires at least perl version v5.10.0
|
|
# Any use must be runtime checked with $^V
|
|
|
|
our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
|
|
our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
|
|
our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
|
|
|
|
our $declaration_macros = qr{(?x:
|
|
(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
|
|
(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
|
|
(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
|
|
(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
|
|
)};
|
|
|
|
sub deparenthesize {
|
|
my ($string) = @_;
|
|
return "" if (!defined($string));
|
|
|
|
while ($string =~ /^\s*\(.*\)\s*$/) {
|
|
$string =~ s@^\s*\(\s*@@;
|
|
$string =~ s@\s*\)\s*$@@;
|
|
}
|
|
|
|
$string =~ s@\s+@ @g;
|
|
|
|
return $string;
|
|
}
|
|
|
|
sub seed_camelcase_file {
|
|
my ($file) = @_;
|
|
|
|
return if (!(-f $file));
|
|
|
|
local $/;
|
|
|
|
open(my $include_file, '<', "$file")
|
|
or warn "$P: Can't read '$file' $!\n";
|
|
my $text = <$include_file>;
|
|
close($include_file);
|
|
|
|
my @lines = split('\n', $text);
|
|
|
|
foreach my $line (@lines) {
|
|
next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
|
|
if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
|
|
$camelcase{$1} = 1;
|
|
} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
|
|
$camelcase{$1} = 1;
|
|
} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
|
|
$camelcase{$1} = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
our %maintained_status = ();
|
|
|
|
sub is_maintained_obsolete {
|
|
my ($filename) = @_;
|
|
|
|
return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
|
|
|
|
if (!exists($maintained_status{$filename})) {
|
|
$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
|
|
}
|
|
|
|
return $maintained_status{$filename} =~ /obsolete/i;
|
|
}
|
|
|
|
sub is_SPDX_License_valid {
|
|
my ($license) = @_;
|
|
|
|
return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
|
|
|
|
my $root_path = abs_path($root);
|
|
my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
|
|
return 0 if ($status ne "");
|
|
return 1;
|
|
}
|
|
|
|
my $camelcase_seeded = 0;
|
|
sub seed_camelcase_includes {
|
|
return if ($camelcase_seeded);
|
|
|
|
my $files;
|
|
my $camelcase_cache = "";
|
|
my @include_files = ();
|
|
|
|
$camelcase_seeded = 1;
|
|
|
|
if (-e ".git") {
|
|
my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
|
|
chomp $git_last_include_commit;
|
|
$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
|
|
} else {
|
|
my $last_mod_date = 0;
|
|
$files = `find $root/include -name "*.h"`;
|
|
@include_files = split('\n', $files);
|
|
foreach my $file (@include_files) {
|
|
my $date = POSIX::strftime("%Y%m%d%H%M",
|
|
localtime((stat $file)[9]));
|
|
$last_mod_date = $date if ($last_mod_date < $date);
|
|
}
|
|
$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
|
|
}
|
|
|
|
if ($camelcase_cache ne "" && -f $camelcase_cache) {
|
|
open(my $camelcase_file, '<', "$camelcase_cache")
|
|
or warn "$P: Can't read '$camelcase_cache' $!\n";
|
|
while (<$camelcase_file>) {
|
|
chomp;
|
|
$camelcase{$_} = 1;
|
|
}
|
|
close($camelcase_file);
|
|
|
|
return;
|
|
}
|
|
|
|
if (-e ".git") {
|
|
$files = `${git_command} ls-files "include/*.h"`;
|
|
@include_files = split('\n', $files);
|
|
}
|
|
|
|
foreach my $file (@include_files) {
|
|
seed_camelcase_file($file);
|
|
}
|
|
|
|
if ($camelcase_cache ne "") {
|
|
unlink glob ".checkpatch-camelcase.*";
|
|
open(my $camelcase_file, '>', "$camelcase_cache")
|
|
or warn "$P: Can't write '$camelcase_cache' $!\n";
|
|
foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
|
|
print $camelcase_file ("$_\n");
|
|
}
|
|
close($camelcase_file);
|
|
}
|
|
}
|
|
|
|
sub git_commit_info {
|
|
my ($commit, $id, $desc) = @_;
|
|
|
|
return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
|
|
|
|
my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
|
|
$output =~ s/^\s*//gm;
|
|
my @lines = split("\n", $output);
|
|
|
|
return ($id, $desc) if ($#lines < 0);
|
|
|
|
if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
|
|
# Maybe one day convert this block of bash into something that returns
|
|
# all matching commit ids, but it's very slow...
|
|
#
|
|
# echo "checking commits $1..."
|
|
# git rev-list --remotes | grep -i "^$1" |
|
|
# while read line ; do
|
|
# git log --format='%H %s' -1 $line |
|
|
# echo "commit $(cut -c 1-12,41-)"
|
|
# done
|
|
} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
|
|
$id = undef;
|
|
} else {
|
|
$id = substr($lines[0], 0, 12);
|
|
$desc = substr($lines[0], 41);
|
|
}
|
|
|
|
return ($id, $desc);
|
|
}
|
|
|
|
$chk_signoff = 0 if ($file);
|
|
|
|
my @rawlines = ();
|
|
my @lines = ();
|
|
my @fixed = ();
|
|
my @fixed_inserted = ();
|
|
my @fixed_deleted = ();
|
|
my $fixlinenr = -1;
|
|
|
|
# If input is git commits, extract all commits from the commit expressions.
|
|
# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
|
|
die "$P: No git repository found\n" if ($git && !-e ".git");
|
|
|
|
if ($git) {
|
|
my @commits = ();
|
|
foreach my $commit_expr (@ARGV) {
|
|
my $git_range;
|
|
if ($commit_expr =~ m/^(.*)-(\d+)$/) {
|
|
$git_range = "-$2 $1";
|
|
} elsif ($commit_expr =~ m/\.\./) {
|
|
$git_range = "$commit_expr";
|
|
} else {
|
|
$git_range = "-1 $commit_expr";
|
|
}
|
|
my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
|
|
foreach my $line (split(/\n/, $lines)) {
|
|
$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
|
|
next if (!defined($1) || !defined($2));
|
|
my $sha1 = $1;
|
|
my $subject = $2;
|
|
unshift(@commits, $sha1);
|
|
$git_commits{$sha1} = $subject;
|
|
}
|
|
}
|
|
die "$P: no git commits after extraction!\n" if (@commits == 0);
|
|
@ARGV = @commits;
|
|
}
|
|
|
|
my $vname;
|
|
$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
|
|
for my $filename (@ARGV) {
|
|
my $FILE;
|
|
if ($git) {
|
|
open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
|
|
die "$P: $filename: git format-patch failed - $!\n";
|
|
} elsif ($file) {
|
|
open($FILE, '-|', "diff -u /dev/null $filename") ||
|
|
die "$P: $filename: diff failed - $!\n";
|
|
} elsif ($filename eq '-') {
|
|
open($FILE, '<&STDIN');
|
|
} else {
|
|
open($FILE, '<', "$filename") ||
|
|
die "$P: $filename: open failed - $!\n";
|
|
}
|
|
if ($filename eq '-') {
|
|
$vname = 'Your patch';
|
|
} elsif ($git) {
|
|
$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
|
|
} else {
|
|
$vname = $filename;
|
|
}
|
|
while (<$FILE>) {
|
|
chomp;
|
|
push(@rawlines, $_);
|
|
}
|
|
close($FILE);
|
|
|
|
if ($#ARGV > 0 && $quiet == 0) {
|
|
print '-' x length($vname) . "\n";
|
|
print "$vname\n";
|
|
print '-' x length($vname) . "\n";
|
|
}
|
|
|
|
if (!process($filename)) {
|
|
$exit = 1;
|
|
}
|
|
@rawlines = ();
|
|
@lines = ();
|
|
@fixed = ();
|
|
@fixed_inserted = ();
|
|
@fixed_deleted = ();
|
|
$fixlinenr = -1;
|
|
@modifierListFile = ();
|
|
@typeListFile = ();
|
|
build_types();
|
|
}
|
|
|
|
if (!$quiet) {
|
|
hash_show_words(\%use_type, "Used");
|
|
hash_show_words(\%ignore_type, "Ignored");
|
|
|
|
if (!$perl_version_ok) {
|
|
print << "EOM"
|
|
|
|
NOTE: perl $^V is not modern enough to detect all possible issues.
|
|
An upgrade to at least perl $minimum_perl_version is suggested.
|
|
EOM
|
|
}
|
|
if ($exit) {
|
|
print << "EOM"
|
|
|
|
NOTE: If any of the errors are false positives, please report
|
|
them to the maintainer, see CHECKPATCH in MAINTAINERS.
|
|
EOM
|
|
}
|
|
}
|
|
|
|
exit($exit);
|
|
|
|
sub top_of_kernel_tree {
|
|
my ($root) = @_;
|
|
|
|
my @tree_check = (
|
|
"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
|
|
"README", "Documentation", "arch", "include", "drivers",
|
|
"fs", "init", "ipc", "kernel", "lib", "scripts",
|
|
);
|
|
|
|
foreach my $check (@tree_check) {
|
|
if (! -e $root . '/' . $check) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
sub parse_email {
|
|
my ($formatted_email) = @_;
|
|
|
|
my $name = "";
|
|
my $address = "";
|
|
my $comment = "";
|
|
|
|
if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
|
|
$name = $1;
|
|
$address = $2;
|
|
$comment = $3 if defined $3;
|
|
} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
|
|
$address = $1;
|
|
$comment = $2 if defined $2;
|
|
} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
|
|
$address = $1;
|
|
$comment = $2 if defined $2;
|
|
$formatted_email =~ s/\Q$address\E.*$//;
|
|
$name = $formatted_email;
|
|
$name = trim($name);
|
|
$name =~ s/^\"|\"$//g;
|
|
# If there's a name left after stripping spaces and
|
|
# leading quotes, and the address doesn't have both
|
|
# leading and trailing angle brackets, the address
|
|
# is invalid. ie:
|
|
# "joe smith joe@smith.com" bad
|
|
# "joe smith <joe@smith.com" bad
|
|
if ($name ne "" && $address !~ /^<[^>]+>$/) {
|
|
$name = "";
|
|
$address = "";
|
|
$comment = "";
|
|
}
|
|
}
|
|
|
|
$name = trim($name);
|
|
$name =~ s/^\"|\"$//g;
|
|
$address = trim($address);
|
|
$address =~ s/^\<|\>$//g;
|
|
|
|
if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
|
|
$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
|
|
$name = "\"$name\"";
|
|
}
|
|
|
|
return ($name, $address, $comment);
|
|
}
|
|
|
|
sub format_email {
|
|
my ($name, $address) = @_;
|
|
|
|
my $formatted_email;
|
|
|
|
$name = trim($name);
|
|
$name =~ s/^\"|\"$//g;
|
|
$address = trim($address);
|
|
|
|
if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
|
|
$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
|
|
$name = "\"$name\"";
|
|
}
|
|
|
|
if ("$name" eq "") {
|
|
$formatted_email = "$address";
|
|
} else {
|
|
$formatted_email = "$name <$address>";
|
|
}
|
|
|
|
return $formatted_email;
|
|
}
|
|
|
|
sub which {
|
|
my ($bin) = @_;
|
|
|
|
foreach my $path (split(/:/, $ENV{PATH})) {
|
|
if (-e "$path/$bin") {
|
|
return "$path/$bin";
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
sub which_conf {
|
|
my ($conf) = @_;
|
|
|
|
foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
|
|
if (-e "$path/$conf") {
|
|
return "$path/$conf";
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
sub expand_tabs {
|
|
my ($str) = @_;
|
|
|
|
my $res = '';
|
|
my $n = 0;
|
|
for my $c (split(//, $str)) {
|
|
if ($c eq "\t") {
|
|
$res .= ' ';
|
|
$n++;
|
|
for (; ($n % 8) != 0; $n++) {
|
|
$res .= ' ';
|
|
}
|
|
next;
|
|
}
|
|
$res .= $c;
|
|
$n++;
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
sub copy_spacing {
|
|
(my $res = shift) =~ tr/\t/ /c;
|
|
return $res;
|
|
}
|
|
|
|
sub line_stats {
|
|
my ($line) = @_;
|
|
|
|
# Drop the diff line leader and expand tabs
|
|
$line =~ s/^.//;
|
|
$line = expand_tabs($line);
|
|
|
|
# Pick the indent from the front of the line.
|
|
my ($white) = ($line =~ /^(\s*)/);
|
|
|
|
return (length($line), length($white));
|
|
}
|
|
|
|
my $sanitise_quote = '';
|
|
|
|
sub sanitise_line_reset {
|
|
my ($in_comment) = @_;
|
|
|
|
if ($in_comment) {
|
|
$sanitise_quote = '*/';
|
|
} else {
|
|
$sanitise_quote = '';
|
|
}
|
|
}
|
|
sub sanitise_line {
|
|
my ($line) = @_;
|
|
|
|
my $res = '';
|
|
my $l = '';
|
|
|
|
my $qlen = 0;
|
|
my $off = 0;
|
|
my $c;
|
|
|
|
# Always copy over the diff marker.
|
|
$res = substr($line, 0, 1);
|
|
|
|
for ($off = 1; $off < length($line); $off++) {
|
|
$c = substr($line, $off, 1);
|
|
|
|
# Comments we are whacking completely including the begin
|
|
# and end, all to $;.
|
|
if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
|
|
$sanitise_quote = '*/';
|
|
|
|
substr($res, $off, 2, "$;$;");
|
|
$off++;
|
|
next;
|
|
}
|
|
if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
|
|
$sanitise_quote = '';
|
|
substr($res, $off, 2, "$;$;");
|
|
$off++;
|
|
next;
|
|
}
|
|
if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
|
|
$sanitise_quote = '//';
|
|
|
|
substr($res, $off, 2, $sanitise_quote);
|
|
$off++;
|
|
next;
|
|
}
|
|
|
|
# A \ in a string means ignore the next character.
|
|
if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
|
|
$c eq "\\") {
|
|
substr($res, $off, 2, 'XX');
|
|
$off++;
|
|
next;
|
|
}
|
|
# Regular quotes.
|
|
if ($c eq "'" || $c eq '"') {
|
|
if ($sanitise_quote eq '') {
|
|
$sanitise_quote = $c;
|
|
|
|
substr($res, $off, 1, $c);
|
|
next;
|
|
} elsif ($sanitise_quote eq $c) {
|
|
$sanitise_quote = '';
|
|
}
|
|
}
|
|
|
|
#print "c<$c> SQ<$sanitise_quote>\n";
|
|
if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
|
|
substr($res, $off, 1, $;);
|
|
} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
|
|
substr($res, $off, 1, $;);
|
|
} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
|
|
substr($res, $off, 1, 'X');
|
|
} else {
|
|
substr($res, $off, 1, $c);
|
|
}
|
|
}
|
|
|
|
if ($sanitise_quote eq '//') {
|
|
$sanitise_quote = '';
|
|
}
|
|
|
|
# The pathname on a #include may be surrounded by '<' and '>'.
|
|
if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
|
|
my $clean = 'X' x length($1);
|
|
$res =~ s@\<.*\>@<$clean>@;
|
|
|
|
# The whole of a #error is a string.
|
|
} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
|
|
my $clean = 'X' x length($1);
|
|
$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
|
|
}
|
|
|
|
if ($allow_c99_comments && $res =~ m@(//.*$)@) {
|
|
my $match = $1;
|
|
$res =~ s/\Q$match\E/"$;" x length($match)/e;
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
|
|
sub get_quoted_string {
|
|
my ($line, $rawline) = @_;
|
|
|
|
return "" if (!defined($line) || !defined($rawline));
|
|
return "" if ($line !~ m/($String)/g);
|
|
return substr($rawline, $-[0], $+[0] - $-[0]);
|
|
}
|
|
|
|
sub ctx_statement_block {
|
|
my ($linenr, $remain, $off) = @_;
|
|
my $line = $linenr - 1;
|
|
my $blk = '';
|
|
my $soff = $off;
|
|
my $coff = $off - 1;
|
|
my $coff_set = 0;
|
|
|
|
my $loff = 0;
|
|
|
|
my $type = '';
|
|
my $level = 0;
|
|
my @stack = ();
|
|
my $p;
|
|
my $c;
|
|
my $len = 0;
|
|
|
|
my $remainder;
|
|
while (1) {
|
|
@stack = (['', 0]) if ($#stack == -1);
|
|
|
|
#warn "CSB: blk<$blk> remain<$remain>\n";
|
|
# If we are about to drop off the end, pull in more
|
|
# context.
|
|
if ($off >= $len) {
|
|
for (; $remain > 0; $line++) {
|
|
last if (!defined $lines[$line]);
|
|
next if ($lines[$line] =~ /^-/);
|
|
$remain--;
|
|
$loff = $len;
|
|
$blk .= $lines[$line] . "\n";
|
|
$len = length($blk);
|
|
$line++;
|
|
last;
|
|
}
|
|
# Bail if there is no further context.
|
|
#warn "CSB: blk<$blk> off<$off> len<$len>\n";
|
|
if ($off >= $len) {
|
|
last;
|
|
}
|
|
if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
|
|
$level++;
|
|
$type = '#';
|
|
}
|
|
}
|
|
$p = $c;
|
|
$c = substr($blk, $off, 1);
|
|
$remainder = substr($blk, $off);
|
|
|
|
#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
|
|
|
|
# Handle nested #if/#else.
|
|
if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
|
|
push(@stack, [ $type, $level ]);
|
|
} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
|
|
($type, $level) = @{$stack[$#stack - 1]};
|
|
} elsif ($remainder =~ /^#\s*endif\b/) {
|
|
($type, $level) = @{pop(@stack)};
|
|
}
|
|
|
|
# Statement ends at the ';' or a close '}' at the
|
|
# outermost level.
|
|
if ($level == 0 && $c eq ';') {
|
|
last;
|
|
}
|
|
|
|
# An else is really a conditional as long as its not else if
|
|
if ($level == 0 && $coff_set == 0 &&
|
|
(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
|
|
$remainder =~ /^(else)(?:\s|{)/ &&
|
|
$remainder !~ /^else\s+if\b/) {
|
|
$coff = $off + length($1) - 1;
|
|
$coff_set = 1;
|
|
#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
|
|
#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
|
|
}
|
|
|
|
if (($type eq '' || $type eq '(') && $c eq '(') {
|
|
$level++;
|
|
$type = '(';
|
|
}
|
|
if ($type eq '(' && $c eq ')') {
|
|
$level--;
|
|
$type = ($level != 0)? '(' : '';
|
|
|
|
if ($level == 0 && $coff < $soff) {
|
|
$coff = $off;
|
|
$coff_set = 1;
|
|
#warn "CSB: mark coff<$coff>\n";
|
|
}
|
|
}
|
|
if (($type eq '' || $type eq '{') && $c eq '{') {
|
|
$level++;
|
|
$type = '{';
|
|
}
|
|
if ($type eq '{' && $c eq '}') {
|
|
$level--;
|
|
$type = ($level != 0)? '{' : '';
|
|
|
|
if ($level == 0) {
|
|
if (substr($blk, $off + 1, 1) eq ';') {
|
|
$off++;
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
# Preprocessor commands end at the newline unless escaped.
|
|
if ($type eq '#' && $c eq "\n" && $p ne "\\") {
|
|
$level--;
|
|
$type = '';
|
|
$off++;
|
|
last;
|
|
}
|
|
$off++;
|
|
}
|
|
# We are truly at the end, so shuffle to the next line.
|
|
if ($off == $len) {
|
|
$loff = $len + 1;
|
|
$line++;
|
|
$remain--;
|
|
}
|
|
|
|
my $statement = substr($blk, $soff, $off - $soff + 1);
|
|
my $condition = substr($blk, $soff, $coff - $soff + 1);
|
|
|
|
#warn "STATEMENT<$statement>\n";
|
|
#warn "CONDITION<$condition>\n";
|
|
|
|
#print "coff<$coff> soff<$off> loff<$loff>\n";
|
|
|
|
return ($statement, $condition,
|
|
$line, $remain + 1, $off - $loff + 1, $level);
|
|
}
|
|
|
|
sub statement_lines {
|
|
my ($stmt) = @_;
|
|
|
|
# Strip the diff line prefixes and rip blank lines at start and end.
|
|
$stmt =~ s/(^|\n)./$1/g;
|
|
$stmt =~ s/^\s*//;
|
|
$stmt =~ s/\s*$//;
|
|
|
|
my @stmt_lines = ($stmt =~ /\n/g);
|
|
|
|
return $#stmt_lines + 2;
|
|
}
|
|
|
|
sub statement_rawlines {
|
|
my ($stmt) = @_;
|
|
|
|
my @stmt_lines = ($stmt =~ /\n/g);
|
|
|
|
return $#stmt_lines + 2;
|
|
}
|
|
|
|
sub statement_block_size {
|
|
my ($stmt) = @_;
|
|
|
|
$stmt =~ s/(^|\n)./$1/g;
|
|
$stmt =~ s/^\s*{//;
|
|
$stmt =~ s/}\s*$//;
|
|
$stmt =~ s/^\s*//;
|
|
$stmt =~ s/\s*$//;
|
|
|
|
my @stmt_lines = ($stmt =~ /\n/g);
|
|
my @stmt_statements = ($stmt =~ /;/g);
|
|
|
|
my $stmt_lines = $#stmt_lines + 2;
|
|
my $stmt_statements = $#stmt_statements + 1;
|
|
|
|
if ($stmt_lines > $stmt_statements) {
|
|
return $stmt_lines;
|
|
} else {
|
|
return $stmt_statements;
|
|
}
|
|
}
|
|
|
|
sub ctx_statement_full {
|
|
my ($linenr, $remain, $off) = @_;
|
|
my ($statement, $condition, $level);
|
|
|
|
my (@chunks);
|
|
|
|
# Grab the first conditional/block pair.
|
|
($statement, $condition, $linenr, $remain, $off, $level) =
|
|
ctx_statement_block($linenr, $remain, $off);
|
|
#print "F: c<$condition> s<$statement> remain<$remain>\n";
|
|
push(@chunks, [ $condition, $statement ]);
|
|
if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
|
|
return ($level, $linenr, @chunks);
|
|
}
|
|
|
|
# Pull in the following conditional/block pairs and see if they
|
|
# could continue the statement.
|
|
for (;;) {
|
|
($statement, $condition, $linenr, $remain, $off, $level) =
|
|
ctx_statement_block($linenr, $remain, $off);
|
|
#print "C: c<$condition> s<$statement> remain<$remain>\n";
|
|
last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
|
|
#print "C: push\n";
|
|
push(@chunks, [ $condition, $statement ]);
|
|
}
|
|
|
|
return ($level, $linenr, @chunks);
|
|
}
|
|
|
|
sub ctx_block_get {
|
|
my ($linenr, $remain, $outer, $open, $close, $off) = @_;
|
|
my $line;
|
|
my $start = $linenr - 1;
|
|
my $blk = '';
|
|
my @o;
|
|
my @c;
|
|
my @res = ();
|
|
|
|
my $level = 0;
|
|
my @stack = ($level);
|
|
for ($line = $start; $remain > 0; $line++) {
|
|
next if ($rawlines[$line] =~ /^-/);
|
|
$remain--;
|
|
|
|
$blk .= $rawlines[$line];
|
|
|
|
# Handle nested #if/#else.
|
|
if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
|
|
push(@stack, $level);
|
|
} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
|
|
$level = $stack[$#stack - 1];
|
|
} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
|
|
$level = pop(@stack);
|
|
}
|
|
|
|
foreach my $c (split(//, $lines[$line])) {
|
|
##print "C<$c>L<$level><$open$close>O<$off>\n";
|
|
if ($off > 0) {
|
|
$off--;
|
|
next;
|
|
}
|
|
|
|
if ($c eq $close && $level > 0) {
|
|
$level--;
|
|
last if ($level == 0);
|
|
} elsif ($c eq $open) {
|
|
$level++;
|
|
}
|
|
}
|
|
|
|
if (!$outer || $level <= 1) {
|
|
push(@res, $rawlines[$line]);
|
|
}
|
|
|
|
last if ($level == 0);
|
|
}
|
|
|
|
return ($level, @res);
|
|
}
|
|
sub ctx_block_outer {
|
|
my ($linenr, $remain) = @_;
|
|
|
|
my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
|
|
return @r;
|
|
}
|
|
sub ctx_block {
|
|
my ($linenr, $remain) = @_;
|
|
|
|
my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
|
|
return @r;
|
|
}
|
|
sub ctx_statement {
|
|
my ($linenr, $remain, $off) = @_;
|
|
|
|
my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
|
|
return @r;
|
|
}
|
|
sub ctx_block_level {
|
|
my ($linenr, $remain) = @_;
|
|
|
|
return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
|
|
}
|
|
sub ctx_statement_level {
|
|
my ($linenr, $remain, $off) = @_;
|
|
|
|
return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
|
|
}
|
|
|
|
sub ctx_locate_comment {
|
|
my ($first_line, $end_line) = @_;
|
|
|
|
# Catch a comment on the end of the line itself.
|
|
my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
|
|
return $current_comment if (defined $current_comment);
|
|
|
|
# Look through the context and try and figure out if there is a
|
|
# comment.
|
|
my $in_comment = 0;
|
|
$current_comment = '';
|
|
for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
|
|
my $line = $rawlines[$linenr - 1];
|
|
#warn " $line\n";
|
|
if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
|
|
$in_comment = 1;
|
|
}
|
|
if ($line =~ m@/\*@) {
|
|
$in_comment = 1;
|
|
}
|
|
if (!$in_comment && $current_comment ne '') {
|
|
$current_comment = '';
|
|
}
|
|
$current_comment .= $line . "\n" if ($in_comment);
|
|
if ($line =~ m@\*/@) {
|
|
$in_comment = 0;
|
|
}
|
|
}
|
|
|
|
chomp($current_comment);
|
|
return($current_comment);
|
|
}
|
|
sub ctx_has_comment {
|
|
my ($first_line, $end_line) = @_;
|
|
my $cmt = ctx_locate_comment($first_line, $end_line);
|
|
|
|
##print "LINE: $rawlines[$end_line - 1 ]\n";
|
|
##print "CMMT: $cmt\n";
|
|
|
|
return ($cmt ne '');
|
|
}
|
|
|
|
sub raw_line {
|
|
my ($linenr, $cnt) = @_;
|
|
|
|
my $offset = $linenr - 1;
|
|
$cnt++;
|
|
|
|
my $line;
|
|
while ($cnt) {
|
|
$line = $rawlines[$offset++];
|
|
next if (defined($line) && $line =~ /^-/);
|
|
$cnt--;
|
|
}
|
|
|
|
return $line;
|
|
}
|
|
|
|
sub get_stat_real {
|
|
my ($linenr, $lc) = @_;
|
|
|
|
my $stat_real = raw_line($linenr, 0);
|
|
for (my $count = $linenr + 1; $count <= $lc; $count++) {
|
|
$stat_real = $stat_real . "\n" . raw_line($count, 0);
|
|
}
|
|
|
|
return $stat_real;
|
|
}
|
|
|
|
sub get_stat_here {
|
|
my ($linenr, $cnt, $here) = @_;
|
|
|
|
my $herectx = $here . "\n";
|
|
for (my $n = 0; $n < $cnt; $n++) {
|
|
$herectx .= raw_line($linenr, $n) . "\n";
|
|
}
|
|
|
|
return $herectx;
|
|
}
|
|
|
|
sub cat_vet {
|
|
my ($vet) = @_;
|
|
my ($res, $coded);
|
|
|
|
$res = '';
|
|
while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
|
|
$res .= $1;
|
|
if ($2 ne '') {
|
|
$coded = sprintf("^%c", unpack('C', $2) + 64);
|
|
$res .= $coded;
|
|
}
|
|
}
|
|
$res =~ s/$/\$/;
|
|
|
|
return $res;
|
|
}
|
|
|
|
my $av_preprocessor = 0;
|
|
my $av_pending;
|
|
my @av_paren_type;
|
|
my $av_pend_colon;
|
|
|
|
sub annotate_reset {
|
|
$av_preprocessor = 0;
|
|
$av_pending = '_';
|
|
@av_paren_type = ('E');
|
|
$av_pend_colon = 'O';
|
|
}
|
|
|
|
sub annotate_values {
|
|
my ($stream, $type) = @_;
|
|
|
|
my $res;
|
|
my $var = '_' x length($stream);
|
|
my $cur = $stream;
|
|
|
|
print "$stream\n" if ($dbg_values > 1);
|
|
|
|
while (length($cur)) {
|
|
@av_paren_type = ('E') if ($#av_paren_type < 0);
|
|
print " <" . join('', @av_paren_type) .
|
|
"> <$type> <$av_pending>" if ($dbg_values > 1);
|
|
if ($cur =~ /^(\s+)/o) {
|
|
print "WS($1)\n" if ($dbg_values > 1);
|
|
if ($1 =~ /\n/ && $av_preprocessor) {
|
|
$type = pop(@av_paren_type);
|
|
$av_preprocessor = 0;
|
|
}
|
|
|
|
} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
|
|
print "CAST($1)\n" if ($dbg_values > 1);
|
|
push(@av_paren_type, $type);
|
|
$type = 'c';
|
|
|
|
} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
|
|
print "DECLARE($1)\n" if ($dbg_values > 1);
|
|
$type = 'T';
|
|
|
|
} elsif ($cur =~ /^($Modifier)\s*/) {
|
|
print "MODIFIER($1)\n" if ($dbg_values > 1);
|
|
$type = 'T';
|
|
|
|
} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
|
|
print "DEFINE($1,$2)\n" if ($dbg_values > 1);
|
|
$av_preprocessor = 1;
|
|
push(@av_paren_type, $type);
|
|
if ($2 ne '') {
|
|
$av_pending = 'N';
|
|
}
|
|
$type = 'E';
|
|
|
|
} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
|
|
print "UNDEF($1)\n" if ($dbg_values > 1);
|
|
$av_preprocessor = 1;
|
|
push(@av_paren_type, $type);
|
|
|
|
} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
|
|
print "PRE_START($1)\n" if ($dbg_values > 1);
|
|
$av_preprocessor = 1;
|
|
|
|
push(@av_paren_type, $type);
|
|
push(@av_paren_type, $type);
|
|
$type = 'E';
|
|
|
|
} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
|
|
print "PRE_RESTART($1)\n" if ($dbg_values > 1);
|
|
$av_preprocessor = 1;
|
|
|
|
push(@av_paren_type, $av_paren_type[$#av_paren_type]);
|
|
|
|
$type = 'E';
|
|
|
|
} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
|
|
print "PRE_END($1)\n" if ($dbg_values > 1);
|
|
|
|
$av_preprocessor = 1;
|
|
|
|
# Assume all arms of the conditional end as this
|
|
# one does, and continue as if the #endif was not here.
|
|
pop(@av_paren_type);
|
|
push(@av_paren_type, $type);
|
|
$type = 'E';
|
|
|
|
} elsif ($cur =~ /^(\\\n)/o) {
|
|
print "PRECONT($1)\n" if ($dbg_values > 1);
|
|
|
|
} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
|
|
print "ATTR($1)\n" if ($dbg_values > 1);
|
|
$av_pending = $type;
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
|
|
print "SIZEOF($1)\n" if ($dbg_values > 1);
|
|
if (defined $2) {
|
|
$av_pending = 'V';
|
|
}
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(if|while|for)\b/o) {
|
|
print "COND($1)\n" if ($dbg_values > 1);
|
|
$av_pending = 'E';
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~/^(case)/o) {
|
|
print "CASE($1)\n" if ($dbg_values > 1);
|
|
$av_pend_colon = 'C';
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
|
|
print "KEYWORD($1)\n" if ($dbg_values > 1);
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(\()/o) {
|
|
print "PAREN('$1')\n" if ($dbg_values > 1);
|
|
push(@av_paren_type, $av_pending);
|
|
$av_pending = '_';
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(\))/o) {
|
|
my $new_type = pop(@av_paren_type);
|
|
if ($new_type ne '_') {
|
|
$type = $new_type;
|
|
print "PAREN('$1') -> $type\n"
|
|
if ($dbg_values > 1);
|
|
} else {
|
|
print "PAREN('$1')\n" if ($dbg_values > 1);
|
|
}
|
|
|
|
} elsif ($cur =~ /^($Ident)\s*\(/o) {
|
|
print "FUNC($1)\n" if ($dbg_values > 1);
|
|
$type = 'V';
|
|
$av_pending = 'V';
|
|
|
|
} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
|
|
if (defined $2 && $type eq 'C' || $type eq 'T') {
|
|
$av_pend_colon = 'B';
|
|
} elsif ($type eq 'E') {
|
|
$av_pend_colon = 'L';
|
|
}
|
|
print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
|
|
$type = 'V';
|
|
|
|
} elsif ($cur =~ /^($Ident|$Constant)/o) {
|
|
print "IDENT($1)\n" if ($dbg_values > 1);
|
|
$type = 'V';
|
|
|
|
} elsif ($cur =~ /^($Assignment)/o) {
|
|
print "ASSIGN($1)\n" if ($dbg_values > 1);
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~/^(;|{|})/) {
|
|
print "END($1)\n" if ($dbg_values > 1);
|
|
$type = 'E';
|
|
$av_pend_colon = 'O';
|
|
|
|
} elsif ($cur =~/^(,)/) {
|
|
print "COMMA($1)\n" if ($dbg_values > 1);
|
|
$type = 'C';
|
|
|
|
} elsif ($cur =~ /^(\?)/o) {
|
|
print "QUESTION($1)\n" if ($dbg_values > 1);
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(:)/o) {
|
|
print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
|
|
|
|
substr($var, length($res), 1, $av_pend_colon);
|
|
if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
|
|
$type = 'E';
|
|
} else {
|
|
$type = 'N';
|
|
}
|
|
$av_pend_colon = 'O';
|
|
|
|
} elsif ($cur =~ /^(\[)/o) {
|
|
print "CLOSE($1)\n" if ($dbg_values > 1);
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
|
|
my $variant;
|
|
|
|
print "OPV($1)\n" if ($dbg_values > 1);
|
|
if ($type eq 'V') {
|
|
$variant = 'B';
|
|
} else {
|
|
$variant = 'U';
|
|
}
|
|
|
|
substr($var, length($res), 1, $variant);
|
|
$type = 'N';
|
|
|
|
} elsif ($cur =~ /^($Operators)/o) {
|
|
print "OP($1)\n" if ($dbg_values > 1);
|
|
if ($1 ne '++' && $1 ne '--') {
|
|
$type = 'N';
|
|
}
|
|
|
|
} elsif ($cur =~ /(^.)/o) {
|
|
print "C($1)\n" if ($dbg_values > 1);
|
|
}
|
|
if (defined $1) {
|
|
$cur = substr($cur, length($1));
|
|
$res .= $type x length($1);
|
|
}
|
|
}
|
|
|
|
return ($res, $var);
|
|
}
|
|
|
|
sub possible {
|
|
my ($possible, $line) = @_;
|
|
my $notPermitted = qr{(?:
|
|
^(?:
|
|
$Modifier|
|
|
$Storage|
|
|
$Type|
|
|
DEFINE_\S+
|
|
)$|
|
|
^(?:
|
|
goto|
|
|
return|
|
|
case|
|
|
else|
|
|
asm|__asm__|
|
|
do|
|
|
\#|
|
|
\#\#|
|
|
)(?:\s|$)|
|
|
^(?:typedef|struct|enum)\b
|
|
)}x;
|
|
warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
|
|
if ($possible !~ $notPermitted) {
|
|
# Check for modifiers.
|
|
$possible =~ s/\s*$Storage\s*//g;
|
|
$possible =~ s/\s*$Sparse\s*//g;
|
|
if ($possible =~ /^\s*$/) {
|
|
|
|
} elsif ($possible =~ /\s/) {
|
|
$possible =~ s/\s*$Type\s*//g;
|
|
for my $modifier (split(' ', $possible)) {
|
|
if ($modifier !~ $notPermitted) {
|
|
warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
|
|
push(@modifierListFile, $modifier);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
|
|
push(@typeListFile, $possible);
|
|
}
|
|
build_types();
|
|
} else {
|
|
warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
|
|
}
|
|
}
|
|
|
|
my $prefix = '';
|
|
|
|
sub show_type {
|
|
my ($type) = @_;
|
|
|
|
$type =~ tr/[a-z]/[A-Z]/;
|
|
|
|
return defined $use_type{$type} if (scalar keys %use_type > 0);
|
|
|
|
return !defined $ignore_type{$type};
|
|
}
|
|
|
|
sub report {
|
|
my ($level, $type, $msg) = @_;
|
|
|
|
if (!show_type($type) ||
|
|
(defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
|
|
return 0;
|
|
}
|
|
my $output = '';
|
|
if ($color) {
|
|
if ($level eq 'ERROR') {
|
|
$output .= RED;
|
|
} elsif ($level eq 'WARNING') {
|
|
$output .= YELLOW;
|
|
} else {
|
|
$output .= GREEN;
|
|
}
|
|
}
|
|
$output .= $prefix . $level . ':';
|
|
if ($show_types) {
|
|
$output .= BLUE if ($color);
|
|
$output .= "$type:";
|
|
}
|
|
$output .= RESET if ($color);
|
|
$output .= ' ' . $msg . "\n";
|
|
|
|
if ($showfile) {
|
|
my @lines = split("\n", $output, -1);
|
|
splice(@lines, 1, 1);
|
|
$output = join("\n", @lines);
|
|
}
|
|
$output = (split('\n', $output))[0] . "\n" if ($terse);
|
|
|
|
push(our @report, $output);
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub report_dump {
|
|
our @report;
|
|
}
|
|
|
|
sub fixup_current_range {
|
|
my ($lineRef, $offset, $length) = @_;
|
|
|
|
if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
|
|
my $o = $1;
|
|
my $l = $2;
|
|
my $no = $o + $offset;
|
|
my $nl = $l + $length;
|
|
$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
|
|
}
|
|
}
|
|
|
|
sub fix_inserted_deleted_lines {
|
|
my ($linesRef, $insertedRef, $deletedRef) = @_;
|
|
|
|
my $range_last_linenr = 0;
|
|
my $delta_offset = 0;
|
|
|
|
my $old_linenr = 0;
|
|
my $new_linenr = 0;
|
|
|
|
my $next_insert = 0;
|
|
my $next_delete = 0;
|
|
|
|
my @lines = ();
|
|
|
|
my $inserted = @{$insertedRef}[$next_insert++];
|
|
my $deleted = @{$deletedRef}[$next_delete++];
|
|
|
|
foreach my $old_line (@{$linesRef}) {
|
|
my $save_line = 1;
|
|
my $line = $old_line; #don't modify the array
|
|
if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
|
|
$delta_offset = 0;
|
|
} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
|
|
$range_last_linenr = $new_linenr;
|
|
fixup_current_range(\$line, $delta_offset, 0);
|
|
}
|
|
|
|
while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
|
|
$deleted = @{$deletedRef}[$next_delete++];
|
|
$save_line = 0;
|
|
fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
|
|
}
|
|
|
|
while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
|
|
push(@lines, ${$inserted}{'LINE'});
|
|
$inserted = @{$insertedRef}[$next_insert++];
|
|
$new_linenr++;
|
|
fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
|
|
}
|
|
|
|
if ($save_line) {
|
|
push(@lines, $line);
|
|
$new_linenr++;
|
|
}
|
|
|
|
$old_linenr++;
|
|
}
|
|
|
|
return @lines;
|
|
}
|
|
|
|
sub fix_insert_line {
|
|
my ($linenr, $line) = @_;
|
|
|
|
my $inserted = {
|
|
LINENR => $linenr,
|
|
LINE => $line,
|
|
};
|
|
push(@fixed_inserted, $inserted);
|
|
}
|
|
|
|
sub fix_delete_line {
|
|
my ($linenr, $line) = @_;
|
|
|
|
my $deleted = {
|
|
LINENR => $linenr,
|
|
LINE => $line,
|
|
};
|
|
|
|
push(@fixed_deleted, $deleted);
|
|
}
|
|
|
|
sub ERROR {
|
|
my ($type, $msg) = @_;
|
|
|
|
if (report("ERROR", $type, $msg)) {
|
|
our $clean = 0;
|
|
our $cnt_error++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
sub WARN {
|
|
my ($type, $msg) = @_;
|
|
|
|
if (report("WARNING", $type, $msg)) {
|
|
our $clean = 0;
|
|
our $cnt_warn++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
sub CHK {
|
|
my ($type, $msg) = @_;
|
|
|
|
if ($check && report("CHECK", $type, $msg)) {
|
|
our $clean = 0;
|
|
our $cnt_chk++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub check_absolute_file {
|
|
my ($absolute, $herecurr) = @_;
|
|
my $file = $absolute;
|
|
|
|
##print "absolute<$absolute>\n";
|
|
|
|
# See if any suffix of this path is a path within the tree.
|
|
while ($file =~ s@^[^/]*/@@) {
|
|
if (-f "$root/$file") {
|
|
##print "file<$file>\n";
|
|
last;
|
|
}
|
|
}
|
|
if (! -f _) {
|
|
return 0;
|
|
}
|
|
|
|
# It is, so see if the prefix is acceptable.
|
|
my $prefix = $absolute;
|
|
substr($prefix, -length($file)) = '';
|
|
|
|
##print "prefix<$prefix>\n";
|
|
if ($prefix ne ".../") {
|
|
WARN("USE_RELATIVE_PATH",
|
|
"use relative pathname instead of absolute in changelog text\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
sub trim {
|
|
my ($string) = @_;
|
|
|
|
$string =~ s/^\s+|\s+$//g;
|
|
|
|
return $string;
|
|
}
|
|
|
|
sub ltrim {
|
|
my ($string) = @_;
|
|
|
|
$string =~ s/^\s+//;
|
|
|
|
return $string;
|
|
}
|
|
|
|
sub rtrim {
|
|
my ($string) = @_;
|
|
|
|
$string =~ s/\s+$//;
|
|
|
|
return $string;
|
|
}
|
|
|
|
sub string_find_replace {
|
|
my ($string, $find, $replace) = @_;
|
|
|
|
$string =~ s/$find/$replace/g;
|
|
|
|
return $string;
|
|
}
|
|
|
|
sub tabify {
|
|
my ($leading) = @_;
|
|
|
|
my $source_indent = 8;
|
|
my $max_spaces_before_tab = $source_indent - 1;
|
|
my $spaces_to_tab = " " x $source_indent;
|
|
|
|
#convert leading spaces to tabs
|
|
1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
|
|
#Remove spaces before a tab
|
|
1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
|
|
|
|
return "$leading";
|
|
}
|
|
|
|
sub cleanup_continuation_headers {
|
|
# Collapse any header-continuation lines into a single line so they
|
|
# can be parsed meaningfully, as the parser only has one line
|
|
# of context to work with.
|
|
my $again;
|
|
do {
|
|
$again = 0;
|
|
foreach my $n (0 .. scalar(@rawlines) - 2) {
|
|
if ($rawlines[$n]=~/^\s*$/) {
|
|
# A blank line means there's no more chance
|
|
# of finding headers. Shortcut to done.
|
|
return;
|
|
}
|
|
if ($rawlines[$n]=~/^[\x21-\x39\x3b-\x7e]+:/ &&
|
|
$rawlines[$n+1]=~/^\s+/) {
|
|
# Continuation header. Collapse it.
|
|
my $line = splice @rawlines, $n+1, 1;
|
|
$line=~s/^\s+/ /;
|
|
$rawlines[$n] .= $line;
|
|
# We've 'destabilized' the list, so restart.
|
|
$again = 1;
|
|
last;
|
|
}
|
|
}
|
|
} while ($again);
|
|
}
|
|
|
|
sub pos_last_openparen {
|
|
my ($line) = @_;
|
|
|
|
my $pos = 0;
|
|
|
|
my $opens = $line =~ tr/\(/\(/;
|
|
my $closes = $line =~ tr/\)/\)/;
|
|
|
|
my $last_openparen = 0;
|
|
|
|
if (($opens == 0) || ($closes >= $opens)) {
|
|
return -1;
|
|
}
|
|
|
|
my $len = length($line);
|
|
|
|
for ($pos = 0; $pos < $len; $pos++) {
|
|
my $string = substr($line, $pos);
|
|
if ($string =~ /^($FuncArg|$balanced_parens)/) {
|
|
$pos += length($1) - 1;
|
|
} elsif (substr($line, $pos, 1) eq '(') {
|
|
$last_openparen = $pos;
|
|
} elsif (index($string, '(') == -1) {
|
|
last;
|
|
}
|
|
}
|
|
|
|
return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
|
|
}
|
|
|
|
sub process {
|
|
my $filename = shift;
|
|
|
|
my $linenr=0;
|
|
my $prevline="";
|
|
my $prevrawline="";
|
|
my $stashline="";
|
|
my $stashrawline="";
|
|
my $subjectline="";
|
|
my $sublinenr="";
|
|
|
|
my $length;
|
|
my $indent;
|
|
my $previndent=0;
|
|
my $stashindent=0;
|
|
|
|
our $clean = 1;
|
|
my $signoff = 0;
|
|
my $author = '';
|
|
my $authorsignoff = 0;
|
|
my $is_patch = 0;
|
|
my $is_binding_patch = -1;
|
|
my $in_header_lines = $file ? 0 : 1;
|
|
my $in_commit_log = 0; #Scanning lines before patch
|
|
my $has_commit_log = 0; #Encountered lines before patch
|
|
my $commit_log_lines = 0; #Number of commit log lines
|
|
my $commit_log_possible_stack_dump = 0;
|
|
my $commit_log_long_line = 0;
|
|
my $commit_log_has_diff = 0;
|
|
my $reported_maintainer_file = 0;
|
|
my $non_utf8_charset = 0;
|
|
|
|
my $last_blank_line = 0;
|
|
my $last_coalesced_string_linenr = -1;
|
|
|
|
our @report = ();
|
|
our $cnt_lines = 0;
|
|
our $cnt_error = 0;
|
|
our $cnt_warn = 0;
|
|
our $cnt_chk = 0;
|
|
|
|
# Trace the real file/line as we go.
|
|
my $realfile = '';
|
|
my $realline = 0;
|
|
my $realcnt = 0;
|
|
my $here = '';
|
|
my $context_function; #undef'd unless there's a known function
|
|
my $in_comment = 0;
|
|
my $comment_edge = 0;
|
|
my $first_line = 0;
|
|
my $p1_prefix = '';
|
|
|
|
my $prev_values = 'E';
|
|
|
|
# suppression flags
|
|
my %suppress_ifbraces;
|
|
my %suppress_whiletrailers;
|
|
my %suppress_export;
|
|
my $suppress_statement = 0;
|
|
|
|
my %signatures = ();
|
|
|
|
# Pre-scan the patch sanitizing the lines.
|
|
# Pre-scan the patch looking for any __setup documentation.
|
|
#
|
|
my @setup_docs = ();
|
|
my $setup_docs = 0;
|
|
|
|
my $camelcase_file_seeded = 0;
|
|
my $shorttext = BEFORE_SHORTTEXT;
|
|
my $shorttext_exspc = 0;
|
|
my $commit_text_present = 0;
|
|
|
|
my $checklicenseline = 1;
|
|
|
|
sanitise_line_reset();
|
|
cleanup_continuation_headers();
|
|
my $line;
|
|
|
|
foreach my $rawline (@rawlines) {
|
|
$linenr++;
|
|
$line = $rawline;
|
|
|
|
push(@fixed, $rawline) if ($fix);
|
|
|
|
if ($rawline=~/^\+\+\+\s+(\S+)/) {
|
|
$setup_docs = 0;
|
|
if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
|
|
$setup_docs = 1;
|
|
}
|
|
#next;
|
|
}
|
|
if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
|
|
$realline=$1-1;
|
|
if (defined $2) {
|
|
$realcnt=$3+1;
|
|
} else {
|
|
$realcnt=1+1;
|
|
}
|
|
$in_comment = 0;
|
|
|
|
# Guestimate if this is a continuing comment. Run
|
|
# the context looking for a comment "edge". If this
|
|
# edge is a close comment then we must be in a comment
|
|
# at context start.
|
|
my $edge;
|
|
my $cnt = $realcnt;
|
|
for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
|
|
next if (defined $rawlines[$ln - 1] &&
|
|
$rawlines[$ln - 1] =~ /^-/);
|
|
$cnt--;
|
|
#print "RAW<$rawlines[$ln - 1]>\n";
|
|
last if (!defined $rawlines[$ln - 1]);
|
|
if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
|
|
$rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
|
|
($edge) = $1;
|
|
last;
|
|
}
|
|
}
|
|
if (defined $edge && $edge eq '*/') {
|
|
$in_comment = 1;
|
|
}
|
|
|
|
# Guestimate if this is a continuing comment. If this
|
|
# is the start of a diff block and this line starts
|
|
# ' *' then it is very likely a comment.
|
|
if (!defined $edge &&
|
|
$rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
|
|
{
|
|
$in_comment = 1;
|
|
}
|
|
|
|
##print "COMMENT:$in_comment edge<$edge> $rawline\n";
|
|
sanitise_line_reset($in_comment);
|
|
|
|
} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
|
|
# Standardise the strings and chars within the input to
|
|
# simplify matching -- only bother with positive lines.
|
|
$line = sanitise_line($rawline);
|
|
}
|
|
push(@lines, $line);
|
|
|
|
if ($realcnt > 1) {
|
|
$realcnt-- if ($line =~ /^(?:\+| |$)/);
|
|
} else {
|
|
$realcnt = 0;
|
|
}
|
|
|
|
#print "==>$rawline\n";
|
|
#print "-->$line\n";
|
|
|
|
if ($setup_docs && $line =~ /^\+/) {
|
|
push(@setup_docs, $line);
|
|
}
|
|
}
|
|
|
|
$prefix = '';
|
|
|
|
$realcnt = 0;
|
|
$linenr = 0;
|
|
$fixlinenr = -1;
|
|
foreach my $line (@lines) {
|
|
$linenr++;
|
|
$fixlinenr++;
|
|
my $sline = $line; #copy of $line
|
|
$sline =~ s/$;/ /g; #with comments as spaces
|
|
|
|
my $rawline = $rawlines[$linenr - 1];
|
|
|
|
# check if it's a mode change, rename or start of a patch
|
|
if (!$in_commit_log &&
|
|
($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
|
|
($line =~ /^rename (?:from|to) \S+\s*$/ ||
|
|
$line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
|
|
$is_patch = 1;
|
|
}
|
|
|
|
#extract the line range in the file after the patch is applied
|
|
if (!$in_commit_log &&
|
|
$line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
|
|
my $context = $4;
|
|
$is_patch = 1;
|
|
$first_line = $linenr + 1;
|
|
$realline=$1-1;
|
|
if (defined $2) {
|
|
$realcnt=$3+1;
|
|
} else {
|
|
$realcnt=1+1;
|
|
}
|
|
annotate_reset();
|
|
$prev_values = 'E';
|
|
|
|
%suppress_ifbraces = ();
|
|
%suppress_whiletrailers = ();
|
|
%suppress_export = ();
|
|
$suppress_statement = 0;
|
|
if ($context =~ /\b(\w+)\s*\(/) {
|
|
$context_function = $1;
|
|
} else {
|
|
undef $context_function;
|
|
}
|
|
next;
|
|
|
|
# track the line number as we move through the hunk, note that
|
|
# new versions of GNU diff omit the leading space on completely
|
|
# blank context lines so we need to count that too.
|
|
} elsif ($line =~ /^( |\+|$)/) {
|
|
$realline++;
|
|
$realcnt-- if ($realcnt != 0);
|
|
|
|
# Measure the line length and indent.
|
|
($length, $indent) = line_stats($rawline);
|
|
|
|
# Track the previous line.
|
|
($prevline, $stashline) = ($stashline, $line);
|
|
($previndent, $stashindent) = ($stashindent, $indent);
|
|
($prevrawline, $stashrawline) = ($stashrawline, $rawline);
|
|
|
|
#warn "line<$line>\n";
|
|
|
|
} elsif ($realcnt == 1) {
|
|
$realcnt--;
|
|
}
|
|
|
|
my $hunk_line = ($realcnt != 0);
|
|
|
|
$here = "#$linenr: " if (!$file);
|
|
$here = "#$realline: " if ($file);
|
|
|
|
my $found_file = 0;
|
|
# extract the filename as it passes
|
|
if ($line =~ /^diff --git.*?(\S+)$/) {
|
|
$realfile = $1;
|
|
$realfile =~ s@^([^/]*)/@@ if (!$file);
|
|
$in_commit_log = 0;
|
|
$found_file = 1;
|
|
} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
|
|
$realfile = $1;
|
|
$realfile =~ s@^([^/]*)/@@ if (!$file);
|
|
$in_commit_log = 0;
|
|
|
|
$p1_prefix = $1;
|
|
if (!$file && $tree && $p1_prefix ne '' &&
|
|
-e "$root/$p1_prefix") {
|
|
WARN("PATCH_PREFIX",
|
|
"patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
|
|
}
|
|
|
|
if ($realfile =~ m@^include/asm/@) {
|
|
ERROR("MODIFIED_INCLUDE_ASM",
|
|
"do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
|
|
}
|
|
$found_file = 1;
|
|
}
|
|
|
|
#make up the handle for any error we report on this line
|
|
if ($showfile) {
|
|
$prefix = "$realfile:$realline: "
|
|
} elsif ($emacs) {
|
|
if ($file) {
|
|
$prefix = "$filename:$realline: ";
|
|
} else {
|
|
$prefix = "$filename:$linenr: ";
|
|
}
|
|
}
|
|
|
|
if ($found_file) {
|
|
if (is_maintained_obsolete($realfile)) {
|
|
WARN("OBSOLETE",
|
|
"$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
|
|
}
|
|
if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
|
|
$check = 1;
|
|
} else {
|
|
$check = $check_orig;
|
|
}
|
|
$checklicenseline = 1;
|
|
|
|
if ($realfile !~ /^MAINTAINERS/) {
|
|
my $last_binding_patch = $is_binding_patch;
|
|
|
|
$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
|
|
|
|
if (($last_binding_patch != -1) &&
|
|
($last_binding_patch ^ $is_binding_patch)) {
|
|
WARN("DT_SPLIT_BINDING_PATCH",
|
|
"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
|
|
}
|
|
}
|
|
|
|
next;
|
|
}
|
|
$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
|
|
|
|
my $hereline = "$here\n$rawline\n";
|
|
my $herecurr = "$here\n$rawline\n";
|
|
my $hereprev = "$here\n$prevrawline\n$rawline\n";
|
|
|
|
if ($shorttext != AFTER_SHORTTEXT) {
|
|
if ($shorttext == IN_SHORTTEXT_BLANKLINE && $line=~/\S/) {
|
|
# the subject line was just processed,
|
|
# a blank line must be next
|
|
WARN("NONBLANK_AFTER_SUMMARY",
|
|
"non-blank line after summary line\n" . $herecurr);
|
|
$shorttext = IN_SHORTTEXT;
|
|
# this non-blank line may or may not be commit text -
|
|
# a warning has been generated so assume it is commit
|
|
# text and move on
|
|
$commit_text_present = 1;
|
|
# fall through and treat this line as IN_SHORTTEXT
|
|
}
|
|
if ($shorttext == IN_SHORTTEXT) {
|
|
if ($line=~/^---/ || $line=~/^diff.*/) {
|
|
if ($commit_text_present == 0) {
|
|
WARN("NO_COMMIT_TEXT",
|
|
"please add commit text explaining " .
|
|
"*why* the change is needed\n" .
|
|
$herecurr);
|
|
}
|
|
$shorttext = AFTER_SHORTTEXT;
|
|
} elsif ($line=~/^\s*change-id:/i ||
|
|
$line=~/^\s*signed-off-by:/i ||
|
|
$line=~/^\s*crs-fixed:/i ||
|
|
$line=~/^\s*acked-by:/i) {
|
|
# this is a tag, there must be commit
|
|
# text by now
|
|
if ($commit_text_present == 0) {
|
|
WARN("NO_COMMIT_TEXT",
|
|
"please add commit text explaining " .
|
|
"*why* the change is needed\n" .
|
|
$herecurr);
|
|
# prevent duplicate warnings
|
|
$commit_text_present = 1;
|
|
}
|
|
} elsif ($line=~/\S/) {
|
|
$commit_text_present = 1;
|
|
}
|
|
} elsif ($shorttext == IN_SHORTTEXT_BLANKLINE) {
|
|
# case of non-blank line in this state handled above
|
|
$shorttext = IN_SHORTTEXT;
|
|
} elsif ($shorttext == CHECK_NEXT_SHORTTEXT) {
|
|
# The Subject line doesn't have to be the last header in the patch.
|
|
# Avoid moving to the IN_SHORTTEXT state until clear of all headers.
|
|
# Per RFC5322, continuation lines must be folded, so any left-justified
|
|
# text which looks like a header is definitely a header.
|
|
if ($line!~/^[\x21-\x39\x3b-\x7e]+:/) {
|
|
$shorttext = IN_SHORTTEXT;
|
|
# Check for Subject line followed by a blank line.
|
|
if (length($line) != 0) {
|
|
WARN("NONBLANK_AFTER_SUMMARY",
|
|
"non-blank line after " .
|
|
"summary line\n" .
|
|
$sublinenr . $here .
|
|
"\n" . $subjectline .
|
|
"\n" . $line . "\n");
|
|
# this non-blank line may or may not
|
|
# be commit text - a warning has been
|
|
# generated so assume it is commit
|
|
# text and move on
|
|
$commit_text_present = 1;
|
|
}
|
|
}
|
|
# The next two cases are BEFORE_SHORTTEXT.
|
|
} elsif ($line=~/^Subject: \[[^\]]*\] (.*)/) {
|
|
# This is the subject line. Go to
|
|
# CHECK_NEXT_SHORTTEXT to wait for the commit
|
|
# text to show up.
|
|
$shorttext = CHECK_NEXT_SHORTTEXT;
|
|
$subjectline = $line;
|
|
$sublinenr = "#$linenr & ";
|
|
# Check for Subject line less than line limit
|
|
if (length($1) > SHORTTEXT_LIMIT && !($1 =~ m/Revert\ \"/)) {
|
|
WARN("LONG_SUMMARY_LINE",
|
|
"summary line over " .
|
|
SHORTTEXT_LIMIT .
|
|
" characters\n" . $herecurr);
|
|
}
|
|
} elsif ($line=~/^ (.*)/) {
|
|
# Indented format, this must be the summary
|
|
# line (i.e. git show). There will be no more
|
|
# headers so we are now in the shorttext.
|
|
$shorttext = IN_SHORTTEXT_BLANKLINE;
|
|
$shorttext_exspc = 4;
|
|
if (length($1) > SHORTTEXT_LIMIT && !($1 =~ m/Revert\ \"/)) {
|
|
WARN("LONG_SUMMARY_LINE",
|
|
"summary line over " .
|
|
SHORTTEXT_LIMIT .
|
|
" characters\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
|
|
$cnt_lines++ if ($realcnt != 0);
|
|
|
|
# Verify the existence of a commit log if appropriate
|
|
# 2 is used because a $signature is counted in $commit_log_lines
|
|
if ($in_commit_log) {
|
|
if ($line !~ /^\s*$/) {
|
|
$commit_log_lines++; #could be a $signature
|
|
}
|
|
} elsif ($has_commit_log && $commit_log_lines < 2) {
|
|
WARN("COMMIT_MESSAGE",
|
|
"Missing commit description - Add an appropriate one\n");
|
|
$commit_log_lines = 2; #warn only once
|
|
}
|
|
|
|
# Check if the commit log has what seems like a diff which can confuse patch
|
|
if ($in_commit_log && !$commit_log_has_diff &&
|
|
(($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
|
|
$line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
|
|
$line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
|
|
$line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
|
|
ERROR("DIFF_IN_COMMIT_MSG",
|
|
"Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
|
|
$commit_log_has_diff = 1;
|
|
}
|
|
|
|
# Check for incorrect file permissions
|
|
if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
|
|
my $permhere = $here . "FILE: $realfile\n";
|
|
if ($realfile !~ m@scripts/@ &&
|
|
$realfile !~ /\.(py|pl|awk|sh)$/) {
|
|
ERROR("EXECUTE_PERMISSIONS",
|
|
"do not set execute permissions for source files\n" . $permhere);
|
|
}
|
|
}
|
|
|
|
# Check the patch for a From:
|
|
if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
|
|
$author = $1;
|
|
$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
|
|
$author =~ s/"//g;
|
|
}
|
|
|
|
# Check the patch for a signoff:
|
|
if ($line =~ /^\s*signed-off-by:/i) {
|
|
$signoff++;
|
|
$in_commit_log = 0;
|
|
if ($author ne '') {
|
|
my $l = $line;
|
|
$l =~ s/"//g;
|
|
if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
|
|
$authorsignoff = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check if MAINTAINERS is being updated. If so, there's probably no need to
|
|
# emit the "does MAINTAINERS need updating?" message on file add/move/delete
|
|
if ($line =~ /^\s*MAINTAINERS\s*\|/) {
|
|
$reported_maintainer_file = 1;
|
|
}
|
|
|
|
# Check signature styles
|
|
if (!$in_header_lines &&
|
|
$line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
|
|
my $space_before = $1;
|
|
my $sign_off = $2;
|
|
my $space_after = $3;
|
|
my $email = $4;
|
|
my $ucfirst_sign_off = ucfirst(lc($sign_off));
|
|
|
|
if ($sign_off !~ /$signature_tags/) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"Non-standard signature: $sign_off\n" . $herecurr);
|
|
}
|
|
if (defined $space_before && $space_before ne "") {
|
|
if (WARN("BAD_SIGN_OFF",
|
|
"Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =
|
|
"$ucfirst_sign_off $email";
|
|
}
|
|
}
|
|
if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
|
|
if (WARN("BAD_SIGN_OFF",
|
|
"'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =
|
|
"$ucfirst_sign_off $email";
|
|
}
|
|
|
|
}
|
|
if (!defined $space_after || $space_after ne " ") {
|
|
if (WARN("BAD_SIGN_OFF",
|
|
"Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =
|
|
"$ucfirst_sign_off $email";
|
|
}
|
|
}
|
|
|
|
my ($email_name, $email_address, $comment) = parse_email($email);
|
|
my $suggested_email = format_email(($email_name, $email_address));
|
|
if ($suggested_email eq "") {
|
|
ERROR("BAD_SIGN_OFF",
|
|
"Unrecognized email address: '$email'\n" . $herecurr);
|
|
} else {
|
|
my $dequoted = $suggested_email;
|
|
$dequoted =~ s/^"//;
|
|
$dequoted =~ s/" </ </;
|
|
# Don't force email to have quotes
|
|
# Allow just an angle bracketed address
|
|
if ("$dequoted$comment" ne $email &&
|
|
"<$email_address>$comment" ne $email &&
|
|
"$suggested_email$comment" ne $email) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# Check for duplicate signatures
|
|
my $sig_nospace = $line;
|
|
$sig_nospace =~ s/\s//g;
|
|
$sig_nospace = lc($sig_nospace);
|
|
if (defined $signatures{$sig_nospace}) {
|
|
WARN("DUPLICATE_SIGN_OFF",
|
|
"Duplicate signature\n" . $herecurr);
|
|
} else {
|
|
$signatures{$sig_nospace} = 1;
|
|
}
|
|
|
|
# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
|
|
if ($sign_off =~ /^co-developed-by:$/i) {
|
|
if ($email eq $author) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
|
|
}
|
|
if (!defined $lines[$linenr]) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
|
|
} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
|
|
} elsif ($1 ne $email) {
|
|
WARN("BAD_SIGN_OFF",
|
|
"Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check email subject for common tools that don't need to be mentioned
|
|
if ($in_header_lines &&
|
|
$line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
|
|
WARN("EMAIL_SUBJECT",
|
|
"A patch subject line should describe the change not the tool that found it\n" . $herecurr);
|
|
}
|
|
|
|
# Check for unwanted Gerrit info
|
|
if ($in_commit_log && $line =~ /^\s*change-id:/i) {
|
|
ERROR("GERRIT_CHANGE_ID",
|
|
"Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
|
|
}
|
|
|
|
# Check if the commit log is in a possible stack dump
|
|
if ($in_commit_log && !$commit_log_possible_stack_dump &&
|
|
($line =~ /^\s*(?:WARNING:|BUG:)/ ||
|
|
$line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
|
|
# timestamp
|
|
$line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
|
|
$line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
|
|
$line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
|
|
# stack dump address styles
|
|
$commit_log_possible_stack_dump = 1;
|
|
}
|
|
|
|
# Check for line lengths > 75 in commit log, warn once
|
|
if ($in_commit_log && !$commit_log_long_line &&
|
|
length($line) > 75 &&
|
|
!($line =~ /^\s*[a-zA-Z0-9_\/\.\-\,]+\s+\|\s+\d+/ ||
|
|
# file delta changes
|
|
$line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
|
|
# filename then :
|
|
$line =~ /^\s*(?:Fixes:|Link:)/i ||
|
|
# A Fixes: or Link: line
|
|
$commit_log_possible_stack_dump)) {
|
|
WARN("COMMIT_LOG_LONG_LINE",
|
|
"Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
|
|
$commit_log_long_line = 1;
|
|
}
|
|
|
|
# Reset possible stack dump if a blank line is found
|
|
if ($in_commit_log && $commit_log_possible_stack_dump &&
|
|
$line =~ /^\s*$/) {
|
|
$commit_log_possible_stack_dump = 0;
|
|
}
|
|
|
|
# Check for git id commit length and improperly formed commit descriptions
|
|
if ($in_commit_log && !$commit_log_possible_stack_dump &&
|
|
$line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
|
|
$line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
|
|
($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
|
|
($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
|
|
$line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
|
|
$line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
|
|
my $init_char = "c";
|
|
my $orig_commit = "";
|
|
my $short = 1;
|
|
my $long = 0;
|
|
my $case = 1;
|
|
my $space = 1;
|
|
my $hasdesc = 0;
|
|
my $hasparens = 0;
|
|
my $id = '0123456789ab';
|
|
my $orig_desc = "commit description";
|
|
my $description = "";
|
|
|
|
if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
|
|
$init_char = $1;
|
|
$orig_commit = lc($2);
|
|
} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
|
|
$orig_commit = lc($1);
|
|
}
|
|
|
|
$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
|
|
$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
|
|
$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
|
|
$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
|
|
if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
|
|
$orig_desc = $1;
|
|
$hasparens = 1;
|
|
} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
|
|
defined $rawlines[$linenr] &&
|
|
$rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
|
|
$orig_desc = $1;
|
|
$hasparens = 1;
|
|
} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
|
|
defined $rawlines[$linenr] &&
|
|
$rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
|
|
$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
|
|
$orig_desc = $1;
|
|
$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
|
|
$orig_desc .= " " . $1;
|
|
$hasparens = 1;
|
|
}
|
|
|
|
($id, $description) = git_commit_info($orig_commit,
|
|
$id, $orig_desc);
|
|
|
|
if (defined($id) &&
|
|
($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
|
|
ERROR("GIT_COMMIT_ID",
|
|
"Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# Check for added, moved or deleted files
|
|
if (!$reported_maintainer_file && !$in_commit_log &&
|
|
($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
|
|
$line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
|
|
($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
|
|
(defined($1) || defined($2))))) {
|
|
$is_patch = 1;
|
|
$reported_maintainer_file = 1;
|
|
WARN("FILE_PATH_CHANGES",
|
|
"added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
|
|
}
|
|
|
|
# Check for adding new DT bindings not in schema format
|
|
if (!$in_commit_log &&
|
|
($line =~ /^new file mode\s*\d+\s*$/) &&
|
|
($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
|
|
WARN("DT_SCHEMA_BINDING_PATCH",
|
|
"DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
|
|
}
|
|
|
|
# Check for wrappage within a valid hunk of the file
|
|
if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
|
|
ERROR("CORRUPTED_PATCH",
|
|
"patch seems to be corrupt (line wrapped?)\n" .
|
|
$herecurr) if (!$emitted_corrupt++);
|
|
}
|
|
|
|
# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
|
|
if (($realfile =~ /^$/ || $line =~ /^\+/) &&
|
|
$rawline !~ m/^$UTF8*$/) {
|
|
my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
|
|
|
|
my $blank = copy_spacing($rawline);
|
|
my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
|
|
my $hereptr = "$hereline$ptr\n";
|
|
|
|
CHK("INVALID_UTF8",
|
|
"Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
|
|
}
|
|
|
|
# Check if it's the start of a commit log
|
|
# (not a header line and we haven't seen the patch filename)
|
|
if ($in_header_lines && $realfile =~ /^$/ &&
|
|
!($rawline =~ /^\s+(?:\S|$)/ ||
|
|
$rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
|
|
$in_header_lines = 0;
|
|
$in_commit_log = 1;
|
|
$has_commit_log = 1;
|
|
}
|
|
|
|
# Check if there is UTF-8 in a commit log when a mail header has explicitly
|
|
# declined it, i.e defined some charset where it is missing.
|
|
if ($in_header_lines &&
|
|
$rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
|
|
$1 !~ /utf-8/i) {
|
|
$non_utf8_charset = 1;
|
|
}
|
|
|
|
if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
|
|
$rawline =~ /$NON_ASCII_UTF8/) {
|
|
WARN("UTF8_BEFORE_PATCH",
|
|
"8-bit UTF-8 used in possible commit log\n" . $herecurr);
|
|
}
|
|
|
|
# Check for absolute kernel paths in commit message
|
|
if ($tree && $in_commit_log) {
|
|
while ($line =~ m{(?:^|\s)(/\S*)}g) {
|
|
my $file = $1;
|
|
|
|
if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
|
|
check_absolute_file($1, $herecurr)) {
|
|
#
|
|
} else {
|
|
check_absolute_file($file, $herecurr);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check for various typo / spelling mistakes
|
|
if (defined($misspellings) &&
|
|
($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
|
|
while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
|
|
my $typo = $1;
|
|
my $typo_fix = $spelling_fix{lc($typo)};
|
|
$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
|
|
$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
|
|
my $msg_level = \&WARN;
|
|
$msg_level = \&CHK if ($file);
|
|
if (&{$msg_level}("TYPO_SPELLING",
|
|
"'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for invalid commit id
|
|
if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
|
|
my $id;
|
|
my $description;
|
|
($id, $description) = git_commit_info($2, undef, undef);
|
|
if (!defined($id)) {
|
|
WARN("UNKNOWN_COMMIT_ID",
|
|
"Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# ignore non-hunk lines and lines being removed
|
|
next if (!$hunk_line || $line =~ /^-/);
|
|
|
|
#trailing whitespace
|
|
if ($line =~ /^\+.*\015/) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
if (ERROR("DOS_LINE_ENDINGS",
|
|
"DOS line endings\n" . $herevet) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/[\s\015]+$//;
|
|
}
|
|
} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
if (ERROR("TRAILING_WHITESPACE",
|
|
"trailing whitespace\n" . $herevet) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\s+$//;
|
|
}
|
|
|
|
$rpt_cleaners = 1;
|
|
}
|
|
|
|
# Check for FSF mailing addresses.
|
|
if ($rawline =~ /\bwrite to the Free/i ||
|
|
$rawline =~ /\b675\s+Mass\s+Ave/i ||
|
|
$rawline =~ /\b59\s+Temple\s+Pl/i ||
|
|
$rawline =~ /\b51\s+Franklin\s+St/i) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
my $msg_level = \&ERROR;
|
|
$msg_level = \&CHK if ($file);
|
|
&{$msg_level}("FSF_MAILING_ADDRESS",
|
|
"Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
|
|
}
|
|
|
|
# check for Kconfig help text having a real description
|
|
# Only applies when adding the entry originally, after that we do not have
|
|
# sufficient context to determine whether it is indeed long enough.
|
|
if ($realfile =~ /Kconfig/ &&
|
|
# 'choice' is usually the last thing on the line (though
|
|
# Kconfig supports named choices), so use a word boundary
|
|
# (\b) rather than a whitespace character (\s)
|
|
$line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
|
|
my $length = 0;
|
|
my $cnt = $realcnt;
|
|
my $ln = $linenr + 1;
|
|
my $f;
|
|
my $is_start = 0;
|
|
my $is_end = 0;
|
|
for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
|
|
$f = $lines[$ln - 1];
|
|
$cnt-- if ($lines[$ln - 1] !~ /^-/);
|
|
$is_end = $lines[$ln - 1] =~ /^\+/;
|
|
|
|
next if ($f =~ /^-/);
|
|
last if (!$file && $f =~ /^\@\@/);
|
|
|
|
if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
|
|
$is_start = 1;
|
|
} elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
|
|
if ($lines[$ln - 1] =~ "---help---") {
|
|
WARN("CONFIG_DESCRIPTION",
|
|
"prefer 'help' over '---help---' for new help texts\n" . $herecurr);
|
|
}
|
|
$length = -1;
|
|
}
|
|
|
|
$f =~ s/^.//;
|
|
$f =~ s/#.*//;
|
|
$f =~ s/^\s+//;
|
|
next if ($f =~ /^$/);
|
|
|
|
# This only checks context lines in the patch
|
|
# and so hopefully shouldn't trigger false
|
|
# positives, even though some of these are
|
|
# common words in help texts
|
|
if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
|
|
if|endif|menu|endmenu|source)\b/x) {
|
|
$is_end = 1;
|
|
last;
|
|
}
|
|
$length++;
|
|
}
|
|
if ($is_start && $is_end && $length < $min_conf_desc_length) {
|
|
WARN("CONFIG_DESCRIPTION",
|
|
"please write a paragraph that describes the config symbol fully\n" . $herecurr);
|
|
}
|
|
#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
|
|
}
|
|
|
|
# check for MAINTAINERS entries that don't have the right form
|
|
if ($realfile =~ /^MAINTAINERS$/ &&
|
|
$rawline =~ /^\+[A-Z]:/ &&
|
|
$rawline !~ /^\+[A-Z]:\t\S/) {
|
|
if (WARN("MAINTAINERS_STYLE",
|
|
"MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
|
|
}
|
|
}
|
|
|
|
# discourage the use of boolean for type definition attributes of Kconfig options
|
|
if ($realfile =~ /Kconfig/ &&
|
|
$line =~ /^\+\s*\bboolean\b/) {
|
|
WARN("CONFIG_TYPE_BOOLEAN",
|
|
"Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
|
|
}
|
|
|
|
if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
|
|
($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
|
|
my $flag = $1;
|
|
my $replacement = {
|
|
'EXTRA_AFLAGS' => 'asflags-y',
|
|
'EXTRA_CFLAGS' => 'ccflags-y',
|
|
'EXTRA_CPPFLAGS' => 'cppflags-y',
|
|
'EXTRA_LDFLAGS' => 'ldflags-y',
|
|
};
|
|
|
|
WARN("DEPRECATED_VARIABLE",
|
|
"Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
|
|
}
|
|
|
|
# check for DT compatible documentation
|
|
if (defined $root &&
|
|
(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
|
|
($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
|
|
|
|
my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
|
|
|
|
my $dt_path = $root . "/Documentation/devicetree/bindings/";
|
|
my $vp_file = $dt_path . "vendor-prefixes.yaml";
|
|
|
|
foreach my $compat (@compats) {
|
|
my $compat2 = $compat;
|
|
$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
|
|
my $compat3 = $compat;
|
|
$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
|
|
`grep -ERq "$compat|$compat2|$compat3" $dt_path`;
|
|
if ( $? >> 8 ) {
|
|
WARN("UNDOCUMENTED_DT_STRING",
|
|
"DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
|
|
}
|
|
|
|
next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
|
|
my $vendor = $1;
|
|
`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
|
|
if ( $? >> 8 ) {
|
|
WARN("UNDOCUMENTED_DT_STRING",
|
|
"DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for using SPDX license tag at beginning of files
|
|
if ($realline == $checklicenseline) {
|
|
if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
|
|
$checklicenseline = 2;
|
|
} elsif ($rawline =~ /^\+/) {
|
|
my $comment = "";
|
|
if ($realfile =~ /\.(h|s|S)$/) {
|
|
$comment = '/*';
|
|
} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
|
|
$comment = '//';
|
|
} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
|
|
$comment = '#';
|
|
} elsif ($realfile =~ /\.rst$/) {
|
|
$comment = '..';
|
|
}
|
|
|
|
# check SPDX comment style for .[chsS] files
|
|
if ($realfile =~ /\.[chsS]$/ &&
|
|
$rawline =~ /SPDX-License-Identifier:/ &&
|
|
$rawline !~ m@^\+\s*\Q$comment\E\s*@) {
|
|
WARN("SPDX_LICENSE_TAG",
|
|
"Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
|
|
}
|
|
|
|
if ($comment !~ /^$/ &&
|
|
$rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
|
|
WARN("SPDX_LICENSE_TAG",
|
|
"Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
|
|
} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
|
|
my $spdx_license = $1;
|
|
if (!is_SPDX_License_valid($spdx_license)) {
|
|
WARN("SPDX_LICENSE_TAG",
|
|
"'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# check we are in a valid source file if not then ignore this hunk
|
|
next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
|
|
|
|
# check for using SPDX-License-Identifier on the wrong line number
|
|
if ($realline != $checklicenseline &&
|
|
$rawline =~ /\bSPDX-License-Identifier:/ &&
|
|
substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
|
|
WARN("SPDX_LICENSE_TAG",
|
|
"Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
|
|
}
|
|
|
|
# line length limit (with some exclusions)
|
|
#
|
|
# There are a few types of lines that may extend beyond $max_line_length:
|
|
# logging functions like pr_info that end in a string
|
|
# lines with a single string
|
|
# #defines that are a single string
|
|
# lines with an RFC3986 like URL
|
|
#
|
|
# There are 3 different line length message types:
|
|
# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
|
|
# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
|
|
# LONG_LINE all other lines longer than $max_line_length
|
|
#
|
|
# if LONG_LINE is ignored, the other 2 types are also ignored
|
|
#
|
|
|
|
if ($line =~ /^\+/ && $length > $max_line_length) {
|
|
my $msg_type = "LONG_LINE";
|
|
|
|
# Check the allowed long line types first
|
|
|
|
# logging functions that end in a string that starts
|
|
# before $max_line_length
|
|
if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
|
|
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
|
|
$msg_type = "";
|
|
|
|
# lines with only strings (w/ possible termination)
|
|
# #defines with only strings
|
|
} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
|
|
$line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
|
|
$msg_type = "";
|
|
|
|
# More special cases
|
|
} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
|
|
$line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
|
|
$msg_type = "";
|
|
|
|
# URL ($rawline is used in case the URL is in a comment)
|
|
} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
|
|
$msg_type = "";
|
|
|
|
# Long copyright statements are another special case
|
|
} elsif ($rawline =~ /^\+.\*.*copyright.*\(c\).*$/i) {
|
|
$msg_type = "";
|
|
|
|
# Otherwise set the alternate message types
|
|
|
|
# a comment starts before $max_line_length
|
|
} elsif ($line =~ /($;[\s$;]*)$/ &&
|
|
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
|
|
$msg_type = "LONG_LINE_COMMENT"
|
|
|
|
# a quoted string starts before $max_line_length
|
|
} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
|
|
length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
|
|
$msg_type = "LONG_LINE_STRING"
|
|
}
|
|
|
|
if ($msg_type ne "" &&
|
|
(show_type("LONG_LINE") || show_type($msg_type))) {
|
|
WARN($msg_type,
|
|
"line over $max_line_length characters\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for adding lines without a newline.
|
|
if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
|
|
WARN("MISSING_EOF_NEWLINE",
|
|
"adding a line without newline at end of file\n" . $herecurr);
|
|
}
|
|
|
|
# check we are in a valid source file C or perl if not then ignore this hunk
|
|
next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
|
|
|
|
# at the beginning of a line any tabs must come first and anything
|
|
# more than 8 must use tabs.
|
|
if ($rawline =~ /^\+\s* \t\s*\S/ ||
|
|
$rawline =~ /^\+\s* \s*/) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
$rpt_cleaners = 1;
|
|
if (ERROR("CODE_INDENT",
|
|
"code indent should use tabs where possible\n" . $herevet) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
|
|
}
|
|
}
|
|
|
|
# check for space before tabs.
|
|
if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
if (WARN("SPACE_BEFORE_TAB",
|
|
"please, no space before tabs\n" . $herevet) &&
|
|
$fix) {
|
|
while ($fixed[$fixlinenr] =~
|
|
s/(^\+.*) {8,8}\t/$1\t\t/) {}
|
|
while ($fixed[$fixlinenr] =~
|
|
s/(^\+.*) +\t/$1\t/) {}
|
|
}
|
|
}
|
|
|
|
# check for assignments on the start of a line
|
|
if ($sline =~ /^\+\s+($Assignment)[^=]/) {
|
|
CHK("ASSIGNMENT_CONTINUATIONS",
|
|
"Assignment operator '$1' should be on the previous line\n" . $hereprev);
|
|
}
|
|
|
|
# check for && or || at the start of a line
|
|
if ($rawline =~ /^\+\s*(&&|\|\|)/) {
|
|
CHK("LOGICAL_CONTINUATIONS",
|
|
"Logical continuations should be on the previous line\n" . $hereprev);
|
|
}
|
|
|
|
# check indentation starts on a tab stop
|
|
if ($perl_version_ok &&
|
|
$sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
|
|
my $indent = length($1);
|
|
if ($indent % 8) {
|
|
if (WARN("TABSTOP",
|
|
"Statements should start on a tabstop\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check multi-line statement indentation matches previous line
|
|
if ($perl_version_ok &&
|
|
$prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
|
|
$prevline =~ /^\+(\t*)(.*)$/;
|
|
my $oldindent = $1;
|
|
my $rest = $2;
|
|
|
|
my $pos = pos_last_openparen($rest);
|
|
if ($pos >= 0) {
|
|
$line =~ /^(\+| )([ \t]*)/;
|
|
my $newindent = $2;
|
|
|
|
my $goodtabindent = $oldindent .
|
|
"\t" x ($pos / 8) .
|
|
" " x ($pos % 8);
|
|
my $goodspaceindent = $oldindent . " " x $pos;
|
|
|
|
if ($newindent ne $goodtabindent &&
|
|
$newindent ne $goodspaceindent) {
|
|
|
|
if (CHK("PARENTHESIS_ALIGNMENT",
|
|
"Alignment should match open parenthesis\n" . $hereprev) &&
|
|
$fix && $line =~ /^\+/) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^\+[ \t]*/\+$goodtabindent/;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for space after cast like "(int) foo" or "(struct foo) bar"
|
|
# avoid checking a few false positives:
|
|
# "sizeof(<type>)" or "__alignof__(<type>)"
|
|
# function pointer declarations like "(*foo)(int) = bar;"
|
|
# structure definitions like "(struct foo) { 0 };"
|
|
# multiline macros that define functions
|
|
# known attributes or the __attribute__ keyword
|
|
if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
|
|
(!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
|
|
if (CHK("SPACING",
|
|
"No space is necessary after a cast\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/(\(\s*$Type\s*\))[ \t]+/$1/;
|
|
}
|
|
}
|
|
|
|
# Block comment styles
|
|
# Networking with an initial /*
|
|
if ($realfile =~ m@^(drivers/net/|net/)@ &&
|
|
$prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
|
|
$rawline =~ /^\+[ \t]*\*/ &&
|
|
$realline > 2) {
|
|
WARN("NETWORKING_BLOCK_COMMENT_STYLE",
|
|
"networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
|
|
}
|
|
|
|
# Block comments use * on subsequent lines
|
|
if ($prevline =~ /$;[ \t]*$/ && #ends in comment
|
|
$prevrawline =~ /^\+.*?\/\*/ && #starting /*
|
|
$prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
|
|
$rawline =~ /^\+/ && #line is new
|
|
$rawline !~ /^\+[ \t]*\*/) { #no leading *
|
|
WARN("BLOCK_COMMENT_STYLE",
|
|
"Block comments use * on subsequent lines\n" . $hereprev);
|
|
}
|
|
|
|
# Block comments use */ on trailing lines
|
|
if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
|
|
$rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
|
|
$rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
|
|
$rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
|
|
WARN("BLOCK_COMMENT_STYLE",
|
|
"Block comments use a trailing */ on a separate line\n" . $herecurr);
|
|
}
|
|
|
|
# Block comment * alignment
|
|
if ($prevline =~ /$;[ \t]*$/ && #ends in comment
|
|
$line =~ /^\+[ \t]*$;/ && #leading comment
|
|
$rawline =~ /^\+[ \t]*\*/ && #leading *
|
|
(($prevrawline =~ /^\+.*?\/\*/ && #leading /*
|
|
$prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
|
|
$prevrawline =~ /^\+[ \t]*\*/)) { #leading *
|
|
my $oldindent;
|
|
$prevrawline =~ m@^\+([ \t]*/?)\*@;
|
|
if (defined($1)) {
|
|
$oldindent = expand_tabs($1);
|
|
} else {
|
|
$prevrawline =~ m@^\+(.*/?)\*@;
|
|
$oldindent = expand_tabs($1);
|
|
}
|
|
$rawline =~ m@^\+([ \t]*)\*@;
|
|
my $newindent = $1;
|
|
$newindent = expand_tabs($newindent);
|
|
if (length($oldindent) ne length($newindent)) {
|
|
WARN("BLOCK_COMMENT_STYLE",
|
|
"Block comments should align the * on each line\n" . $hereprev);
|
|
}
|
|
}
|
|
|
|
# check for missing blank lines after struct/union declarations
|
|
# with exceptions for various attributes and macros
|
|
if ($prevline =~ /^[\+ ]};?\s*$/ &&
|
|
$line =~ /^\+/ &&
|
|
!($line =~ /^\+\s*$/ ||
|
|
$line =~ /^\+\s*EXPORT_SYMBOL/ ||
|
|
$line =~ /^\+\s*MODULE_/i ||
|
|
$line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
|
|
$line =~ /^\+[a-z_]*init/ ||
|
|
$line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
|
|
$line =~ /^\+\s*DECLARE/ ||
|
|
$line =~ /^\+\s*builtin_[\w_]*driver/ ||
|
|
$line =~ /^\+\s*__setup/)) {
|
|
if (CHK("LINE_SPACING",
|
|
"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
|
|
$fix) {
|
|
fix_insert_line($fixlinenr, "\+");
|
|
}
|
|
}
|
|
|
|
# check for multiple consecutive blank lines
|
|
if ($prevline =~ /^[\+ ]\s*$/ &&
|
|
$line =~ /^\+\s*$/ &&
|
|
$last_blank_line != ($linenr - 1)) {
|
|
if (CHK("LINE_SPACING",
|
|
"Please don't use multiple blank lines\n" . $hereprev) &&
|
|
$fix) {
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
}
|
|
|
|
$last_blank_line = $linenr;
|
|
}
|
|
|
|
# check for missing blank lines after declarations
|
|
if ($sline =~ /^\+\s+\S/ && #Not at char 1
|
|
# actual declarations
|
|
($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
|
|
# function pointer declarations
|
|
$prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
|
|
# foo bar; where foo is some local typedef or #define
|
|
$prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
|
|
# known declaration macros
|
|
$prevline =~ /^\+\s+$declaration_macros/) &&
|
|
# for "else if" which can look like "$Ident $Ident"
|
|
!($prevline =~ /^\+\s+$c90_Keywords\b/ ||
|
|
# other possible extensions of declaration lines
|
|
$prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
|
|
# not starting a section or a macro "\" extended line
|
|
$prevline =~ /(?:\{\s*|\\)$/) &&
|
|
# looks like a declaration
|
|
!($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
|
|
# function pointer declarations
|
|
$sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
|
|
# foo bar; where foo is some local typedef or #define
|
|
$sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
|
|
# known declaration macros
|
|
$sline =~ /^\+\s+$declaration_macros/ ||
|
|
# start of struct or union or enum
|
|
$sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
|
|
# start or end of block or continuation of declaration
|
|
$sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
|
|
# bitfield continuation
|
|
$sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
|
|
# other possible extensions of declaration lines
|
|
$sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
|
|
# indentation of previous and current line are the same
|
|
(($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
|
|
if (WARN("LINE_SPACING",
|
|
"Missing a blank line after declarations\n" . $hereprev) &&
|
|
$fix) {
|
|
fix_insert_line($fixlinenr, "\+");
|
|
}
|
|
}
|
|
|
|
# check for spaces at the beginning of a line.
|
|
# Exceptions:
|
|
# 1) within comments
|
|
# 2) indented preprocessor commands
|
|
# 3) hanging labels
|
|
if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
|
|
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
|
if (WARN("LEADING_SPACE",
|
|
"please, no spaces at the start of a line\n" . $herevet) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
|
|
}
|
|
}
|
|
|
|
# check we are in a valid C source file if not then ignore this hunk
|
|
next if ($realfile !~ /\.(h|c)$/);
|
|
|
|
# check for unusual line ending [ or (
|
|
if ($line =~ /^\+.*([\[\(])\s*$/) {
|
|
CHK("OPEN_ENDED_LINE",
|
|
"Lines should not end with a '$1'\n" . $herecurr);
|
|
}
|
|
|
|
# check if this appears to be the start function declaration, save the name
|
|
if ($sline =~ /^\+\{\s*$/ &&
|
|
$prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
|
|
$context_function = $1;
|
|
}
|
|
|
|
# check if this appears to be the end of function declaration
|
|
if ($sline =~ /^\+\}\s*$/) {
|
|
undef $context_function;
|
|
}
|
|
|
|
# check indentation of any line with a bare else
|
|
# (but not if it is a multiple line "if (foo) return bar; else return baz;")
|
|
# if the previous line is a break or return and is indented 1 tab more...
|
|
if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
|
|
my $tabs = length($1) + 1;
|
|
if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
|
|
($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
|
|
defined $lines[$linenr] &&
|
|
$lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
|
|
WARN("UNNECESSARY_ELSE",
|
|
"else is not generally useful after a break or return\n" . $hereprev);
|
|
}
|
|
}
|
|
|
|
# check indentation of a line with a break;
|
|
# if the previous line is a goto or return and is indented the same # of tabs
|
|
if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
|
|
my $tabs = $1;
|
|
if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
|
|
WARN("UNNECESSARY_BREAK",
|
|
"break is not useful after a goto or return\n" . $hereprev);
|
|
}
|
|
}
|
|
|
|
# check for RCS/CVS revision markers
|
|
if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
|
|
WARN("CVS_KEYWORD",
|
|
"CVS style keyword markers, these will _not_ be updated\n". $herecurr);
|
|
}
|
|
|
|
# check for old HOTPLUG __dev<foo> section markings
|
|
if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
|
|
WARN("HOTPLUG_SECTION",
|
|
"Using $1 is unnecessary\n" . $herecurr);
|
|
}
|
|
|
|
# Check for potential 'bare' types
|
|
my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
|
|
$realline_next);
|
|
#print "LINE<$line>\n";
|
|
if ($linenr > $suppress_statement &&
|
|
$realcnt && $sline =~ /.\s*\S/) {
|
|
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
|
|
ctx_statement_block($linenr, $realcnt, 0);
|
|
$stat =~ s/\n./\n /g;
|
|
$cond =~ s/\n./\n /g;
|
|
|
|
#print "linenr<$linenr> <$stat>\n";
|
|
# If this statement has no statement boundaries within
|
|
# it there is no point in retrying a statement scan
|
|
# until we hit end of it.
|
|
my $frag = $stat; $frag =~ s/;+\s*$//;
|
|
if ($frag !~ /(?:{|;)/) {
|
|
#print "skip<$line_nr_next>\n";
|
|
$suppress_statement = $line_nr_next;
|
|
}
|
|
|
|
# Find the real next line.
|
|
$realline_next = $line_nr_next;
|
|
if (defined $realline_next &&
|
|
(!defined $lines[$realline_next - 1] ||
|
|
substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
|
|
$realline_next++;
|
|
}
|
|
|
|
my $s = $stat;
|
|
$s =~ s/{.*$//s;
|
|
|
|
# Ignore goto labels.
|
|
if ($s =~ /$Ident:\*$/s) {
|
|
|
|
# Ignore functions being called
|
|
} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
|
|
|
|
} elsif ($s =~ /^.\s*else\b/s) {
|
|
|
|
# declarations always start with types
|
|
} elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) {
|
|
my $type = $1;
|
|
$type =~ s/\s+/ /g;
|
|
possible($type, "A:" . $s);
|
|
|
|
# definitions in global scope can only start with types
|
|
} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
|
|
possible($1, "B:" . $s);
|
|
}
|
|
|
|
# any (foo ... *) is a pointer cast, and foo is a type
|
|
while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
|
|
possible($1, "C:" . $s);
|
|
}
|
|
|
|
# Check for any sort of function declaration.
|
|
# int foo(something bar, other baz);
|
|
# void (*store_gdt)(x86_descr_ptr *);
|
|
if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
|
|
my ($name_len) = length($1);
|
|
|
|
my $ctx = $s;
|
|
substr($ctx, 0, $name_len + 1, '');
|
|
$ctx =~ s/\)[^\)]*$//;
|
|
|
|
for my $arg (split(/\s*,\s*/, $ctx)) {
|
|
if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
|
|
|
|
possible($1, "D:" . $s);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#
|
|
# Checks which may be anchored in the context.
|
|
#
|
|
|
|
# Check for switch () and associated case and default
|
|
# statements should be at the same indent.
|
|
if ($line=~/\bswitch\s*\(.*\)/) {
|
|
my $err = '';
|
|
my $sep = '';
|
|
my @ctx = ctx_block_outer($linenr, $realcnt);
|
|
shift(@ctx);
|
|
for my $ctx (@ctx) {
|
|
my ($clen, $cindent) = line_stats($ctx);
|
|
if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
|
|
$indent != $cindent) {
|
|
$err .= "$sep$ctx\n";
|
|
$sep = '';
|
|
} else {
|
|
$sep = "[...]\n";
|
|
}
|
|
}
|
|
if ($err ne '') {
|
|
ERROR("SWITCH_CASE_INDENT_LEVEL",
|
|
"switch and case should be at the same indent\n$hereline$err");
|
|
}
|
|
}
|
|
|
|
# if/while/etc brace do not go on next line, unless defining a do while loop,
|
|
# or if that brace on the next line is for something else
|
|
if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
|
|
my $pre_ctx = "$1$2";
|
|
|
|
my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
|
|
|
|
if ($line =~ /^\+\t{6,}/) {
|
|
WARN("DEEP_INDENTATION",
|
|
"Too many leading tabs - consider code refactoring\n" . $herecurr);
|
|
}
|
|
|
|
my $ctx_cnt = $realcnt - $#ctx - 1;
|
|
my $ctx = join("\n", @ctx);
|
|
|
|
my $ctx_ln = $linenr;
|
|
my $ctx_skip = $realcnt;
|
|
|
|
while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
|
|
defined $lines[$ctx_ln - 1] &&
|
|
$lines[$ctx_ln - 1] =~ /^-/)) {
|
|
##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
|
|
$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
|
|
$ctx_ln++;
|
|
}
|
|
|
|
#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
|
|
#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
|
|
|
|
if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
|
|
ERROR("OPEN_BRACE",
|
|
"that open brace { should be on the previous line\n" .
|
|
"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
|
|
}
|
|
if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
|
|
$ctx =~ /\)\s*\;\s*$/ &&
|
|
defined $lines[$ctx_ln - 1])
|
|
{
|
|
my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
|
|
if ($nindent > $indent) {
|
|
WARN("TRAILING_SEMICOLON",
|
|
"trailing semicolon indicates no statements, indent implies otherwise\n" .
|
|
"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check relative indent for conditionals and blocks.
|
|
if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
|
|
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
|
|
ctx_statement_block($linenr, $realcnt, 0)
|
|
if (!defined $stat);
|
|
my ($s, $c) = ($stat, $cond);
|
|
|
|
substr($s, 0, length($c), '');
|
|
|
|
# remove inline comments
|
|
$s =~ s/$;/ /g;
|
|
$c =~ s/$;/ /g;
|
|
|
|
# Find out how long the conditional actually is.
|
|
my @newlines = ($c =~ /\n/gs);
|
|
my $cond_lines = 1 + $#newlines;
|
|
|
|
# Make sure we remove the line prefixes as we have
|
|
# none on the first line, and are going to readd them
|
|
# where necessary.
|
|
$s =~ s/\n./\n/gs;
|
|
while ($s =~ /\n\s+\\\n/) {
|
|
$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
|
|
}
|
|
|
|
# We want to check the first line inside the block
|
|
# starting at the end of the conditional, so remove:
|
|
# 1) any blank line termination
|
|
# 2) any opening brace { on end of the line
|
|
# 3) any do (...) {
|
|
my $continuation = 0;
|
|
my $check = 0;
|
|
$s =~ s/^.*\bdo\b//;
|
|
$s =~ s/^\s*{//;
|
|
if ($s =~ s/^\s*\\//) {
|
|
$continuation = 1;
|
|
}
|
|
if ($s =~ s/^\s*?\n//) {
|
|
$check = 1;
|
|
$cond_lines++;
|
|
}
|
|
|
|
# Also ignore a loop construct at the end of a
|
|
# preprocessor statement.
|
|
if (($prevline =~ /^.\s*#\s*define\s/ ||
|
|
$prevline =~ /\\\s*$/) && $continuation == 0) {
|
|
$check = 0;
|
|
}
|
|
|
|
my $cond_ptr = -1;
|
|
$continuation = 0;
|
|
while ($cond_ptr != $cond_lines) {
|
|
$cond_ptr = $cond_lines;
|
|
|
|
# If we see an #else/#elif then the code
|
|
# is not linear.
|
|
if ($s =~ /^\s*\#\s*(?:else|elif)/) {
|
|
$check = 0;
|
|
}
|
|
|
|
# Ignore:
|
|
# 1) blank lines, they should be at 0,
|
|
# 2) preprocessor lines, and
|
|
# 3) labels.
|
|
if ($continuation ||
|
|
$s =~ /^\s*?\n/ ||
|
|
$s =~ /^\s*#\s*?/ ||
|
|
$s =~ /^\s*$Ident\s*:/) {
|
|
$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
|
|
if ($s =~ s/^.*?\n//) {
|
|
$cond_lines++;
|
|
}
|
|
}
|
|
}
|
|
|
|
my (undef, $sindent) = line_stats("+" . $s);
|
|
my $stat_real = raw_line($linenr, $cond_lines);
|
|
|
|
# Check if either of these lines are modified, else
|
|
# this is not this patch's fault.
|
|
if (!defined($stat_real) ||
|
|
$stat !~ /^\+/ && $stat_real !~ /^\+/) {
|
|
$check = 0;
|
|
}
|
|
if (defined($stat_real) && $cond_lines > 1) {
|
|
$stat_real = "[...]\n$stat_real";
|
|
}
|
|
|
|
#print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
|
|
|
|
if ($check && $s ne '' &&
|
|
(($sindent % 8) != 0 ||
|
|
($sindent < $indent) ||
|
|
($sindent == $indent &&
|
|
($s !~ /^\s*(?:\}|\{|else\b)/)) ||
|
|
($sindent > $indent + 8))) {
|
|
WARN("SUSPECT_CODE_INDENT",
|
|
"suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
|
|
}
|
|
}
|
|
|
|
# Track the 'values' across context and added lines.
|
|
my $opline = $line; $opline =~ s/^./ /;
|
|
my ($curr_values, $curr_vars) =
|
|
annotate_values($opline . "\n", $prev_values);
|
|
$curr_values = $prev_values . $curr_values;
|
|
if ($dbg_values) {
|
|
my $outline = $opline; $outline =~ s/\t/ /g;
|
|
print "$linenr > .$outline\n";
|
|
print "$linenr > $curr_values\n";
|
|
print "$linenr > $curr_vars\n";
|
|
}
|
|
$prev_values = substr($curr_values, -1);
|
|
|
|
#ignore lines not being added
|
|
next if ($line =~ /^[^\+]/);
|
|
|
|
# check for dereferences that span multiple lines
|
|
if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
|
|
$line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
|
|
$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
|
|
my $ref = $1;
|
|
$line =~ /^.\s*($Lval)/;
|
|
$ref .= $1;
|
|
$ref =~ s/\s//g;
|
|
WARN("MULTILINE_DEREFERENCE",
|
|
"Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
|
|
}
|
|
|
|
# check for declarations of signed or unsigned without int
|
|
while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
|
|
my $type = $1;
|
|
my $var = $2;
|
|
$var = "" if (!defined $var);
|
|
if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
|
|
my $sign = $1;
|
|
my $pointer = $2;
|
|
|
|
$pointer = "" if (!defined $pointer);
|
|
|
|
if (WARN("UNSPECIFIED_INT",
|
|
"Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
|
|
$fix) {
|
|
my $decl = trim($sign) . " int ";
|
|
my $comp_pointer = $pointer;
|
|
$comp_pointer =~ s/\s//g;
|
|
$decl .= $comp_pointer;
|
|
$decl = rtrim($decl) if ($var eq "");
|
|
$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
|
|
}
|
|
}
|
|
}
|
|
|
|
# TEST: allow direct testing of the type matcher.
|
|
if ($dbg_type) {
|
|
if ($line =~ /^.\s*$Declare\s*$/) {
|
|
ERROR("TEST_TYPE",
|
|
"TEST: is type\n" . $herecurr);
|
|
} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
|
|
ERROR("TEST_NOT_TYPE",
|
|
"TEST: is not type ($1 is)\n". $herecurr);
|
|
}
|
|
next;
|
|
}
|
|
# TEST: allow direct testing of the attribute matcher.
|
|
if ($dbg_attr) {
|
|
if ($line =~ /^.\s*$Modifier\s*$/) {
|
|
ERROR("TEST_ATTR",
|
|
"TEST: is attr\n" . $herecurr);
|
|
} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
|
|
ERROR("TEST_NOT_ATTR",
|
|
"TEST: is not attr ($1 is)\n". $herecurr);
|
|
}
|
|
next;
|
|
}
|
|
|
|
# check for initialisation to aggregates open brace on the next line
|
|
if ($line =~ /^.\s*{/ &&
|
|
$prevline =~ /(?:^|[^=])=\s*$/) {
|
|
if (ERROR("OPEN_BRACE",
|
|
"that open brace { should be on the previous line\n" . $hereprev) &&
|
|
$fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixedline = $prevrawline;
|
|
$fixedline =~ s/\s*=\s*$/ = {/;
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
$fixedline = $line;
|
|
$fixedline =~ s/^(.\s*)\{\s*/$1/;
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
}
|
|
|
|
#
|
|
# Checks which are anchored on the added line.
|
|
#
|
|
|
|
# check for malformed paths in #include statements (uses RAW line)
|
|
if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
|
|
my $path = $1;
|
|
if ($path =~ m{//}) {
|
|
ERROR("MALFORMED_INCLUDE",
|
|
"malformed #include filename\n" . $herecurr);
|
|
}
|
|
if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
|
|
ERROR("UAPI_INCLUDE",
|
|
"No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# no C99 // comments
|
|
if ($line =~ m{//}) {
|
|
if (ERROR("C99_COMMENTS",
|
|
"do not use C99 // comments\n" . $herecurr) &&
|
|
$fix) {
|
|
my $line = $fixed[$fixlinenr];
|
|
if ($line =~ /\/\/(.*)$/) {
|
|
my $comment = trim($1);
|
|
$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
|
|
}
|
|
}
|
|
}
|
|
# Remove C99 comments.
|
|
$line =~ s@//.*@@;
|
|
$opline =~ s@//.*@@;
|
|
|
|
# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
|
|
# the whole statement.
|
|
#print "APW <$lines[$realline_next - 1]>\n";
|
|
if (defined $realline_next &&
|
|
exists $lines[$realline_next - 1] &&
|
|
!defined $suppress_export{$realline_next} &&
|
|
($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
|
|
$lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
|
|
# Handle definitions which produce identifiers with
|
|
# a prefix:
|
|
# XXX(foo);
|
|
# EXPORT_SYMBOL(something_foo);
|
|
my $name = $1;
|
|
if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
|
|
$name =~ /^${Ident}_$2/) {
|
|
#print "FOO C name<$name>\n";
|
|
$suppress_export{$realline_next} = 1;
|
|
|
|
} elsif ($stat !~ /(?:
|
|
\n.}\s*$|
|
|
^.DEFINE_$Ident\(\Q$name\E\)|
|
|
^.DECLARE_$Ident\(\Q$name\E\)|
|
|
^.LIST_HEAD\(\Q$name\E\)|
|
|
^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
|
|
\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
|
|
)/x) {
|
|
#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
|
|
$suppress_export{$realline_next} = 2;
|
|
} else {
|
|
$suppress_export{$realline_next} = 1;
|
|
}
|
|
}
|
|
if (!defined $suppress_export{$linenr} &&
|
|
$prevline =~ /^.\s*$/ &&
|
|
($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
|
|
$line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
|
|
#print "FOO B <$lines[$linenr - 1]>\n";
|
|
$suppress_export{$linenr} = 2;
|
|
}
|
|
if (defined $suppress_export{$linenr} &&
|
|
$suppress_export{$linenr} == 2) {
|
|
WARN("EXPORT_SYMBOL",
|
|
"EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
|
|
}
|
|
|
|
# check for global initialisers.
|
|
if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
|
|
if (ERROR("GLOBAL_INITIALISERS",
|
|
"do not initialise globals to $1\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
|
|
}
|
|
}
|
|
# check for static initialisers.
|
|
if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
|
|
if (ERROR("INITIALISED_STATIC",
|
|
"do not initialise statics to $1\n" .
|
|
$herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
|
|
}
|
|
}
|
|
|
|
# check for misordered declarations of char/short/int/long with signed/unsigned
|
|
while ($sline =~ m{(\b$TypeMisordered\b)}g) {
|
|
my $tmp = trim($1);
|
|
WARN("MISORDERED_TYPE",
|
|
"type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
|
|
}
|
|
|
|
# check for unnecessary <signed> int declarations of short/long/long long
|
|
while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
|
|
my $type = trim($1);
|
|
next if ($type !~ /\bint\b/);
|
|
next if ($type !~ /\b(?:short|long\s+long|long)\b/);
|
|
my $new_type = $type;
|
|
$new_type =~ s/\b\s*int\s*\b/ /;
|
|
$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
|
|
$new_type =~ s/^const\s+//;
|
|
$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
|
|
$new_type = "const $new_type" if ($type =~ /^const\b/);
|
|
$new_type =~ s/\s+/ /g;
|
|
$new_type = trim($new_type);
|
|
if (WARN("UNNECESSARY_INT",
|
|
"Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
|
|
}
|
|
}
|
|
|
|
# check for static const char * arrays.
|
|
if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
|
|
WARN("STATIC_CONST_CHAR_ARRAY",
|
|
"static const char * array should probably be static const char * const\n" .
|
|
$herecurr);
|
|
}
|
|
|
|
# check for initialized const char arrays that should be static const
|
|
if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
|
|
if (WARN("STATIC_CONST_CHAR_ARRAY",
|
|
"const array should probably be static const\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
|
|
}
|
|
}
|
|
|
|
# check for static char foo[] = "bar" declarations.
|
|
if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
|
|
WARN("STATIC_CONST_CHAR_ARRAY",
|
|
"static char array declaration should probably be static const char\n" .
|
|
$herecurr);
|
|
}
|
|
|
|
# check for const <foo> const where <foo> is not a pointer or array type
|
|
if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
|
|
my $found = $1;
|
|
if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
|
|
WARN("CONST_CONST",
|
|
"'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
|
|
} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
|
|
WARN("CONST_CONST",
|
|
"'const $found const' should probably be 'const $found'\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for non-global char *foo[] = {"bar", ...} declarations.
|
|
if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
|
|
WARN("STATIC_CONST_CHAR_ARRAY",
|
|
"char * array declaration might be better as static const\n" .
|
|
$herecurr);
|
|
}
|
|
|
|
# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
|
|
if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
|
|
my $array = $1;
|
|
if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
|
|
my $array_div = $1;
|
|
if (WARN("ARRAY_SIZE",
|
|
"Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for function declarations without arguments like "int foo()"
|
|
if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
|
|
if (ERROR("FUNCTION_WITHOUT_ARGS",
|
|
"Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
|
|
}
|
|
}
|
|
|
|
# check for new typedefs, only function parameters and sparse annotations
|
|
# make sense.
|
|
if ($line =~ /\btypedef\s/ &&
|
|
$line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
|
|
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
|
|
$line !~ /\b$typeTypedefs\b/ &&
|
|
$line !~ /\b__bitwise\b/) {
|
|
WARN("NEW_TYPEDEFS",
|
|
"do not add new typedefs\n" . $herecurr);
|
|
}
|
|
|
|
# * goes on variable not on type
|
|
# (char*[ const])
|
|
while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
|
|
#print "AA<$1>\n";
|
|
my ($ident, $from, $to) = ($1, $2, $2);
|
|
|
|
# Should start with a space.
|
|
$to =~ s/^(\S)/ $1/;
|
|
# Should not end with a space.
|
|
$to =~ s/\s+$//;
|
|
# '*'s should not have spaces between.
|
|
while ($to =~ s/\*\s+\*/\*\*/) {
|
|
}
|
|
|
|
## print "1: from<$from> to<$to> ident<$ident>\n";
|
|
if ($from ne $to) {
|
|
if (ERROR("POINTER_LOCATION",
|
|
"\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
|
|
$fix) {
|
|
my $sub_from = $ident;
|
|
my $sub_to = $ident;
|
|
$sub_to =~ s/\Q$from\E/$to/;
|
|
$fixed[$fixlinenr] =~
|
|
s@\Q$sub_from\E@$sub_to@;
|
|
}
|
|
}
|
|
}
|
|
while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
|
|
#print "BB<$1>\n";
|
|
my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
|
|
|
|
# Should start with a space.
|
|
$to =~ s/^(\S)/ $1/;
|
|
# Should not end with a space.
|
|
$to =~ s/\s+$//;
|
|
# '*'s should not have spaces between.
|
|
while ($to =~ s/\*\s+\*/\*\*/) {
|
|
}
|
|
# Modifiers should have spaces.
|
|
$to =~ s/(\b$Modifier$)/$1 /;
|
|
|
|
## print "2: from<$from> to<$to> ident<$ident>\n";
|
|
if ($from ne $to && $ident !~ /^$Modifier$/) {
|
|
if (ERROR("POINTER_LOCATION",
|
|
"\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
|
|
$fix) {
|
|
|
|
my $sub_from = $match;
|
|
my $sub_to = $match;
|
|
$sub_to =~ s/\Q$from\E/$to/;
|
|
$fixed[$fixlinenr] =~
|
|
s@\Q$sub_from\E@$sub_to@;
|
|
}
|
|
}
|
|
}
|
|
|
|
# avoid BUG() or BUG_ON()
|
|
if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
|
|
my $msg_level = \&WARN;
|
|
$msg_level = \&CHK if ($file);
|
|
&{$msg_level}("AVOID_BUG",
|
|
"Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
|
|
}
|
|
|
|
# avoid LINUX_VERSION_CODE
|
|
if ($line =~ /\bLINUX_VERSION_CODE\b/) {
|
|
WARN("LINUX_VERSION_CODE",
|
|
"LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
|
|
}
|
|
|
|
# check for uses of printk_ratelimit
|
|
if ($line =~ /\bprintk_ratelimit\s*\(/) {
|
|
WARN("PRINTK_RATELIMITED",
|
|
"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
|
|
}
|
|
|
|
# printk should use KERN_* levels
|
|
if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
|
|
WARN("PRINTK_WITHOUT_KERN_LEVEL",
|
|
"printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
|
|
}
|
|
|
|
if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
|
|
my $orig = $1;
|
|
my $level = lc($orig);
|
|
$level = "warn" if ($level eq "warning");
|
|
my $level2 = $level;
|
|
$level2 = "dbg" if ($level eq "debug");
|
|
WARN("PREFER_PR_LEVEL",
|
|
"Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
|
|
}
|
|
|
|
if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
|
|
my $orig = $1;
|
|
my $level = lc($orig);
|
|
$level = "warn" if ($level eq "warning");
|
|
$level = "dbg" if ($level eq "debug");
|
|
WARN("PREFER_DEV_LEVEL",
|
|
"Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
|
|
}
|
|
|
|
# ENOSYS means "bad syscall nr" and nothing else. This will have a small
|
|
# number of false positives, but assembly files are not checked, so at
|
|
# least the arch entry code will not trigger this warning.
|
|
if ($line =~ /\bENOSYS\b/) {
|
|
WARN("ENOSYS",
|
|
"ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
|
|
}
|
|
|
|
# function brace can't be on same line, except for #defines of do while,
|
|
# or if closed on same line
|
|
if ($perl_version_ok &&
|
|
$sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
|
|
$sline !~ /\#\s*define\b.*do\s*\{/ &&
|
|
$sline !~ /}/) {
|
|
if (ERROR("OPEN_BRACE",
|
|
"open brace '{' following function definitions go on the next line\n" . $herecurr) &&
|
|
$fix) {
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixed_line = $rawline;
|
|
$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
|
|
my $line1 = $1;
|
|
my $line2 = $2;
|
|
fix_insert_line($fixlinenr, ltrim($line1));
|
|
fix_insert_line($fixlinenr, "\+{");
|
|
if ($line2 !~ /^\s*$/) {
|
|
fix_insert_line($fixlinenr, "\+\t" . trim($line2));
|
|
}
|
|
}
|
|
}
|
|
|
|
# open braces for enum, union and struct go on the same line.
|
|
if ($line =~ /^.\s*{/ &&
|
|
$prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
|
|
if (ERROR("OPEN_BRACE",
|
|
"open brace '{' following $1 go on the same line\n" . $hereprev) &&
|
|
$fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixedline = rtrim($prevrawline) . " {";
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
$fixedline = $rawline;
|
|
$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
|
|
if ($fixedline !~ /^\+\s*$/) {
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
}
|
|
}
|
|
|
|
# missing space after union, struct or enum definition
|
|
if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
|
|
if (WARN("SPACING",
|
|
"missing space after $1 definition\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
|
|
}
|
|
}
|
|
|
|
# Function pointer declarations
|
|
# check spacing between type, funcptr, and args
|
|
# canonical declaration is "type (*funcptr)(args...)"
|
|
if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
|
|
my $declare = $1;
|
|
my $pre_pointer_space = $2;
|
|
my $post_pointer_space = $3;
|
|
my $funcname = $4;
|
|
my $post_funcname_space = $5;
|
|
my $pre_args_space = $6;
|
|
|
|
# the $Declare variable will capture all spaces after the type
|
|
# so check it for a missing trailing missing space but pointer return types
|
|
# don't need a space so don't warn for those.
|
|
my $post_declare_space = "";
|
|
if ($declare =~ /(\s+)$/) {
|
|
$post_declare_space = $1;
|
|
$declare = rtrim($declare);
|
|
}
|
|
if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
|
|
WARN("SPACING",
|
|
"missing space after return type\n" . $herecurr);
|
|
$post_declare_space = " ";
|
|
}
|
|
|
|
# unnecessary space "type (*funcptr)(args...)"
|
|
# This test is not currently implemented because these declarations are
|
|
# equivalent to
|
|
# int foo(int bar, ...)
|
|
# and this is form shouldn't/doesn't generate a checkpatch warning.
|
|
#
|
|
# elsif ($declare =~ /\s{2,}$/) {
|
|
# WARN("SPACING",
|
|
# "Multiple spaces after return type\n" . $herecurr);
|
|
# }
|
|
|
|
# unnecessary space "type ( *funcptr)(args...)"
|
|
if (defined $pre_pointer_space &&
|
|
$pre_pointer_space =~ /^\s/) {
|
|
WARN("SPACING",
|
|
"Unnecessary space after function pointer open parenthesis\n" . $herecurr);
|
|
}
|
|
|
|
# unnecessary space "type (* funcptr)(args...)"
|
|
if (defined $post_pointer_space &&
|
|
$post_pointer_space =~ /^\s/) {
|
|
WARN("SPACING",
|
|
"Unnecessary space before function pointer name\n" . $herecurr);
|
|
}
|
|
|
|
# unnecessary space "type (*funcptr )(args...)"
|
|
if (defined $post_funcname_space &&
|
|
$post_funcname_space =~ /^\s/) {
|
|
WARN("SPACING",
|
|
"Unnecessary space after function pointer name\n" . $herecurr);
|
|
}
|
|
|
|
# unnecessary space "type (*funcptr) (args...)"
|
|
if (defined $pre_args_space &&
|
|
$pre_args_space =~ /^\s/) {
|
|
WARN("SPACING",
|
|
"Unnecessary space before function pointer arguments\n" . $herecurr);
|
|
}
|
|
|
|
if (show_type("SPACING") && $fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
|
|
}
|
|
}
|
|
|
|
# check for spacing round square brackets; allowed:
|
|
# 1. with a type on the left -- int [] a;
|
|
# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
|
|
# 3. inside a curly brace -- = { [0...10] = 5 }
|
|
while ($line =~ /(.*?\s)\[/g) {
|
|
my ($where, $prefix) = ($-[1], $1);
|
|
if ($prefix !~ /$Type\s+$/ &&
|
|
($where != 0 || $prefix !~ /^.\s+$/) &&
|
|
$prefix !~ /[{,:]\s+$/) {
|
|
if (ERROR("BRACKET_SPACE",
|
|
"space prohibited before open square bracket '['\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^(\+.*?)\s+\[/$1\[/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for spaces between functions and their parentheses.
|
|
while ($line =~ /($Ident)\s+\(/g) {
|
|
my $name = $1;
|
|
my $ctx_before = substr($line, 0, $-[1]);
|
|
my $ctx = "$ctx_before$name";
|
|
|
|
# Ignore those directives where spaces _are_ permitted.
|
|
if ($name =~ /^(?:
|
|
if|for|while|switch|return|case|
|
|
volatile|__volatile__|
|
|
__attribute__|format|__extension__|
|
|
asm|__asm__)$/x)
|
|
{
|
|
# cpp #define statements have non-optional spaces, ie
|
|
# if there is a space between the name and the open
|
|
# parenthesis it is simply not a parameter group.
|
|
} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
|
|
|
|
# cpp #elif statement condition may start with a (
|
|
} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
|
|
|
|
# If this whole things ends with a type its most
|
|
# likely a typedef for a function.
|
|
} elsif ($ctx =~ /$Type$/) {
|
|
|
|
} else {
|
|
if (WARN("SPACING",
|
|
"space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\b$name\s+\(/$name\(/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check operator spacing.
|
|
if (!($line=~/\#\s*include/)) {
|
|
my $fixed_line = "";
|
|
my $line_fixed = 0;
|
|
|
|
my $ops = qr{
|
|
<<=|>>=|<=|>=|==|!=|
|
|
\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
|
|
=>|->|<<|>>|<|>|=|!|~|
|
|
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
|
|
\?:|\?|:
|
|
}x;
|
|
my @elements = split(/($ops|;)/, $opline);
|
|
|
|
## print("element count: <" . $#elements . ">\n");
|
|
## foreach my $el (@elements) {
|
|
## print("el: <$el>\n");
|
|
## }
|
|
|
|
my @fix_elements = ();
|
|
my $off = 0;
|
|
|
|
foreach my $el (@elements) {
|
|
push(@fix_elements, substr($rawline, $off, length($el)));
|
|
$off += length($el);
|
|
}
|
|
|
|
$off = 0;
|
|
|
|
my $blank = copy_spacing($opline);
|
|
my $last_after = -1;
|
|
|
|
for (my $n = 0; $n < $#elements; $n += 2) {
|
|
|
|
my $good = $fix_elements[$n] . $fix_elements[$n + 1];
|
|
|
|
## print("n: <$n> good: <$good>\n");
|
|
|
|
$off += length($elements[$n]);
|
|
|
|
# Pick up the preceding and succeeding characters.
|
|
my $ca = substr($opline, 0, $off);
|
|
my $cc = '';
|
|
if (length($opline) >= ($off + length($elements[$n + 1]))) {
|
|
$cc = substr($opline, $off + length($elements[$n + 1]));
|
|
}
|
|
my $cb = "$ca$;$cc";
|
|
|
|
my $a = '';
|
|
$a = 'V' if ($elements[$n] ne '');
|
|
$a = 'W' if ($elements[$n] =~ /\s$/);
|
|
$a = 'C' if ($elements[$n] =~ /$;$/);
|
|
$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
|
|
$a = 'O' if ($elements[$n] eq '');
|
|
$a = 'E' if ($ca =~ /^\s*$/);
|
|
|
|
my $op = $elements[$n + 1];
|
|
|
|
my $c = '';
|
|
if (defined $elements[$n + 2]) {
|
|
$c = 'V' if ($elements[$n + 2] ne '');
|
|
$c = 'W' if ($elements[$n + 2] =~ /^\s/);
|
|
$c = 'C' if ($elements[$n + 2] =~ /^$;/);
|
|
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
|
|
$c = 'O' if ($elements[$n + 2] eq '');
|
|
$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
|
|
} else {
|
|
$c = 'E';
|
|
}
|
|
|
|
my $ctx = "${a}x${c}";
|
|
|
|
my $at = "(ctx:$ctx)";
|
|
|
|
my $ptr = substr($blank, 0, $off) . "^";
|
|
my $hereptr = "$hereline$ptr\n";
|
|
|
|
# Pull out the value of this operator.
|
|
my $op_type = substr($curr_values, $off + 1, 1);
|
|
|
|
# Get the full operator variant.
|
|
my $opv = $op . substr($curr_vars, $off, 1);
|
|
|
|
# Ignore operators passed as parameters.
|
|
if ($op_type ne 'V' &&
|
|
$ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
|
|
|
|
# # Ignore comments
|
|
# } elsif ($op =~ /^$;+$/) {
|
|
|
|
# ; should have either the end of line or a space or \ after it
|
|
} elsif ($op eq ';') {
|
|
if ($ctx !~ /.x[WEBC]/ &&
|
|
$cc !~ /^\\/ && $cc !~ /^;/) {
|
|
if (ERROR("SPACING",
|
|
"space required after that '$op' $at\n" . $hereptr)) {
|
|
$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# // is a comment
|
|
} elsif ($op eq '//') {
|
|
|
|
# : when part of a bitfield
|
|
} elsif ($opv eq ':B') {
|
|
# skip the bitfield test for now
|
|
|
|
# No spaces for:
|
|
# ->
|
|
} elsif ($op eq '->') {
|
|
if ($ctx =~ /Wx.|.xW/) {
|
|
if (ERROR("SPACING",
|
|
"spaces prohibited around that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
|
|
if (defined $fix_elements[$n + 2]) {
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
}
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# , must not have a space before and must have a space on the right.
|
|
} elsif ($op eq ',') {
|
|
my $rtrim_before = 0;
|
|
my $space_after = 0;
|
|
if ($ctx =~ /Wx./) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited before that '$op' $at\n" . $hereptr)) {
|
|
$line_fixed = 1;
|
|
$rtrim_before = 1;
|
|
}
|
|
}
|
|
if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
|
|
if (ERROR("SPACING",
|
|
"space required after that '$op' $at\n" . $hereptr)) {
|
|
$line_fixed = 1;
|
|
$last_after = $n;
|
|
$space_after = 1;
|
|
}
|
|
}
|
|
if ($rtrim_before || $space_after) {
|
|
if ($rtrim_before) {
|
|
$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
|
|
} else {
|
|
$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
|
|
}
|
|
if ($space_after) {
|
|
$good .= " ";
|
|
}
|
|
}
|
|
|
|
# '*' as part of a type definition -- reported already.
|
|
} elsif ($opv eq '*_') {
|
|
#warn "'*' is part of type\n";
|
|
|
|
# unary operators should have a space before and
|
|
# none after. May be left adjacent to another
|
|
# unary operator, or a cast
|
|
} elsif ($op eq '!' || $op eq '~' ||
|
|
$opv eq '*U' || $opv eq '-U' ||
|
|
$opv eq '&U' || $opv eq '&&U') {
|
|
if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
|
|
if (ERROR("SPACING",
|
|
"space required before that '$op' $at\n" . $hereptr)) {
|
|
if ($n != $last_after + 2) {
|
|
$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
}
|
|
if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
|
|
# A unary '*' may be const
|
|
|
|
} elsif ($ctx =~ /.xW/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited after that '$op' $at\n" . $hereptr)) {
|
|
$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
|
|
if (defined $fix_elements[$n + 2]) {
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
}
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# unary ++ and unary -- are allowed no space on one side.
|
|
} elsif ($op eq '++' or $op eq '--') {
|
|
if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
|
|
if (ERROR("SPACING",
|
|
"space required one side of that '$op' $at\n" . $hereptr)) {
|
|
$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
if ($ctx =~ /Wx[BE]/ ||
|
|
($ctx =~ /Wx./ && $cc =~ /^;/)) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited before that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
if ($ctx =~ /ExW/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited after that '$op' $at\n" . $hereptr)) {
|
|
$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
|
|
if (defined $fix_elements[$n + 2]) {
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
}
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# << and >> may either have or not have spaces both sides
|
|
} elsif ($op eq '<<' or $op eq '>>' or
|
|
$op eq '&' or $op eq '^' or $op eq '|' or
|
|
$op eq '+' or $op eq '-' or
|
|
$op eq '*' or $op eq '/' or
|
|
$op eq '%')
|
|
{
|
|
if ($check) {
|
|
if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
|
|
if (CHK("SPACING",
|
|
"spaces preferred around that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
$line_fixed = 1;
|
|
}
|
|
} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
|
|
if (CHK("SPACING",
|
|
"space preferred before that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
|
|
if (ERROR("SPACING",
|
|
"need consistent spacing around '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
|
|
if (defined $fix_elements[$n + 2]) {
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
}
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# A colon needs no spaces before when it is
|
|
# terminating a case value or a label.
|
|
} elsif ($opv eq ':C' || $opv eq ':L') {
|
|
if ($ctx =~ /Wx./) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited before that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
|
|
# All the others need spaces both sides.
|
|
} elsif ($ctx !~ /[EWC]x[CWE]/) {
|
|
my $ok = 0;
|
|
|
|
# Ignore email addresses <foo@bar>
|
|
if (($op eq '<' &&
|
|
$cc =~ /^\S+\@\S+>/) ||
|
|
($op eq '>' &&
|
|
$ca =~ /<\S+\@\S+$/))
|
|
{
|
|
$ok = 1;
|
|
}
|
|
|
|
# for asm volatile statements
|
|
# ignore a colon with another
|
|
# colon immediately before or after
|
|
if (($op eq ':') &&
|
|
($ca =~ /:$/ || $cc =~ /^:/)) {
|
|
$ok = 1;
|
|
}
|
|
|
|
# messages are ERROR, but ?: are CHK
|
|
if ($ok == 0) {
|
|
my $msg_level = \&ERROR;
|
|
$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
|
|
|
|
if (&{$msg_level}("SPACING",
|
|
"spaces required around that '$op' $at\n" . $hereptr)) {
|
|
$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
|
|
if (defined $fix_elements[$n + 2]) {
|
|
$fix_elements[$n + 2] =~ s/^\s+//;
|
|
}
|
|
$line_fixed = 1;
|
|
}
|
|
}
|
|
}
|
|
$off += length($elements[$n + 1]);
|
|
|
|
## print("n: <$n> GOOD: <$good>\n");
|
|
|
|
$fixed_line = $fixed_line . $good;
|
|
}
|
|
|
|
if (($#elements % 2) == 0) {
|
|
$fixed_line = $fixed_line . $fix_elements[$#elements];
|
|
}
|
|
|
|
if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
|
|
$fixed[$fixlinenr] = $fixed_line;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
# check for whitespace before a non-naked semicolon
|
|
if ($line =~ /^\+.*\S\s+;\s*$/) {
|
|
if (WARN("SPACING",
|
|
"space prohibited before semicolon\n" . $herecurr) &&
|
|
$fix) {
|
|
1 while $fixed[$fixlinenr] =~
|
|
s/^(\+.*\S)\s+;/$1;/;
|
|
}
|
|
}
|
|
|
|
# check for multiple assignments
|
|
if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
|
|
CHK("MULTIPLE_ASSIGNMENTS",
|
|
"multiple assignments should be avoided\n" . $herecurr);
|
|
}
|
|
|
|
## # check for multiple declarations, allowing for a function declaration
|
|
## # continuation.
|
|
## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
|
|
## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
|
|
##
|
|
## # Remove any bracketed sections to ensure we do not
|
|
## # falsly report the parameters of functions.
|
|
## my $ln = $line;
|
|
## while ($ln =~ s/\([^\(\)]*\)//g) {
|
|
## }
|
|
## if ($ln =~ /,/) {
|
|
## WARN("MULTIPLE_DECLARATION",
|
|
## "declaring multiple variables together should be avoided\n" . $herecurr);
|
|
## }
|
|
## }
|
|
|
|
#need space before brace following if, while, etc
|
|
if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
|
|
$line =~ /\b(?:else|do)\{/) {
|
|
if (ERROR("SPACING",
|
|
"space required before the open brace '{'\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
|
|
}
|
|
}
|
|
|
|
## # check for blank lines before declarations
|
|
## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
|
|
## $prevrawline =~ /^.\s*$/) {
|
|
## WARN("SPACING",
|
|
## "No blank lines before declarations\n" . $hereprev);
|
|
## }
|
|
##
|
|
|
|
# closing brace should have a space following it when it has anything
|
|
# on the line
|
|
if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
|
|
if (ERROR("SPACING",
|
|
"space required after that close brace '}'\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/}((?!(?:,|;|\)))\S)/} $1/;
|
|
}
|
|
}
|
|
|
|
# check spacing on square brackets
|
|
if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited after that open square bracket '['\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\[\s+/\[/;
|
|
}
|
|
}
|
|
if ($line =~ /\s\]/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited before that close square bracket ']'\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\s+\]/\]/;
|
|
}
|
|
}
|
|
|
|
# check spacing on parentheses
|
|
if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
|
|
$line !~ /for\s*\(\s+;/ && $line !~ /^\+\s*[A-Z_][A-Z\d_]*\(\s*\d+(\,.*)?\)\,?$/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited after that open parenthesis '('\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\(\s+/\(/;
|
|
}
|
|
}
|
|
if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
|
|
$line !~ /for\s*\(.*;\s+\)/ &&
|
|
$line !~ /:\s+\)/) {
|
|
if (ERROR("SPACING",
|
|
"space prohibited before that close parenthesis ')'\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\s+\)/\)/;
|
|
}
|
|
}
|
|
|
|
# check unnecessary parentheses around addressof/dereference single $Lvals
|
|
# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
|
|
|
|
while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
|
|
my $var = $1;
|
|
if (CHK("UNNECESSARY_PARENTHESES",
|
|
"Unnecessary parentheses around $var\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
|
|
}
|
|
}
|
|
|
|
# check for unnecessary parentheses around function pointer uses
|
|
# ie: (foo->bar)(); should be foo->bar();
|
|
# but not "if (foo->bar) (" to avoid some false positives
|
|
if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
|
|
my $var = $2;
|
|
if (CHK("UNNECESSARY_PARENTHESES",
|
|
"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
|
|
$fix) {
|
|
my $var2 = deparenthesize($var);
|
|
$var2 =~ s/\s//g;
|
|
$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
|
|
}
|
|
}
|
|
|
|
# check for unnecessary parentheses around comparisons in if uses
|
|
# when !drivers/staging or command-line uses --strict
|
|
if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
|
|
$perl_version_ok && defined($stat) &&
|
|
$stat =~ /(^.\s*if\s*($balanced_parens))/) {
|
|
my $if_stat = $1;
|
|
my $test = substr($2, 1, -1);
|
|
my $herectx;
|
|
while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
|
|
my $match = $1;
|
|
# avoid parentheses around potential macro args
|
|
next if ($match =~ /^\s*\w+\s*$/);
|
|
if (!defined($herectx)) {
|
|
$herectx = $here . "\n";
|
|
my $cnt = statement_rawlines($if_stat);
|
|
for (my $n = 0; $n < $cnt; $n++) {
|
|
my $rl = raw_line($linenr, $n);
|
|
$herectx .= $rl . "\n";
|
|
last if $rl =~ /^[ \+].*\{/;
|
|
}
|
|
}
|
|
CHK("UNNECESSARY_PARENTHESES",
|
|
"Unnecessary parentheses around '$match'\n" . $herectx);
|
|
}
|
|
}
|
|
|
|
#goto labels aren't indented, allow a single space however
|
|
if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
|
|
!($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
|
|
if (WARN("INDENTED_LABEL",
|
|
"labels should not be indented\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^(.)\s+/$1/;
|
|
}
|
|
}
|
|
|
|
# return is not a function
|
|
if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
|
|
my $spacing = $1;
|
|
if ($perl_version_ok &&
|
|
$stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
|
|
my $value = $1;
|
|
$value = deparenthesize($value);
|
|
if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
|
|
ERROR("RETURN_PARENTHESES",
|
|
"return is not a function, parentheses are not required\n" . $herecurr);
|
|
}
|
|
} elsif ($spacing !~ /\s+/) {
|
|
ERROR("SPACING",
|
|
"space required before the open parenthesis '('\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# unnecessary return in a void function
|
|
# at end-of-function, with the previous line a single leading tab, then return;
|
|
# and the line before that not a goto label target like "out:"
|
|
if ($sline =~ /^[ \+]}\s*$/ &&
|
|
$prevline =~ /^\+\treturn\s*;\s*$/ &&
|
|
$linenr >= 3 &&
|
|
$lines[$linenr - 3] =~ /^[ +]/ &&
|
|
$lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
|
|
WARN("RETURN_VOID",
|
|
"void function return statements are not generally useful\n" . $hereprev);
|
|
}
|
|
|
|
# if statements using unnecessary parentheses - ie: if ((foo == bar))
|
|
if ($perl_version_ok &&
|
|
$line =~ /\bif\s*((?:\(\s*){2,})/) {
|
|
my $openparens = $1;
|
|
my $count = $openparens =~ tr@\(@\(@;
|
|
my $msg = "";
|
|
if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
|
|
my $comp = $4; #Not $1 because of $LvalOrFunc
|
|
$msg = " - maybe == should be = ?" if ($comp eq "==");
|
|
WARN("UNNECESSARY_PARENTHESES",
|
|
"Unnecessary parentheses$msg\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# comparisons with a constant or upper case identifier on the left
|
|
# avoid cases like "foo + BAR < baz"
|
|
# only fix matches surrounded by parentheses to avoid incorrect
|
|
# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
|
|
if ($perl_version_ok &&
|
|
$line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
|
|
my $lead = $1;
|
|
my $const = $2;
|
|
my $comp = $3;
|
|
my $to = $4;
|
|
my $newcomp = $comp;
|
|
if ($lead !~ /(?:$Operators|\.)\s*$/ &&
|
|
$to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
|
|
WARN("CONSTANT_COMPARISON",
|
|
"Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
|
|
$fix) {
|
|
if ($comp eq "<") {
|
|
$newcomp = ">";
|
|
} elsif ($comp eq "<=") {
|
|
$newcomp = ">=";
|
|
} elsif ($comp eq ">") {
|
|
$newcomp = "<";
|
|
} elsif ($comp eq ">=") {
|
|
$newcomp = "<=";
|
|
}
|
|
$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
|
|
}
|
|
}
|
|
|
|
# Return of what appears to be an errno should normally be negative
|
|
if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
|
|
my $name = $1;
|
|
if ($name ne 'EOF' && $name ne 'ERROR') {
|
|
WARN("USE_NEGATIVE_ERRNO",
|
|
"return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# Need a space before open parenthesis after if, while etc
|
|
if ($line =~ /\b(if|while|for|switch)\(/) {
|
|
if (ERROR("SPACING",
|
|
"space required before the open parenthesis '('\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/\b(if|while|for|switch)\(/$1 \(/;
|
|
}
|
|
}
|
|
|
|
# Check for illegal assignment in if conditional -- and check for trailing
|
|
# statements after the conditional.
|
|
if ($line =~ /do\s*(?!{)/) {
|
|
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
|
|
ctx_statement_block($linenr, $realcnt, 0)
|
|
if (!defined $stat);
|
|
my ($stat_next) = ctx_statement_block($line_nr_next,
|
|
$remain_next, $off_next);
|
|
$stat_next =~ s/\n./\n /g;
|
|
##print "stat<$stat> stat_next<$stat_next>\n";
|
|
|
|
if ($stat_next =~ /^\s*while\b/) {
|
|
# If the statement carries leading newlines,
|
|
# then count those as offsets.
|
|
my ($whitespace) =
|
|
($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
|
|
my $offset =
|
|
statement_rawlines($whitespace) - 1;
|
|
|
|
$suppress_whiletrailers{$line_nr_next +
|
|
$offset} = 1;
|
|
}
|
|
}
|
|
if (!defined $suppress_whiletrailers{$linenr} &&
|
|
defined($stat) && defined($cond) &&
|
|
$line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
|
|
my ($s, $c) = ($stat, $cond);
|
|
|
|
if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
|
|
ERROR("ASSIGN_IN_IF",
|
|
"do not use assignment in if condition\n" . $herecurr);
|
|
}
|
|
|
|
# Find out what is on the end of the line after the
|
|
# conditional.
|
|
substr($s, 0, length($c), '');
|
|
$s =~ s/\n.*//g;
|
|
$s =~ s/$;//g; # Remove any comments
|
|
if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
|
|
$c !~ /}\s*while\s*/)
|
|
{
|
|
# Find out how long the conditional actually is.
|
|
my @newlines = ($c =~ /\n/gs);
|
|
my $cond_lines = 1 + $#newlines;
|
|
my $stat_real = '';
|
|
|
|
$stat_real = raw_line($linenr, $cond_lines)
|
|
. "\n" if ($cond_lines);
|
|
if (defined($stat_real) && $cond_lines > 1) {
|
|
$stat_real = "[...]\n$stat_real";
|
|
}
|
|
|
|
ERROR("TRAILING_STATEMENTS",
|
|
"trailing statements should be on next line\n" . $herecurr . $stat_real);
|
|
}
|
|
}
|
|
|
|
# Check for bitwise tests written as boolean
|
|
if ($line =~ /
|
|
(?:
|
|
(?:\[|\(|\&\&|\|\|)
|
|
\s*0[xX][0-9]+\s*
|
|
(?:\&\&|\|\|)
|
|
|
|
|
(?:\&\&|\|\|)
|
|
\s*0[xX][0-9]+\s*
|
|
(?:\&\&|\|\||\)|\])
|
|
)/x)
|
|
{
|
|
WARN("HEXADECIMAL_BOOLEAN_TEST",
|
|
"boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
|
|
}
|
|
|
|
# if and else should not have general statements after it
|
|
if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
|
|
my $s = $1;
|
|
$s =~ s/$;//g; # Remove any comments
|
|
if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
|
|
ERROR("TRAILING_STATEMENTS",
|
|
"trailing statements should be on next line\n" . $herecurr);
|
|
}
|
|
}
|
|
# if should not continue a brace
|
|
if ($line =~ /}\s*if\b/) {
|
|
ERROR("TRAILING_STATEMENTS",
|
|
"trailing statements should be on next line (or did you mean 'else if'?)\n" .
|
|
$herecurr);
|
|
}
|
|
# case and default should not have general statements after them
|
|
if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
|
|
$line !~ /\G(?:
|
|
(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
|
|
\s*return\s+
|
|
)/xg)
|
|
{
|
|
ERROR("TRAILING_STATEMENTS",
|
|
"trailing statements should be on next line\n" . $herecurr);
|
|
}
|
|
|
|
# Check for }<nl>else {, these must be at the same
|
|
# indent level to be relevant to each other.
|
|
if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
|
|
$previndent == $indent) {
|
|
if (ERROR("ELSE_AFTER_BRACE",
|
|
"else should follow close brace '}'\n" . $hereprev) &&
|
|
$fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixedline = $prevrawline;
|
|
$fixedline =~ s/}\s*$//;
|
|
if ($fixedline !~ /^\+\s*$/) {
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
$fixedline = $rawline;
|
|
$fixedline =~ s/^(.\s*)else/$1} else/;
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
}
|
|
|
|
if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
|
|
$previndent == $indent) {
|
|
my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
|
|
|
|
# Find out what is on the end of the line after the
|
|
# conditional.
|
|
substr($s, 0, length($c), '');
|
|
$s =~ s/\n.*//g;
|
|
|
|
if ($s =~ /^\s*;/) {
|
|
if (ERROR("WHILE_AFTER_BRACE",
|
|
"while should follow close brace '}'\n" . $hereprev) &&
|
|
$fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixedline = $prevrawline;
|
|
my $trailing = $rawline;
|
|
$trailing =~ s/^\+//;
|
|
$trailing = trim($trailing);
|
|
$fixedline =~ s/}\s*$/} $trailing/;
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
}
|
|
}
|
|
|
|
#Specific variable tests
|
|
while ($line =~ m{($Constant|$Lval)}g) {
|
|
my $var = $1;
|
|
|
|
#CamelCase
|
|
if ($var !~ /^$Constant$/ &&
|
|
$var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
|
|
#Ignore Page<foo> variants
|
|
$var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
|
|
#Ignore SI style variants like nS, mV and dB
|
|
#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
|
|
$var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
|
|
#Ignore some three character SI units explicitly, like MiB and KHz
|
|
$var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
|
|
while ($var =~ m{($Ident)}g) {
|
|
my $word = $1;
|
|
next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
|
|
if ($check) {
|
|
seed_camelcase_includes();
|
|
if (!$file && !$camelcase_file_seeded) {
|
|
seed_camelcase_file($realfile);
|
|
$camelcase_file_seeded = 1;
|
|
}
|
|
}
|
|
if (!defined $camelcase{$word}) {
|
|
$camelcase{$word} = 1;
|
|
CHK("CAMELCASE",
|
|
"Avoid CamelCase: <$word>\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#no spaces allowed after \ in define
|
|
if ($line =~ /\#\s*define.*\\\s+$/) {
|
|
if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
|
|
"Whitespace after \\ makes next lines useless\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\s+$//;
|
|
}
|
|
}
|
|
|
|
# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
|
|
# itself <asm/foo.h> (uses RAW line)
|
|
if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
|
|
my $file = "$1.h";
|
|
my $checkfile = "include/linux/$file";
|
|
if (-f "$root/$checkfile" &&
|
|
$realfile ne $checkfile &&
|
|
$1 !~ /$allowed_asm_includes/)
|
|
{
|
|
my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
|
|
if ($asminclude > 0) {
|
|
if ($realfile =~ m{^arch/}) {
|
|
CHK("ARCH_INCLUDE_LINUX",
|
|
"Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
|
|
} else {
|
|
WARN("INCLUDE_LINUX",
|
|
"Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# multi-statement macros should be enclosed in a do while loop, grab the
|
|
# first statement and ensure its the whole macro if its not enclosed
|
|
# in a known good container
|
|
if ($realfile !~ m@/vmlinux.lds.h$@ &&
|
|
$line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
|
|
my $ln = $linenr;
|
|
my $cnt = $realcnt - 1;
|
|
my ($off, $dstat, $dcond, $rest);
|
|
my $ctx = '';
|
|
my $has_flow_statement = 0;
|
|
my $has_arg_concat = 0;
|
|
($dstat, $dcond, $ln, $cnt, $off) =
|
|
ctx_statement_block($linenr, $realcnt, 0);
|
|
$ctx = $dstat;
|
|
#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
|
|
#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
|
|
|
|
$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
|
|
$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
|
|
|
|
$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
|
|
my $define_args = $1;
|
|
my $define_stmt = $dstat;
|
|
my @def_args = ();
|
|
|
|
if (defined $define_args && $define_args ne "") {
|
|
$define_args = substr($define_args, 1, length($define_args) - 2);
|
|
$define_args =~ s/\s*//g;
|
|
$define_args =~ s/\\\+?//g;
|
|
@def_args = split(",", $define_args);
|
|
}
|
|
|
|
$dstat =~ s/$;//g;
|
|
$dstat =~ s/\\\n.//g;
|
|
$dstat =~ s/^\s*//s;
|
|
$dstat =~ s/\s*$//s;
|
|
|
|
# Flatten any parentheses and braces
|
|
while ($dstat =~ s/\([^\(\)]*\)/1/ ||
|
|
$dstat =~ s/\{[^\{\}]*\}/1/ ||
|
|
$dstat =~ s/.\[[^\[\]]*\]/1/)
|
|
{
|
|
}
|
|
|
|
# Extremely long macros may fall off the end of the
|
|
# available context without closing. Give a dangling
|
|
# backslash the benefit of the doubt and allow it
|
|
# to gobble any hanging open-parens.
|
|
$dstat =~ s/\(.+\\$/1/;
|
|
|
|
# Flatten any obvious string concatentation.
|
|
while ($dstat =~ s/($String)\s*$Ident/$1/ ||
|
|
$dstat =~ s/$Ident\s*($String)/$1/)
|
|
{
|
|
}
|
|
|
|
# Make asm volatile uses seem like a generic function
|
|
$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
|
|
|
|
my $exceptions = qr{
|
|
$Declare|
|
|
module_param_named|
|
|
MODULE_PARM_DESC|
|
|
DECLARE_PER_CPU|
|
|
DEFINE_PER_CPU|
|
|
CLK_[A-Z\d_]+|
|
|
__typeof__\(|
|
|
union|
|
|
struct|
|
|
\.$Ident\s*=\s*|
|
|
^\"|\"$|
|
|
^\[
|
|
}x;
|
|
#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
|
|
|
|
$ctx =~ s/\n*$//;
|
|
my $stmt_cnt = statement_rawlines($ctx);
|
|
my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
|
|
|
|
if ($dstat ne '' &&
|
|
$dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
|
|
$dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
|
|
$dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
|
|
$dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
|
|
$dstat !~ /$exceptions/ &&
|
|
$dstat !~ /^\.$Ident\s*=/ && # .foo =
|
|
$dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
|
|
$dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
|
|
$dstat !~ /^for\s*$Constant$/ && # for (...)
|
|
$dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
|
|
$dstat !~ /^do\s*{/ && # do {...
|
|
$dstat !~ /^\(\{/ && # ({...
|
|
$ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
|
|
{
|
|
if ($dstat =~ /^\s*if\b/) {
|
|
ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
|
|
"Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
|
|
} elsif ($dstat =~ /;/) {
|
|
ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
|
|
"Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
|
|
} else {
|
|
ERROR("COMPLEX_MACRO",
|
|
"Macros with complex values should be enclosed in parentheses\n" . "$herectx");
|
|
}
|
|
|
|
}
|
|
|
|
# Make $define_stmt single line, comment-free, etc
|
|
my @stmt_array = split('\n', $define_stmt);
|
|
my $first = 1;
|
|
$define_stmt = "";
|
|
foreach my $l (@stmt_array) {
|
|
$l =~ s/\\$//;
|
|
if ($first) {
|
|
$define_stmt = $l;
|
|
$first = 0;
|
|
} elsif ($l =~ /^[\+ ]/) {
|
|
$define_stmt .= substr($l, 1);
|
|
}
|
|
}
|
|
$define_stmt =~ s/$;//g;
|
|
$define_stmt =~ s/\s+/ /g;
|
|
$define_stmt = trim($define_stmt);
|
|
|
|
# check if any macro arguments are reused (ignore '...' and 'type')
|
|
foreach my $arg (@def_args) {
|
|
next if ($arg =~ /\.\.\./);
|
|
next if ($arg =~ /^type$/i);
|
|
my $tmp_stmt = $define_stmt;
|
|
$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
|
|
$tmp_stmt =~ s/\#+\s*$arg\b//g;
|
|
$tmp_stmt =~ s/\b$arg\s*\#\#//g;
|
|
my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
|
|
if ($use_cnt > 1) {
|
|
CHK("MACRO_ARG_REUSE",
|
|
"Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
|
|
}
|
|
# check if any macro arguments may have other precedence issues
|
|
if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
|
|
((defined($1) && $1 ne ',') ||
|
|
(defined($2) && $2 ne ','))) {
|
|
CHK("MACRO_ARG_PRECEDENCE",
|
|
"Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
|
|
}
|
|
}
|
|
|
|
# check for macros with flow control, but without ## concatenation
|
|
# ## concatenation is commonly a macro that defines a function so ignore those
|
|
if ($has_flow_statement && !$has_arg_concat) {
|
|
my $cnt = statement_rawlines($ctx);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
WARN("MACRO_WITH_FLOW_CONTROL",
|
|
"Macros with flow control statements should be avoided\n" . "$herectx");
|
|
}
|
|
|
|
# check for line continuations outside of #defines, preprocessor #, and asm
|
|
|
|
} else {
|
|
if ($prevline !~ /^..*\\$/ &&
|
|
$line !~ /^\+\s*\#.*\\$/ && # preprocessor
|
|
$line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
|
|
$line =~ /^\+.*\\$/) {
|
|
WARN("LINE_CONTINUATIONS",
|
|
"Avoid unnecessary line continuations\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# do {} while (0) macro tests:
|
|
# single-statement macros do not need to be enclosed in do while (0) loop,
|
|
# macro should not end with a semicolon
|
|
if ($perl_version_ok &&
|
|
$realfile !~ m@/vmlinux.lds.h$@ &&
|
|
$line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
|
|
my $ln = $linenr;
|
|
my $cnt = $realcnt;
|
|
my ($off, $dstat, $dcond, $rest);
|
|
my $ctx = '';
|
|
($dstat, $dcond, $ln, $cnt, $off) =
|
|
ctx_statement_block($linenr, $realcnt, 0);
|
|
$ctx = $dstat;
|
|
|
|
$dstat =~ s/\\\n.//g;
|
|
$dstat =~ s/$;/ /g;
|
|
|
|
if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
|
|
my $stmts = $2;
|
|
my $semis = $3;
|
|
|
|
$ctx =~ s/\n*$//;
|
|
my $cnt = statement_rawlines($ctx);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
if (($stmts =~ tr/;/;/) == 1 &&
|
|
$stmts !~ /^\s*(if|while|for|switch)\b/) {
|
|
WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
|
|
"Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
|
|
}
|
|
if (defined $semis && $semis ne "") {
|
|
WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
|
|
"do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
|
|
}
|
|
} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
|
|
$ctx =~ s/\n*$//;
|
|
my $cnt = statement_rawlines($ctx);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
WARN("TRAILING_SEMICOLON",
|
|
"macros should not use a trailing semicolon\n" . "$herectx");
|
|
}
|
|
}
|
|
|
|
# check for redundant bracing round if etc
|
|
if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
|
|
my ($level, $endln, @chunks) =
|
|
ctx_statement_full($linenr, $realcnt, 1);
|
|
#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
|
|
#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
|
|
if ($#chunks > 0 && $level == 0) {
|
|
my @allowed = ();
|
|
my $allow = 0;
|
|
my $seen = 0;
|
|
my $herectx = $here . "\n";
|
|
my $ln = $linenr - 1;
|
|
for my $chunk (@chunks) {
|
|
my ($cond, $block) = @{$chunk};
|
|
|
|
# If the condition carries leading newlines, then count those as offsets.
|
|
my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
|
|
my $offset = statement_rawlines($whitespace) - 1;
|
|
|
|
$allowed[$allow] = 0;
|
|
#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
|
|
|
|
# We have looked at and allowed this specific line.
|
|
$suppress_ifbraces{$ln + $offset} = 1;
|
|
|
|
$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
|
|
$ln += statement_rawlines($block) - 1;
|
|
|
|
substr($block, 0, length($cond), '');
|
|
|
|
$seen++ if ($block =~ /^\s*{/);
|
|
|
|
#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
|
|
if (statement_lines($cond) > 1) {
|
|
#print "APW: ALLOWED: cond<$cond>\n";
|
|
$allowed[$allow] = 1;
|
|
}
|
|
if ($block =~/\b(?:if|for|while)\b/) {
|
|
#print "APW: ALLOWED: block<$block>\n";
|
|
$allowed[$allow] = 1;
|
|
}
|
|
if (statement_block_size($block) > 1) {
|
|
#print "APW: ALLOWED: lines block<$block>\n";
|
|
$allowed[$allow] = 1;
|
|
}
|
|
$allow++;
|
|
}
|
|
if ($seen) {
|
|
my $sum_allowed = 0;
|
|
foreach (@allowed) {
|
|
$sum_allowed += $_;
|
|
}
|
|
if ($sum_allowed == 0) {
|
|
WARN("BRACES",
|
|
"braces {} are not necessary for any arm of this statement\n" . $herectx);
|
|
} elsif ($sum_allowed != $allow &&
|
|
$seen != $allow) {
|
|
CHK("BRACES",
|
|
"braces {} should be used on all arms of this statement\n" . $herectx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!defined $suppress_ifbraces{$linenr - 1} &&
|
|
$line =~ /\b(if|while|for|else)\b/) {
|
|
my $allowed = 0;
|
|
|
|
# Check the pre-context.
|
|
if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
|
|
#print "APW: ALLOWED: pre<$1>\n";
|
|
$allowed = 1;
|
|
}
|
|
|
|
my ($level, $endln, @chunks) =
|
|
ctx_statement_full($linenr, $realcnt, $-[0]);
|
|
|
|
# Check the condition.
|
|
my ($cond, $block) = @{$chunks[0]};
|
|
#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
|
|
if (defined $cond) {
|
|
substr($block, 0, length($cond), '');
|
|
}
|
|
if (statement_lines($cond) > 1) {
|
|
#print "APW: ALLOWED: cond<$cond>\n";
|
|
$allowed = 1;
|
|
}
|
|
if ($block =~/\b(?:if|for|while)\b/) {
|
|
#print "APW: ALLOWED: block<$block>\n";
|
|
$allowed = 1;
|
|
}
|
|
if (statement_block_size($block) > 1) {
|
|
#print "APW: ALLOWED: lines block<$block>\n";
|
|
$allowed = 1;
|
|
}
|
|
# Check the post-context.
|
|
if (defined $chunks[1]) {
|
|
my ($cond, $block) = @{$chunks[1]};
|
|
if (defined $cond) {
|
|
substr($block, 0, length($cond), '');
|
|
}
|
|
if ($block =~ /^\s*\{/) {
|
|
#print "APW: ALLOWED: chunk-1 block<$block>\n";
|
|
$allowed = 1;
|
|
}
|
|
}
|
|
if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
|
|
my $cnt = statement_rawlines($block);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
WARN("BRACES",
|
|
"braces {} are not necessary for single statement blocks\n" . $herectx);
|
|
}
|
|
}
|
|
|
|
# check for single line unbalanced braces
|
|
if ($sline =~ /^.\s*\}\s*else\s*$/ ||
|
|
$sline =~ /^.\s*else\s*\{\s*$/) {
|
|
CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
|
|
}
|
|
|
|
# check for unnecessary blank lines around braces
|
|
if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
|
|
if (CHK("BRACES",
|
|
"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
|
|
$fix && $prevrawline =~ /^\+/) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
}
|
|
}
|
|
if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
|
|
if (CHK("BRACES",
|
|
"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
|
|
$fix) {
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
}
|
|
}
|
|
|
|
# no volatiles please
|
|
my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
|
|
if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
|
|
WARN("VOLATILE",
|
|
"Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
|
|
}
|
|
|
|
# Check for user-visible strings broken across lines, which breaks the ability
|
|
# to grep for the string. Make exceptions when the previous string ends in a
|
|
# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
|
|
# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
|
|
if ($line =~ /^\+\s*$String/ &&
|
|
$prevline =~ /"\s*$/ &&
|
|
$prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
|
|
if (WARN("SPLIT_STRING",
|
|
"quoted string split across lines\n" . $hereprev) &&
|
|
$fix &&
|
|
$prevrawline =~ /^\+.*"\s*$/ &&
|
|
$last_coalesced_string_linenr != $linenr - 1) {
|
|
my $extracted_string = get_quoted_string($line, $rawline);
|
|
my $comma_close = "";
|
|
if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
|
|
$comma_close = $1;
|
|
}
|
|
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
fix_delete_line($fixlinenr, $rawline);
|
|
my $fixedline = $prevrawline;
|
|
$fixedline =~ s/"\s*$//;
|
|
$fixedline .= substr($extracted_string, 1) . trim($comma_close);
|
|
fix_insert_line($fixlinenr - 1, $fixedline);
|
|
$fixedline = $rawline;
|
|
$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
|
|
if ($fixedline !~ /\+\s*$/) {
|
|
fix_insert_line($fixlinenr, $fixedline);
|
|
}
|
|
$last_coalesced_string_linenr = $linenr;
|
|
}
|
|
}
|
|
|
|
# check for missing a space in a string concatenation
|
|
if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
|
|
WARN('MISSING_SPACE',
|
|
"break quoted strings at a space character\n" . $hereprev);
|
|
}
|
|
|
|
# check for an embedded function name in a string when the function is known
|
|
# This does not work very well for -f --file checking as it depends on patch
|
|
# context providing the function name or a single line form for in-file
|
|
# function declarations
|
|
if ($line =~ /^\+.*$String/ &&
|
|
defined($context_function) &&
|
|
get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
|
|
length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
|
|
WARN("EMBEDDED_FUNCTION_NAME",
|
|
"Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
|
|
}
|
|
|
|
# check for spaces before a quoted newline
|
|
if ($rawline =~ /^.*\".*\s\\n/) {
|
|
if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
|
|
"unnecessary whitespace before a quoted newline\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
|
|
}
|
|
|
|
}
|
|
|
|
# concatenated string without spaces between elements
|
|
if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
|
|
if (CHK("CONCATENATED_STRING",
|
|
"Concatenated strings should use spaces between elements\n" . $herecurr) &&
|
|
$fix) {
|
|
while ($line =~ /($String)/g) {
|
|
my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
|
|
$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
|
|
$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# uncoalesced string fragments
|
|
if ($line =~ /$String\s*"/) {
|
|
if (WARN("STRING_FRAGMENTS",
|
|
"Consecutive strings are generally better as a single string\n" . $herecurr) &&
|
|
$fix) {
|
|
while ($line =~ /($String)(?=\s*")/g) {
|
|
my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
|
|
$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for non-standard and hex prefixed decimal printf formats
|
|
my $show_L = 1; #don't show the same defect twice
|
|
my $show_Z = 1;
|
|
while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
|
|
my $string = substr($rawline, $-[1], $+[1] - $-[1]);
|
|
$string =~ s/%%/__/g;
|
|
# check for %L
|
|
if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
|
|
WARN("PRINTF_L",
|
|
"\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
|
|
$show_L = 0;
|
|
}
|
|
# check for %Z
|
|
if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
|
|
WARN("PRINTF_Z",
|
|
"%Z$1 is non-standard C, use %z$1\n" . $herecurr);
|
|
$show_Z = 0;
|
|
}
|
|
# check for 0x<decimal>
|
|
if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
|
|
ERROR("PRINTF_0XDECIMAL",
|
|
"Prefixing 0x with decimal output is defective\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for line continuations in quoted strings with odd counts of "
|
|
if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
|
|
WARN("LINE_CONTINUATIONS",
|
|
"Avoid line continuations in quoted strings\n" . $herecurr);
|
|
}
|
|
|
|
# read[bwl] & write[bwl] use too many barriers, use the _relaxed variants
|
|
if ($line =~ /\b((?:read|write)[bwl])\b/) {
|
|
ERROR("NON_RELAXED_IO",
|
|
"Use of $1 is deprecated: use $1_relaxed\n\t" .
|
|
"with appropriate memory barriers instead.\n" .
|
|
$herecurr);
|
|
}
|
|
|
|
# likewise, in/out[bwl] should be __raw_read/write[bwl]...
|
|
if ($line =~ /\b((in|out)([bwl]))\b/) {
|
|
my ($all, $pref, $suf) = ($1, $2, $3);
|
|
$pref =~ s/in/read/;
|
|
$pref =~ s/out/write/;
|
|
ERROR("NON_RELAXED_IO",
|
|
"Use of $all is deprecated: use " .
|
|
"__raw_$pref$suf\n\t" .
|
|
"with appropriate memory barriers instead.\n" .
|
|
$herecurr);
|
|
}
|
|
# warn about #if 0
|
|
if ($line =~ /^.\s*\#\s*if\s+0\b/) {
|
|
WARN("IF_0",
|
|
"Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
|
|
}
|
|
|
|
# warn about #if 1
|
|
if ($line =~ /^.\s*\#\s*if\s+1\b/) {
|
|
WARN("IF_1",
|
|
"Consider removing the #if 1 and its #endif\n" . $herecurr);
|
|
}
|
|
|
|
# check for needless "if (<foo>) fn(<foo>)" uses
|
|
if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
|
|
my $tested = quotemeta($1);
|
|
my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
|
|
if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
|
|
my $func = $1;
|
|
if (WARN('NEEDLESS_IF',
|
|
"$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
|
|
$fix) {
|
|
my $do_fix = 1;
|
|
my $leading_tabs = "";
|
|
my $new_leading_tabs = "";
|
|
if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
|
|
$leading_tabs = $1;
|
|
} else {
|
|
$do_fix = 0;
|
|
}
|
|
if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
|
|
$new_leading_tabs = $1;
|
|
if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
|
|
$do_fix = 0;
|
|
}
|
|
} else {
|
|
$do_fix = 0;
|
|
}
|
|
if ($do_fix) {
|
|
fix_delete_line($fixlinenr - 1, $prevrawline);
|
|
$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for unnecessary "Out of Memory" messages
|
|
if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
|
|
$prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
|
|
(defined $1 || defined $3) &&
|
|
$linenr > 3) {
|
|
my $testval = $2;
|
|
my $testline = $lines[$linenr - 3];
|
|
|
|
my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
|
|
# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
|
|
|
|
if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
|
|
$s !~ /\b__GFP_NOWARN\b/ ) {
|
|
WARN("OOM_MESSAGE",
|
|
"Possible unnecessary 'out of memory' message\n" . $hereprev);
|
|
}
|
|
}
|
|
|
|
# check for logging functions with KERN_<LEVEL>
|
|
if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
|
|
$line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
|
|
my $level = $1;
|
|
if (WARN("UNNECESSARY_KERN_LEVEL",
|
|
"Possible unnecessary $level\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\s*$level\s*//;
|
|
}
|
|
}
|
|
|
|
# check for logging continuations
|
|
if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
|
|
WARN("LOGGING_CONTINUATION",
|
|
"Avoid logging continuation uses where feasible\n" . $herecurr);
|
|
}
|
|
|
|
# check for mask then right shift without a parentheses
|
|
if ($perl_version_ok &&
|
|
$line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
|
|
$4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
|
|
WARN("MASK_THEN_SHIFT",
|
|
"Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
|
|
}
|
|
|
|
# check for pointer comparisons to NULL
|
|
if ($perl_version_ok) {
|
|
while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
|
|
my $val = $1;
|
|
my $equal = "!";
|
|
$equal = "" if ($4 eq "!=");
|
|
if (CHK("COMPARISON_TO_NULL",
|
|
"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for bad placement of section $InitAttribute (e.g.: __initdata)
|
|
if ($line =~ /(\b$InitAttribute\b)/) {
|
|
my $attr = $1;
|
|
if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
|
|
my $ptr = $1;
|
|
my $var = $2;
|
|
if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
|
|
ERROR("MISPLACED_INIT",
|
|
"$attr should be placed after $var\n" . $herecurr)) ||
|
|
($ptr !~ /\b(union|struct)\s+$attr\b/ &&
|
|
WARN("MISPLACED_INIT",
|
|
"$attr should be placed after $var\n" . $herecurr))) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for $InitAttributeData (ie: __initdata) with const
|
|
if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
|
|
my $attr = $1;
|
|
$attr =~ /($InitAttributePrefix)(.*)/;
|
|
my $attr_prefix = $1;
|
|
my $attr_type = $2;
|
|
if (ERROR("INIT_ATTRIBUTE",
|
|
"Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/$InitAttributeData/${attr_prefix}initconst/;
|
|
}
|
|
}
|
|
|
|
# check for $InitAttributeConst (ie: __initconst) without const
|
|
if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
|
|
my $attr = $1;
|
|
if (ERROR("INIT_ATTRIBUTE",
|
|
"Use of $attr requires a separate use of const\n" . $herecurr) &&
|
|
$fix) {
|
|
my $lead = $fixed[$fixlinenr] =~
|
|
/(^\+\s*(?:static\s+))/;
|
|
$lead = rtrim($1);
|
|
$lead = "$lead " if ($lead !~ /^\+$/);
|
|
$lead = "${lead}const ";
|
|
$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
|
|
}
|
|
}
|
|
|
|
# check for __read_mostly with const non-pointer (should just be const)
|
|
if ($line =~ /\b__read_mostly\b/ &&
|
|
$line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
|
|
if (ERROR("CONST_READ_MOSTLY",
|
|
"Invalid use of __read_mostly with const type\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
|
|
}
|
|
}
|
|
|
|
# don't use __constant_<foo> functions outside of include/uapi/
|
|
if ($realfile !~ m@^include/uapi/@ &&
|
|
$line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
|
|
my $constant_func = $1;
|
|
my $func = $constant_func;
|
|
$func =~ s/^__constant_//;
|
|
if (WARN("CONSTANT_CONVERSION",
|
|
"$constant_func should be $func\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
|
|
}
|
|
}
|
|
|
|
# prefer usleep_range over udelay
|
|
if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
|
|
my $delay = $1;
|
|
# ignore udelay's < 10, however
|
|
if (! ($delay < 10) ) {
|
|
CHK("USLEEP_RANGE",
|
|
"usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
|
|
}
|
|
if ($delay > 2000) {
|
|
WARN("LONG_UDELAY",
|
|
"long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# warn about unexpectedly long msleep's
|
|
if ($line =~ /\bmsleep\s*\((\d+)\);/) {
|
|
if ($1 < 20) {
|
|
WARN("MSLEEP",
|
|
"msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for comparisons of jiffies
|
|
if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
|
|
WARN("JIFFIES_COMPARISON",
|
|
"Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
|
|
}
|
|
|
|
# check for comparisons of get_jiffies_64()
|
|
if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
|
|
WARN("JIFFIES_COMPARISON",
|
|
"Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
|
|
}
|
|
|
|
# warn about #ifdefs in C files
|
|
# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
|
|
# print "#ifdef in C files should be avoided\n";
|
|
# print "$herecurr";
|
|
# $clean = 0;
|
|
# }
|
|
|
|
# warn about spacing in #ifdefs
|
|
if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
|
|
if (ERROR("SPACING",
|
|
"exactly one space required after that #$1\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~
|
|
s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
|
|
}
|
|
|
|
}
|
|
|
|
# check for spinlock_t definitions without a comment.
|
|
if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
|
|
$line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
|
|
my $which = $1;
|
|
if (!ctx_has_comment($first_line, $linenr)) {
|
|
CHK("UNCOMMENTED_DEFINITION",
|
|
"$1 definition without comment\n" . $herecurr);
|
|
}
|
|
}
|
|
# check for memory barriers without a comment.
|
|
|
|
my $barriers = qr{
|
|
mb|
|
|
rmb|
|
|
wmb|
|
|
read_barrier_depends
|
|
}x;
|
|
my $barrier_stems = qr{
|
|
mb__before_atomic|
|
|
mb__after_atomic|
|
|
store_release|
|
|
load_acquire|
|
|
store_mb|
|
|
(?:$barriers)
|
|
}x;
|
|
my $all_barriers = qr{
|
|
(?:$barriers)|
|
|
smp_(?:$barrier_stems)|
|
|
virt_(?:$barrier_stems)
|
|
}x;
|
|
|
|
if ($line =~ /\b(?:$all_barriers)\s*\(/) {
|
|
if (!ctx_has_comment($first_line, $linenr)) {
|
|
WARN("MEMORY_BARRIER",
|
|
"memory barrier without comment\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
|
|
|
|
if ($realfile !~ m@^include/asm-generic/@ &&
|
|
$realfile !~ m@/barrier\.h$@ &&
|
|
$line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
|
|
$line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
|
|
WARN("MEMORY_BARRIER",
|
|
"__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
|
|
}
|
|
|
|
# check for waitqueue_active without a comment.
|
|
if ($line =~ /\bwaitqueue_active\s*\(/) {
|
|
if (!ctx_has_comment($first_line, $linenr)) {
|
|
WARN("WAITQUEUE_ACTIVE",
|
|
"waitqueue_active without comment\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for smp_read_barrier_depends and read_barrier_depends
|
|
if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
|
|
WARN("READ_BARRIER_DEPENDS",
|
|
"$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
|
|
}
|
|
|
|
# check of hardware specific defines
|
|
if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
|
|
CHK("ARCH_DEFINES",
|
|
"architecture specific defines should be avoided\n" . $herecurr);
|
|
}
|
|
|
|
# check that the storage class is not after a type
|
|
if ($line =~ /\b($Type)\s+($Storage)\b/) {
|
|
WARN("STORAGE_CLASS",
|
|
"storage class '$2' should be located before type '$1'\n" . $herecurr);
|
|
}
|
|
# Check that the storage class is at the beginning of a declaration
|
|
if ($line =~ /\b$Storage\b/ &&
|
|
$line !~ /^.\s*$Storage/ &&
|
|
$line =~ /^.\s*(.+?)\$Storage\s/ &&
|
|
$1 !~ /[\,\)]\s*$/) {
|
|
WARN("STORAGE_CLASS",
|
|
"storage class should be at the beginning of the declaration\n" . $herecurr);
|
|
}
|
|
|
|
# check the location of the inline attribute, that it is between
|
|
# storage class and type.
|
|
if ($line =~ /\b$Type\s+$Inline\b/ ||
|
|
$line =~ /\b$Inline\s+$Storage\b/) {
|
|
ERROR("INLINE_LOCATION",
|
|
"inline keyword should sit between storage class and type\n" . $herecurr);
|
|
}
|
|
|
|
# Check for __inline__ and __inline, prefer inline
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b(__inline__|__inline)\b/) {
|
|
if (WARN("INLINE",
|
|
"plain inline is preferred over $1\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
|
|
|
|
}
|
|
}
|
|
|
|
# Check for __attribute__ packed, prefer __packed
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
|
|
WARN("PREFER_PACKED",
|
|
"__packed is preferred over __attribute__((packed))\n" . $herecurr);
|
|
}
|
|
|
|
# Check for __attribute__ aligned, prefer __aligned
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
|
|
WARN("PREFER_ALIGNED",
|
|
"__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
|
|
}
|
|
|
|
# Check for __attribute__ section, prefer __section
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
|
|
my $old = substr($rawline, $-[1], $+[1] - $-[1]);
|
|
my $new = substr($old, 1, -1);
|
|
if (WARN("PREFER_SECTION",
|
|
"__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
|
|
}
|
|
}
|
|
|
|
# Check for __attribute__ format(printf, prefer __printf
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
|
|
if (WARN("PREFER_PRINTF",
|
|
"__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
|
|
|
|
}
|
|
}
|
|
|
|
# Check for __attribute__ format(scanf, prefer __scanf
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
|
|
if (WARN("PREFER_SCANF",
|
|
"__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
|
|
}
|
|
}
|
|
|
|
# Check for __attribute__ weak, or __weak declarations (may have link issues)
|
|
if ($perl_version_ok &&
|
|
$line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
|
|
($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
|
|
$line =~ /\b__weak\b/)) {
|
|
ERROR("WEAK_DECLARATION",
|
|
"Using weak declarations can have unintended link defects\n" . $herecurr);
|
|
}
|
|
|
|
# check for c99 types like uint8_t used outside of uapi/ and tools/
|
|
if ($realfile !~ m@\binclude/uapi/@ &&
|
|
$realfile !~ m@\btools/@ &&
|
|
$line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
|
|
my $type = $1;
|
|
if ($type =~ /\b($typeC99Typedefs)\b/) {
|
|
$type = $1;
|
|
my $kernel_type = 'u';
|
|
$kernel_type = 's' if ($type =~ /^_*[si]/);
|
|
$type =~ /(\d+)/;
|
|
$kernel_type .= $1;
|
|
if (CHK("PREFER_KERNEL_TYPES",
|
|
"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for cast of C90 native int or longer types constants
|
|
if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
|
|
my $cast = $1;
|
|
my $const = $2;
|
|
if (WARN("TYPECAST_INT_CONSTANT",
|
|
"Unnecessary typecast of c90 int constant\n" . $herecurr) &&
|
|
$fix) {
|
|
my $suffix = "";
|
|
my $newconst = $const;
|
|
$newconst =~ s/${Int_type}$//;
|
|
$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
|
|
if ($cast =~ /\blong\s+long\b/) {
|
|
$suffix .= 'LL';
|
|
} elsif ($cast =~ /\blong\b/) {
|
|
$suffix .= 'L';
|
|
}
|
|
$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
|
|
}
|
|
}
|
|
|
|
# check for sizeof(&)
|
|
if ($line =~ /\bsizeof\s*\(\s*\&/) {
|
|
WARN("SIZEOF_ADDRESS",
|
|
"sizeof(& should be avoided\n" . $herecurr);
|
|
}
|
|
|
|
# check for sizeof without parenthesis
|
|
if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
|
|
if (WARN("SIZEOF_PARENTHESIS",
|
|
"sizeof $1 should be sizeof($1)\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
|
|
}
|
|
}
|
|
|
|
# check for struct spinlock declarations
|
|
if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
|
|
WARN("USE_SPINLOCK_T",
|
|
"struct spinlock should be spinlock_t\n" . $herecurr);
|
|
}
|
|
|
|
# check for seq_printf uses that could be seq_puts
|
|
if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
|
|
my $fmt = get_quoted_string($line, $rawline);
|
|
$fmt =~ s/%%//g;
|
|
if ($fmt !~ /%/) {
|
|
if (WARN("PREFER_SEQ_PUTS",
|
|
"Prefer seq_puts to seq_printf\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for vsprintf extension %p<foo> misuses
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
|
|
$1 !~ /^_*volatile_*$/) {
|
|
my $stat_real;
|
|
|
|
my $lc = $stat =~ tr@\n@@;
|
|
$lc = $lc + $linenr;
|
|
for (my $count = $linenr; $count <= $lc; $count++) {
|
|
my $specifier;
|
|
my $extension;
|
|
my $qualifier;
|
|
my $bad_specifier = "";
|
|
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
|
|
$fmt =~ s/%%//g;
|
|
|
|
while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
|
|
$specifier = $1;
|
|
$extension = $2;
|
|
$qualifier = $3;
|
|
if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
|
|
($extension eq "f" &&
|
|
defined $qualifier && $qualifier !~ /^w/)) {
|
|
$bad_specifier = $specifier;
|
|
last;
|
|
}
|
|
if ($extension eq "x" && !defined($stat_real)) {
|
|
if (!defined($stat_real)) {
|
|
$stat_real = get_stat_real($linenr, $lc);
|
|
}
|
|
WARN("VSPRINTF_SPECIFIER_PX",
|
|
"Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
|
|
}
|
|
}
|
|
if ($bad_specifier ne "") {
|
|
my $stat_real = get_stat_real($linenr, $lc);
|
|
my $ext_type = "Invalid";
|
|
my $use = "";
|
|
if ($bad_specifier =~ /p[Ff]/) {
|
|
$use = " - use %pS instead";
|
|
$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
|
|
}
|
|
|
|
WARN("VSPRINTF_POINTER_EXTENSION",
|
|
"$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check for misused memsets
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
|
|
|
|
my $ms_addr = $2;
|
|
my $ms_val = $7;
|
|
my $ms_size = $12;
|
|
|
|
if ($ms_size =~ /^(0x|)0$/i) {
|
|
ERROR("MEMSET",
|
|
"memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
|
|
} elsif ($ms_size =~ /^(0x|)1$/i) {
|
|
WARN("MEMSET",
|
|
"single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
|
|
}
|
|
}
|
|
|
|
# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
|
|
# if ($perl_version_ok &&
|
|
# defined $stat &&
|
|
# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
|
|
# if (WARN("PREFER_ETHER_ADDR_COPY",
|
|
# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
|
|
# $fix) {
|
|
# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
|
|
# }
|
|
# }
|
|
|
|
# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
|
|
# if ($perl_version_ok &&
|
|
# defined $stat &&
|
|
# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
|
|
# WARN("PREFER_ETHER_ADDR_EQUAL",
|
|
# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
|
|
# }
|
|
|
|
# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
|
|
# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
|
|
# if ($perl_version_ok &&
|
|
# defined $stat &&
|
|
# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
|
|
#
|
|
# my $ms_val = $7;
|
|
#
|
|
# if ($ms_val =~ /^(?:0x|)0+$/i) {
|
|
# if (WARN("PREFER_ETH_ZERO_ADDR",
|
|
# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
|
|
# $fix) {
|
|
# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
|
|
# }
|
|
# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
|
|
# if (WARN("PREFER_ETH_BROADCAST_ADDR",
|
|
# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
|
|
# $fix) {
|
|
# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
|
|
# }
|
|
# }
|
|
# }
|
|
|
|
# typecasts on min/max could be min_t/max_t
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
|
|
if (defined $2 || defined $7) {
|
|
my $call = $1;
|
|
my $cast1 = deparenthesize($2);
|
|
my $arg1 = $3;
|
|
my $cast2 = deparenthesize($7);
|
|
my $arg2 = $8;
|
|
my $cast;
|
|
|
|
if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
|
|
$cast = "$cast1 or $cast2";
|
|
} elsif ($cast1 ne "") {
|
|
$cast = $cast1;
|
|
} else {
|
|
$cast = $cast2;
|
|
}
|
|
WARN("MINMAX",
|
|
"$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
|
|
}
|
|
}
|
|
|
|
# check usleep_range arguments
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
|
|
my $min = $1;
|
|
my $max = $7;
|
|
if ($min eq $max) {
|
|
WARN("USLEEP_RANGE",
|
|
"usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
|
|
} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
|
|
$min > $max) {
|
|
WARN("USLEEP_RANGE",
|
|
"usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
|
|
}
|
|
}
|
|
|
|
# check for naked sscanf
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$line =~ /\bsscanf\b/ &&
|
|
($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
|
|
$stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
|
|
$stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
|
|
my $lc = $stat =~ tr@\n@@;
|
|
$lc = $lc + $linenr;
|
|
my $stat_real = get_stat_real($linenr, $lc);
|
|
WARN("NAKED_SSCANF",
|
|
"unchecked sscanf return value\n" . "$here\n$stat_real\n");
|
|
}
|
|
|
|
# check for simple sscanf that should be kstrto<foo>
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$line =~ /\bsscanf\b/) {
|
|
my $lc = $stat =~ tr@\n@@;
|
|
$lc = $lc + $linenr;
|
|
my $stat_real = get_stat_real($linenr, $lc);
|
|
if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
|
|
my $format = $6;
|
|
my $count = $format =~ tr@%@%@;
|
|
if ($count == 1 &&
|
|
$format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
|
|
WARN("SSCANF_TO_KSTRTO",
|
|
"Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for new externs in .h files.
|
|
if ($realfile =~ /\.h$/ &&
|
|
$line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
|
|
if (CHK("AVOID_EXTERNS",
|
|
"extern prototypes should be avoided in .h files\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
|
|
}
|
|
}
|
|
|
|
# check for new externs in .c files.
|
|
if ($realfile =~ /\.c$/ && defined $stat &&
|
|
$stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
|
|
{
|
|
my $function_name = $1;
|
|
my $paren_space = $2;
|
|
|
|
my $s = $stat;
|
|
if (defined $cond) {
|
|
substr($s, 0, length($cond), '');
|
|
}
|
|
if ($s =~ /^\s*;/ &&
|
|
$function_name ne 'uninitialized_var')
|
|
{
|
|
WARN("AVOID_EXTERNS",
|
|
"externs should be avoided in .c files\n" . $herecurr);
|
|
}
|
|
|
|
if ($paren_space =~ /\n/) {
|
|
WARN("FUNCTION_ARGUMENTS",
|
|
"arguments for function declarations should follow identifier\n" . $herecurr);
|
|
}
|
|
|
|
} elsif ($realfile =~ /\.c$/ && defined $stat &&
|
|
$stat =~ /^.\s*extern\s+/)
|
|
{
|
|
WARN("AVOID_EXTERNS",
|
|
"externs should be avoided in .c files\n" . $herecurr);
|
|
}
|
|
|
|
# check for function declarations that have arguments without identifier names
|
|
if (defined $stat &&
|
|
$stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
|
|
$1 ne "void") {
|
|
my $args = trim($1);
|
|
while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
|
|
my $arg = trim($1);
|
|
if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
|
|
WARN("FUNCTION_ARGUMENTS",
|
|
"function definition argument '$arg' should also have an identifier name\n" . $herecurr);
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for function definitions
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
|
|
$context_function = $1;
|
|
|
|
# check for multiline function definition with misplaced open brace
|
|
my $ok = 0;
|
|
my $cnt = statement_rawlines($stat);
|
|
my $herectx = $here . "\n";
|
|
for (my $n = 0; $n < $cnt; $n++) {
|
|
my $rl = raw_line($linenr, $n);
|
|
$herectx .= $rl . "\n";
|
|
$ok = 1 if ($rl =~ /^[ \+]\{/);
|
|
$ok = 1 if ($rl =~ /\{/ && $n == 0);
|
|
last if $rl =~ /^[ \+].*\{/;
|
|
}
|
|
if (!$ok) {
|
|
ERROR("OPEN_BRACE",
|
|
"open brace '{' following function definitions go on the next line\n" . $herectx);
|
|
}
|
|
}
|
|
|
|
# checks for new __setup's
|
|
if ($rawline =~ /\b__setup\("([^"]*)"/) {
|
|
my $name = $1;
|
|
|
|
if (!grep(/$name/, @setup_docs)) {
|
|
CHK("UNDOCUMENTED_SETUP",
|
|
"__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for pointless casting of alloc functions
|
|
if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
|
|
WARN("UNNECESSARY_CASTS",
|
|
"unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
|
|
}
|
|
|
|
# alloc style
|
|
# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
|
|
if ($perl_version_ok &&
|
|
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
|
|
CHK("ALLOC_SIZEOF_STRUCT",
|
|
"Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
|
|
}
|
|
|
|
# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
|
|
my $oldfunc = $3;
|
|
my $a1 = $4;
|
|
my $a2 = $10;
|
|
my $newfunc = "kmalloc_array";
|
|
$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
|
|
my $r1 = $a1;
|
|
my $r2 = $a2;
|
|
if ($a1 =~ /^sizeof\s*\S/) {
|
|
$r1 = $a2;
|
|
$r2 = $a1;
|
|
}
|
|
if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
|
|
!($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
|
|
my $cnt = statement_rawlines($stat);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
if (WARN("ALLOC_WITH_MULTIPLY",
|
|
"Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
|
|
$cnt == 1 &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for krealloc arg reuse
|
|
if ($perl_version_ok &&
|
|
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
|
|
$1 eq $3) {
|
|
WARN("KREALLOC_ARG_REUSE",
|
|
"Reusing the krealloc arg is almost always a bug\n" . $herecurr);
|
|
}
|
|
|
|
# check for alloc argument mismatch
|
|
if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
|
|
WARN("ALLOC_ARRAY_ARGS",
|
|
"$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
|
|
}
|
|
|
|
# check for multiple semicolons
|
|
if ($line =~ /;\s*;\s*$/) {
|
|
if (WARN("ONE_SEMICOLON",
|
|
"Statements terminations use 1 semicolon\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
|
|
}
|
|
}
|
|
|
|
# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
|
|
if ($realfile !~ m@^include/uapi/@ &&
|
|
$line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
|
|
my $ull = "";
|
|
$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
|
|
if (CHK("BIT_MACRO",
|
|
"Prefer using the BIT$ull macro\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
|
|
}
|
|
}
|
|
|
|
# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
|
|
if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
|
|
my $config = $1;
|
|
if (WARN("PREFER_IS_ENABLED",
|
|
"Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
|
|
}
|
|
}
|
|
|
|
# check for case / default statements not preceded by break/fallthrough/switch
|
|
if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
|
|
my $has_break = 0;
|
|
my $has_statement = 0;
|
|
my $count = 0;
|
|
my $prevline = $linenr;
|
|
while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
|
|
$prevline--;
|
|
my $rline = $rawlines[$prevline - 1];
|
|
my $fline = $lines[$prevline - 1];
|
|
last if ($fline =~ /^\@\@/);
|
|
next if ($fline =~ /^\-/);
|
|
next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
|
|
$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
|
|
next if ($fline =~ /^.[\s$;]*$/);
|
|
$has_statement = 1;
|
|
$count++;
|
|
$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
|
|
}
|
|
if (!$has_break && $has_statement) {
|
|
WARN("MISSING_BREAK",
|
|
"Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for switch/default statements without a break;
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
|
|
my $cnt = statement_rawlines($stat);
|
|
my $herectx = get_stat_here($linenr, $cnt, $here);
|
|
|
|
WARN("DEFAULT_NO_BREAK",
|
|
"switch default: should use break\n" . $herectx);
|
|
}
|
|
|
|
# check for return codes on error paths
|
|
if ($line =~ /\breturn\s+-\d+/) {
|
|
ERROR("NO_ERROR_CODE",
|
|
"illegal return value, please use an error code\n" . $herecurr);
|
|
}
|
|
|
|
# check for gcc specific __FUNCTION__
|
|
if ($line =~ /\b__FUNCTION__\b/) {
|
|
if (WARN("USE_FUNC",
|
|
"__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
|
|
}
|
|
}
|
|
|
|
# check for uses of __DATE__, __TIME__, __TIMESTAMP__
|
|
while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
|
|
ERROR("DATE_TIME",
|
|
"Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
|
|
}
|
|
|
|
# check for use of yield()
|
|
if ($line =~ /\byield\s*\(\s*\)/) {
|
|
WARN("YIELD",
|
|
"Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
|
|
}
|
|
|
|
# check for comparisons against true and false
|
|
if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
|
|
my $lead = $1;
|
|
my $arg = $2;
|
|
my $test = $3;
|
|
my $otype = $4;
|
|
my $trail = $5;
|
|
my $op = "!";
|
|
|
|
($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
|
|
|
|
my $type = lc($otype);
|
|
if ($type =~ /^(?:true|false)$/) {
|
|
if (("$test" eq "==" && "$type" eq "true") ||
|
|
("$test" eq "!=" && "$type" eq "false")) {
|
|
$op = "";
|
|
}
|
|
|
|
CHK("BOOL_COMPARISON",
|
|
"Using comparison to $otype is error prone\n" . $herecurr);
|
|
|
|
## maybe suggesting a correct construct would better
|
|
## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
|
|
|
|
}
|
|
}
|
|
|
|
# check for semaphores initialized locked
|
|
if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
|
|
WARN("CONSIDER_COMPLETION",
|
|
"consider using a completion\n" . $herecurr);
|
|
}
|
|
|
|
# recommend kstrto* over simple_strto* and strict_strto*
|
|
if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
|
|
WARN("CONSIDER_KSTRTO",
|
|
"$1 is obsolete, use k$3 instead\n" . $herecurr);
|
|
}
|
|
|
|
# check for __initcall(), use device_initcall() explicitly or more appropriate function please
|
|
if ($line =~ /^.\s*__initcall\s*\(/) {
|
|
WARN("USE_DEVICE_INITCALL",
|
|
"please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
|
|
}
|
|
|
|
# check for spin_is_locked(), suggest lockdep instead
|
|
if ($line =~ /\bspin_is_locked\(/) {
|
|
WARN("USE_LOCKDEP",
|
|
"Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
|
|
}
|
|
|
|
# check for deprecated apis
|
|
if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
|
|
my $deprecated_api = $1;
|
|
my $new_api = $deprecated_apis{$deprecated_api};
|
|
WARN("DEPRECATED_API",
|
|
"Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
|
|
}
|
|
|
|
# check for various structs that are normally const (ops, kgdb, device_tree)
|
|
# and avoid what seem like struct definitions 'struct foo {'
|
|
if ($line !~ /\bconst\b/ &&
|
|
$line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
|
|
WARN("CONST_STRUCT",
|
|
"struct $1 should normally be const\n" . $herecurr);
|
|
}
|
|
|
|
# use of NR_CPUS is usually wrong
|
|
# ignore definitions of NR_CPUS and usage to define arrays as likely right
|
|
if ($line =~ /\bNR_CPUS\b/ &&
|
|
$line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
|
|
$line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
|
|
$line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
|
|
$line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
|
|
$line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
|
|
{
|
|
WARN("NR_CPUS",
|
|
"usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
|
|
}
|
|
|
|
# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
|
|
if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
|
|
ERROR("DEFINE_ARCH_HAS",
|
|
"#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
|
|
}
|
|
|
|
# likely/unlikely comparisons similar to "(likely(foo) > 0)"
|
|
if ($perl_version_ok &&
|
|
$line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
|
|
WARN("LIKELY_MISUSE",
|
|
"Using $1 should generally have parentheses around the comparison\n" . $herecurr);
|
|
}
|
|
|
|
# nested likely/unlikely calls
|
|
if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
|
|
WARN("LIKELY_MISUSE",
|
|
"nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
|
|
}
|
|
|
|
# whine mightly about in_atomic
|
|
if ($line =~ /\bin_atomic\s*\(/) {
|
|
if ($realfile =~ m@^drivers/@) {
|
|
ERROR("IN_ATOMIC",
|
|
"do not use in_atomic in drivers\n" . $herecurr);
|
|
} elsif ($realfile !~ m@^kernel/@) {
|
|
WARN("IN_ATOMIC",
|
|
"use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for mutex_trylock_recursive usage
|
|
if ($line =~ /mutex_trylock_recursive/) {
|
|
ERROR("LOCKING",
|
|
"recursive locking is bad, do not use this ever.\n" . $herecurr);
|
|
}
|
|
|
|
# check for lockdep_set_novalidate_class
|
|
if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
|
|
$line =~ /__lockdep_no_validate__\s*\)/ ) {
|
|
if ($realfile !~ m@^kernel/lockdep@ &&
|
|
$realfile !~ m@^include/linux/lockdep@ &&
|
|
$realfile !~ m@^drivers/base/core@) {
|
|
ERROR("LOCKDEP",
|
|
"lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
|
|
$line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
|
|
WARN("EXPORTED_WORLD_WRITABLE",
|
|
"Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
|
|
}
|
|
|
|
# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
|
|
# and whether or not function naming is typical and if
|
|
# DEVICE_ATTR permissions uses are unusual too
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
|
|
my $var = $1;
|
|
my $perms = $2;
|
|
my $show = $3;
|
|
my $store = $4;
|
|
my $octal_perms = perms_to_octal($perms);
|
|
if ($show =~ /^${var}_show$/ &&
|
|
$store =~ /^${var}_store$/ &&
|
|
$octal_perms eq "0644") {
|
|
if (WARN("DEVICE_ATTR_RW",
|
|
"Use DEVICE_ATTR_RW\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
|
|
}
|
|
} elsif ($show =~ /^${var}_show$/ &&
|
|
$store =~ /^NULL$/ &&
|
|
$octal_perms eq "0444") {
|
|
if (WARN("DEVICE_ATTR_RO",
|
|
"Use DEVICE_ATTR_RO\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
|
|
}
|
|
} elsif ($show =~ /^NULL$/ &&
|
|
$store =~ /^${var}_store$/ &&
|
|
$octal_perms eq "0200") {
|
|
if (WARN("DEVICE_ATTR_WO",
|
|
"Use DEVICE_ATTR_WO\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
|
|
}
|
|
} elsif ($octal_perms eq "0644" ||
|
|
$octal_perms eq "0444" ||
|
|
$octal_perms eq "0200") {
|
|
my $newshow = "$show";
|
|
$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
|
|
my $newstore = $store;
|
|
$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
|
|
my $rename = "";
|
|
if ($show ne $newshow) {
|
|
$rename .= " '$show' to '$newshow'";
|
|
}
|
|
if ($store ne $newstore) {
|
|
$rename .= " '$store' to '$newstore'";
|
|
}
|
|
WARN("DEVICE_ATTR_FUNCTIONS",
|
|
"Consider renaming function(s)$rename\n" . $herecurr);
|
|
} else {
|
|
WARN("DEVICE_ATTR_PERMS",
|
|
"DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# Mode permission misuses where it seems decimal should be octal
|
|
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
|
|
# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
|
|
# specific definition of not visible in sysfs.
|
|
# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
|
|
# use the default permissions
|
|
if ($perl_version_ok &&
|
|
defined $stat &&
|
|
$line =~ /$mode_perms_search/) {
|
|
foreach my $entry (@mode_permission_funcs) {
|
|
my $func = $entry->[0];
|
|
my $arg_pos = $entry->[1];
|
|
|
|
my $lc = $stat =~ tr@\n@@;
|
|
$lc = $lc + $linenr;
|
|
my $stat_real = get_stat_real($linenr, $lc);
|
|
|
|
my $skip_args = "";
|
|
if ($arg_pos > 1) {
|
|
$arg_pos--;
|
|
$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
|
|
}
|
|
my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
|
|
if ($stat =~ /$test/) {
|
|
my $val = $1;
|
|
$val = $6 if ($skip_args ne "");
|
|
if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
|
|
(($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
|
|
($val =~ /^$Octal$/ && length($val) ne 4))) {
|
|
ERROR("NON_OCTAL_PERMISSIONS",
|
|
"Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
|
|
}
|
|
if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
|
|
ERROR("EXPORTED_WORLD_WRITABLE",
|
|
"Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# check for uses of S_<PERMS> that could be octal for readability
|
|
while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
|
|
my $oval = $1;
|
|
my $octal = perms_to_octal($oval);
|
|
if (WARN("SYMBOLIC_PERMS",
|
|
"Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
|
|
$fix) {
|
|
$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
|
|
}
|
|
}
|
|
|
|
# validate content of MODULE_LICENSE against list from include/linux/module.h
|
|
if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
|
|
my $extracted_string = get_quoted_string($line, $rawline);
|
|
my $valid_licenses = qr{
|
|
GPL|
|
|
GPL\ v2|
|
|
GPL\ and\ additional\ rights|
|
|
Dual\ BSD/GPL|
|
|
Dual\ MIT/GPL|
|
|
Dual\ MPL/GPL|
|
|
Proprietary
|
|
}x;
|
|
if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
|
|
WARN("MODULE_LICENSE",
|
|
"unknown module license " . $extracted_string . "\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# check for sysctl duplicate constants
|
|
if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
|
|
WARN("DUPLICATED_SYSCTL_CONST",
|
|
"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
|
|
}
|
|
}
|
|
|
|
# If we have no input at all, then there is nothing to report on
|
|
# so just keep quiet.
|
|
if ($#rawlines == -1) {
|
|
exit(0);
|
|
}
|
|
|
|
# In mailback mode only produce a report in the negative, for
|
|
# things that appear to be patches.
|
|
if ($mailback && ($clean == 1 || !$is_patch)) {
|
|
exit(0);
|
|
}
|
|
|
|
# This is not a patch, and we are are in 'no-patch' mode so
|
|
# just keep quiet.
|
|
if (!$chk_patch && !$is_patch) {
|
|
exit(0);
|
|
}
|
|
|
|
if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
|
|
ERROR("NOT_UNIFIED_DIFF",
|
|
"Does not appear to be a unified-diff format patch\n");
|
|
}
|
|
if ($is_patch && $has_commit_log && $chk_signoff) {
|
|
if ($signoff == 0) {
|
|
ERROR("MISSING_SIGN_OFF",
|
|
"Missing Signed-off-by: line(s)\n");
|
|
} elsif (!$authorsignoff) {
|
|
WARN("NO_AUTHOR_SIGN_OFF",
|
|
"Missing Signed-off-by: line by nominal patch author '$author'\n");
|
|
}
|
|
}
|
|
|
|
print report_dump();
|
|
if ($summary && !($clean == 1 && $quiet == 1)) {
|
|
print "$filename " if ($summary_file);
|
|
print "total: $cnt_error errors, $cnt_warn warnings, " .
|
|
(($check)? "$cnt_chk checks, " : "") .
|
|
"$cnt_lines lines checked\n";
|
|
}
|
|
|
|
if ($quiet == 0) {
|
|
# If there were any defects found and not already fixing them
|
|
if (!$clean and !$fix) {
|
|
print << "EOM"
|
|
|
|
NOTE: For some of the reported defects, checkpatch may be able to
|
|
mechanically convert to the typical style using --fix or --fix-inplace.
|
|
EOM
|
|
}
|
|
# If there were whitespace errors which cleanpatch can fix
|
|
# then suggest that.
|
|
if ($rpt_cleaners) {
|
|
$rpt_cleaners = 0;
|
|
print << "EOM"
|
|
|
|
NOTE: Whitespace errors detected.
|
|
You may wish to use scripts/cleanpatch or scripts/cleanfile
|
|
EOM
|
|
}
|
|
}
|
|
|
|
if ($clean == 0 && $fix &&
|
|
("@rawlines" ne "@fixed" ||
|
|
$#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
|
|
my $newfile = $filename;
|
|
$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
|
|
my $linecount = 0;
|
|
my $f;
|
|
|
|
@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
|
|
|
|
open($f, '>', $newfile)
|
|
or die "$P: Can't open $newfile for write\n";
|
|
foreach my $fixed_line (@fixed) {
|
|
$linecount++;
|
|
if ($file) {
|
|
if ($linecount > 3) {
|
|
$fixed_line =~ s/^\+//;
|
|
print $f $fixed_line . "\n";
|
|
}
|
|
} else {
|
|
print $f $fixed_line . "\n";
|
|
}
|
|
}
|
|
close($f);
|
|
|
|
if (!$quiet) {
|
|
print << "EOM";
|
|
|
|
Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
|
|
|
|
Do _NOT_ trust the results written to this file.
|
|
Do _NOT_ submit these changes without inspecting them for correctness.
|
|
|
|
This EXPERIMENTAL file is simply a convenience to help rewrite patches.
|
|
No warranties, expressed or implied...
|
|
EOM
|
|
}
|
|
}
|
|
|
|
if ($quiet == 0) {
|
|
print "\n";
|
|
if ($clean == 1) {
|
|
print "$vname has no obvious style problems and is ready for submission.\n";
|
|
} else {
|
|
print "$vname has style problems, please review.\n";
|
|
}
|
|
}
|
|
return $clean;
|
|
}
|